Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> [PHP]klasa walidacji
gitbejbe
post 30.09.2013, 11:47:33
Post #1





Grupa: Zarejestrowani
Postów: 515
Pomógł: 63
Dołączył: 27.08.2012

Ostrzeżenie: (0%)
-----


Witam

Nie wiedziałem czy wrzucać to do oceny, bo w sumie bardziej chodzi o to aby ktoś powierzchownie rzucił okiem, czy ide w dobrym kierunku. To moja pierwsza klasa - bazowa, bo chciałbym na niej m.in oprzec pozostałe klasy.

starałem sie uprościć ją do minimum, link do Github'a

jak widać dodanie nowej wartości do walidacji odbywa się w ten sposób:
  1. $validation = new Validation();
  2.  
  3. $validation -> addKey('imie') -> addValue($_POST['imie']) -> addRules('req,min=3,max=10');
  4. $validation -> addKey('login') -> addValue($_POST['login']) -> addRules('req,min=10');
  5. $validation -> addKey('haslo') -> addValue($_POST['haslo']) -> addRules('req,login,min=3,max=10,url,striptags,html,int,'); //itd itp
  6. ...
  7. $validation -> startValidation();


sprawdzenie czy wszystkie pola przeszły poprawną walidacje wywołuje sie poprzez warunek if(!$validation->errors)
odwołanie się do tablicy błędu, np : $validation->errors['imie'] <- bledy beda wyswietlane po kolei począwszy od pierwszej zadeklarowanej wartości do sprawdzenia

błędów nie ma, wszystko działa, ale jak juz wspomniałem, to moja pierwsza samodzielnie napisana klasa, tak więc chciałbym was prosić o to, abyście mogli podpowiedzieć mi czy robie jakieś błędy lub czego mógłbym jeszcze użyć do niezawodności tej klasy

Ten post edytował gitbejbe 30.09.2013, 12:30:18
Go to the top of the page
+Quote Post
buliq
post 30.09.2013, 12:06:19
Post #2





Grupa: Zarejestrowani
Postów: 559
Pomógł: 93
Dołączył: 4.03.2008
Skąd: Olsztyn

Ostrzeżenie: (0%)
-----


Hmm,

Czy nie lepiej wygląda to jak dla zestawu pól ("kay") dodajesz walidatory? Każdy walidator ma osobną klasę, dziedziczy po klasie abstrakcyjnej i ma metody do ustawienia wartości i do walidacji. Klasa główna na podstawie konfiguracji "kay" => "walidatory (z opcjami)" i otrzymanych danych sprawdza każde pole z konfiguracji i odpala odpowiednie walidatory?

I w zależności czy konfiguracja główna zezwala na błędy czy nie (break on failure) zwracasz wynik.
Można to nawet dalej rozwinąć tworząc grupy walidacji itd.

BTW to chyba do Oceny

Ten post edytował buliq 30.09.2013, 12:09:28


--------------------
KTOŚ TU PACZY???

Kompedium wiedzy
Go to the top of the page
+Quote Post
nospor
post 30.09.2013, 12:11:59
Post #3





Grupa: Moderatorzy
Postów: 36 440
Pomógł: 6290
Dołączył: 27.12.2004




Jak juz piszesz po angielsku to nie rob tak fatalnych literowek jak KAY, szczegolnie ze chwile pozniej jako parametr piszesz KEY


--------------------

"Myśl, myśl, myśl..." - Kubuś Puchatek || "Manual, manual, manual..." - Kubuś Programista
"Szukaj, szukaj, szukaj..." - Kubuś Odkrywca || "Debuguj, debuguj, debuguj..." - Kubuś Developer

Go to the top of the page
+Quote Post
gitbejbe
post 30.09.2013, 12:20:16
Post #4





Grupa: Zarejestrowani
Postów: 515
Pomógł: 63
Dołączył: 27.08.2012

Ostrzeżenie: (0%)
-----


Cytat
Czy nie lepiej wygląda to jak dla zestawu pól ("kay") dodajesz walidatory?

Myslałem o takim rozwiązaniu na samym poczatku. Przez konstruktor klasy Validation wskazywałbym tablicę (superglobalną $_POST / $_GET, albo bym sam wypisywał tablicę dla interesujacych mnie wartośći do sprawdzenia).

Cytat
Każdy walidator ma osobną klasę, dziedziczy po klasie abstrakcyjnej i ma metody do ustawienia wartości i do walidacji

tego za bardzo nie rozumiem... Nie byłoby to za dużo (może nawet zbędnej) roboty ? w sumie to tą klase mozna byłoby w ten sposób przerobić, czyli byłaby to poprostu zamiana "case'ów" na klasy. Ale czy to faktycznie byłoby lepsze ? Rozumiem, ze zyskałbym poprostu łatwiejszą modyfikowalność obsługi błędów ?

@nospor
mam z tym czasem problem, a akurat te słówko bardzo łatwo mi sie myli i nie raz bez namysłku przekracam tą literke. Z pewnością poprawie : )
edit: POPRAWIONE : )

Ten post edytował gitbejbe 30.09.2013, 12:29:57
Go to the top of the page
+Quote Post
buliq
post 30.09.2013, 12:35:19
Post #5





Grupa: Zarejestrowani
Postów: 559
Pomógł: 93
Dołączył: 4.03.2008
Skąd: Olsztyn

Ostrzeżenie: (0%)
-----


W zaproponowanym przeze mnie przykładzie masz większe możliwości:
- przede wszystkim, klasa główna zawiera tylko logikę i w miarę zwiększania ilości walidatorów nie zwiększasz ilości linii w pliku, co wpływa na czytelność,
- łatwiej jest znaleźć miejsce modyfikacji algorytmu konkretnego walidatora
- wygodniej tworzy się metody pomocnicze
- prostsza identyfikacja błędów (id walidatora, albo nazwa klasy) i ich "ludzka" definicja
itd.

Przy 50 i więcej walidatorów w jednej klasie, dalsza rozbudowa będzie męczarnią, a z kolei pomysł powyżej przy użyciu PSR pozwala na łatwe ładowanie tylko potrzebnych walidatorów


--------------------
KTOŚ TU PACZY???

Kompedium wiedzy
Go to the top of the page
+Quote Post
gitbejbe
post 17.10.2013, 08:26:19
Post #6





Grupa: Zarejestrowani
Postów: 515
Pomógł: 63
Dołączył: 27.08.2012

Ostrzeżenie: (0%)
-----




dobra, zakutalizowalem klase : )

link : GITGUB

Ogólnie prosze o rzucenie okiem. to moja pierwszy skrypt w oop. Działa pieknie i jest - przynajmniej dla mnie, mocno wygodny : ) Wydaje mi sie ze jest ok, ale wasze oczy moze wyłapią błedy ktore powinienem omijać

w czym lezy wygoda ? Skrypt bardzo latwo mozna rozszerzać o nowe walidatory (może zrobic to nawet laik) oraz sam proces wywołania validacji również jest łatwy i przyjazny:

  1. //pzyklad
  2. $val = new Validation();
  3. $val -> addValue([
  4. "imie" => $_POST['imie'],
  5. "login" => $_POST['login']
  6. ]);
  7.  
  8. $val -> addKey('imie') -> addRules('req,min=3,max=20,login');
  9. $val -> addKey('login') -> addRules('url');
  10. //itd itp
  11.  
  12. $val -> startValidation();
  13.  
  14.  
  15. //wyswietlanie wartosci
  16. $val->getValue('imie')
  17.  
  18. //wyswietlanie bledow
  19. $val->getErrors('email')
  20.  


DODANIE NOWEGO WALIDATORA
  1. //KROK1
  2.  
  3. //lista walidatorow w klasie abstrakcyjnej Validation_engine.
  4. //nalezy dopisac nowy element tablicy, gdzie klucz to nasza wygodna nazwa walidatora, a wartosc to nazwa metody walidującej
  5.  
  6. protected static $rules_list = array(
  7. "REQUIRED, REQ" => "_required",
  8. "MINIMUM, MIN" => "_minimum",
  9. "MAXIMUM, MAX" => "_maximum",
  10. "STRIPTAGS, STRIP" => "_striptags",
  11. "HTML" => "_htmlspecialchars",
  12. "IS_INT, INT" => "_is_int",
  13. "LOGIN" => "_login",
  14. "URL" => "_url"
  15. );
  16.  
  17. //KROK2
  18.  
  19. dodanie do klasy z walidatorami (class Validation) nowej metody, np:
  20. class Validation extends Validation_engine
  21. {
  22. protected function _required()
  23. {
  24. if(empty($this->value)) { $this->errors[$this->key] = 'te pole musi być uzupełnione'; }
  25. }
  26. }
  27.  
  28. //KONIEC : )


Ten post edytował gitbejbe 17.10.2013, 08:27:03
Go to the top of the page
+Quote Post
buliq
post 17.10.2013, 10:06:42
Post #7





Grupa: Zarejestrowani
Postów: 559
Pomógł: 93
Dołączył: 4.03.2008
Skąd: Olsztyn

Ostrzeżenie: (0%)
-----


Hmm, ok.

Zastanów się co robisz, Validator (sprawdzanie poprawności wprowadzonych danych) czy też Filter (przefiltrowanie wprowadzonych danych i w miarę możliwości zwrócenie poprawnego formatu).

Ponadto, pomysł z dodawaniem metody i jednoczesnym aktualizowaniu tablicy statycznej nie trafiony. Przecież możesz sobie ustalić że metody walidacji to takie które zaczynają się od _valid__nazwa i przy pomocy call i callStatic wybierać odpowiednie metody (ewentualnie method_exists podczas walidacji zbiorowej).

Pomyśl jeszcze nad tym, że czasami chcemy sprawdzić poprawność 1 elementu i tworzenie takiej formułki jest zbędne.
zamiast ustawiać wartości pól i później ich walidatory ja bym odwrócił proces, najpierw ustawiamy grupę elementów walidacji, i od razu ich walidatory a na koniec wartości tych pól w jakiejś tablicy, i wtedy wywołanie już samej metody która wykonuje proces walidacji. Wtedy zniknie ci problem z AddValues/__construct.


ECHO w klasie? A nie ładniej by było, gdyby te błędy były zbierane do obiektu/zmiennej w tej klasie? Wtedy dajesz metodę do pobrania wszystkich komunikatów i wyświetlasz je w odpowiednim formacie, nie narzuconym z góry. To samo z wartościami.

Dlaczego postanowiłeś postawić na tablicę z nazwami walidatorów, które umieściłeś w Engine, natomiast sama deklaracja metod jest w klasie dziedziczącej?


--------------------
KTOŚ TU PACZY???

Kompedium wiedzy
Go to the top of the page
+Quote Post
gitbejbe
post 17.10.2013, 12:19:20
Post #8





Grupa: Zarejestrowani
Postów: 515
Pomógł: 63
Dołączył: 27.08.2012

Ostrzeżenie: (0%)
-----


Cytat
Zastanów się co robisz, Validator (sprawdzanie poprawności wprowadzonych danych) czy też Filter (przefiltrowanie wprowadzonych danych i w miarę możliwości zwrócenie poprawnego formatu).

Tutaj masz racje. filtry typu striptags/htmlspecialchar nie powinny tutaj istnieć. Jednak ten skrypt bedzie stosowany tylko dla moich potrzeb i nie robie tego "komercyjnie". Sens tych 2 metod jest znikomy - a nawet żadny, ale dodałem je - przyjnajmiej tymczasowo, dla zwykłego picu : ) Powinienem o tym był wspomnieć...

Cytat
Ponadto, pomysł z dodawaniem metody i jednoczesnym aktualizowaniu tablicy statycznej nie trafiony. Przecież możesz sobie ustalić że metody walidacji to takie które zaczynają się od _valid__nazwa i przy pomocy call i callStatic wybierać odpowiednie metody (ewentualnie method_exists podczas walidacji zbiorowej).


co do call to chcialem własnie uniknąć wywoływania walidatorów w style " ->required() ->max(12) -> is_int() itd. Osobiscie bardziiej przypada mi do gustu wywoływanie jedenej metody i w niej podawania walidatorów. Tablice statyczna powstała po to aby móc wszystko ustawwić na poczatku dokumentu w klasie abstrakcyjnej. Wcześniejsza wersja opierała się na case'ach i to faktycznie było nietrafione rozwiązanie - co nie oznacza, ze obecna metoda jest elegancka. Tak to jednak sobie wymyśliłem

Cytat
ECHO w klasie? A nie ładniej by było, gdyby te błędy były zbierane do obiektu/zmiennej w tej klasie? Wtedy dajesz metodę do pobrania wszystkich komunikatów i wyświetlasz je w odpowiednim formacie, nie narzuconym z góry. To samo z wartościami.

Tutaj też masz racje. Obsługe błędów musze jeszcze dopracowac. A pomysł jak najbardziej fajny : )


Cytat
Dlaczego postanowiłeś postawić na tablicę z nazwami walidatorów, które umieściłeś w Engine, natomiast sama deklaracja metod jest w klasie dziedziczącej?


powód taki sam jaki podałem wczesniej. Chciałem aby cały mechanizm obsługi był tylko w jedenej klasie abstrakcyjnej, tak abym w klasie dziedziczącej mógł skupić sie tylko na metodach walidujących : )

Pisząc ten skrypt na nowo, kierowąłem się głównie tym co sam mi napisałeś w tym temacie:

Cytat
- przede wszystkim, klasa główna zawiera tylko logikę i w miarę zwiększania ilości walidatorów nie zwiększasz ilości linii w pliku, co wpływa na czytelność,
- łatwiej jest znaleźć miejsce modyfikacji algorytmu konkretnego walidatora
- wygodniej tworzy się metody pomocnicze
- prostsza identyfikacja błędów (id walidatora, albo nazwa klasy) i ich "ludzka" definicja


dokladnie wlasnie zrobiłem to w ten deseń : )
- logika tylko w jednej klasie
- oddzielilem walidatory do osobnej klasy i moge łatwo je edytowac oraz rozwiac w razie potrzeby
- metody pomocnicze rowniez mozna latwo dopisać
- tutaj tez sie kierowałem Twoja wczesniejszą wypowiedzią. Oddzieliłem pobranie tablic z danymi wejsciowymi (POST/GET) od ustawienia walidatorów dla tej tablicy.


Go to the top of the page
+Quote Post
buliq
post 17.10.2013, 12:49:08
Post #9





Grupa: Zarejestrowani
Postów: 559
Pomógł: 93
Dołączył: 4.03.2008
Skąd: Olsztyn

Ostrzeżenie: (0%)
-----


Cytat(gitbejbe @ 17.10.2013, 13:19:20 ) *
co do call to chcialem własnie uniknąć wywoływania walidatorów w style " ->required() ->max(12) -> is_int() itd. Osobiscie bardziiej przypada mi do gustu wywoływanie jedenej metody i w niej podawania walidatorów. Tablice statyczna powstała po to aby móc wszystko ustawwić na poczatku dokumentu w klasie abstrakcyjnej. Wcześniejsza wersja opierała się na case'ach i to faktycznie było nietrafione rozwiązanie - co nie oznacza, ze obecna metoda jest elegancka. Tak to jednak sobie wymyśliłem


Ja Ci nie karzę pozwalać użytkownikowi na wywołanie metody dziecka bez kontroli rodzica. Zwróć uwagę na to ze metody protected nie wywołasz z zewnątrz a rozwiązanie jest szybsze jeżeli automatycznie na podstawie nazwy walidatora wywołujesz metodę, nie musisz pamiętać i "zjadać paznokci", bo zapomniałeś że trzeba to jeszcze dopisać do tablicy. Przykład: walidator notEmpty, metoda protected _valid__notEmpty() {};

Cytat(gitbejbe @ 17.10.2013, 13:19:20 ) *
powód taki sam jaki podałem wczesniej. Chciałem aby cały mechanizm obsługi był tylko w jedenej klasie abstrakcyjnej, tak abym w klasie dziedziczącej mógł skupić sie tylko na metodach walidujących : )

Pisząc ten skrypt na nowo, kierowąłem się głównie tym co sam mi napisałeś w tym temacie:

...

dokladnie wlasnie zrobiłem to w ten deseń : )
- logika tylko w jednej klasie
- oddzielilem walidatory do osobnej klasy i moge łatwo je edytowac oraz rozwiac w razie potrzeby
- metody pomocnicze rowniez mozna latwo dopisać
- tutaj tez sie kierowałem Twoja wczesniejszą wypowiedzią. Oddzieliłem pobranie tablic z danymi wejsciowymi (POST/GET) od ustawienia walidatorów dla tej tablicy.


To spójrz teraz na to tak:
Jestem rodzicem i mogę mieć dzieci, nie wiem jednak co to będą za dzieci, a raczej co te dzieci będą miały, do momentu ich powstania. Do własnych operacji używam tego co posiadają dzieci, więc powinienem wymusić na dzieciach aby posiadały to czego ja potrzebuję.

Prościej: jeżeli deklarujesz tablicę z nazwami walidatorów w klasie rodzica, to nie możesz wymagać ich obecności u dzieci, może dojść do sytuacji gdzie masz grupę walidatorów w kilku klasach, dziedziczących po klasie Engine, machnąłeś się gdzieś i chcesz walidatora z innej klasy, której nie używasz, a definicja walidatora jest w Engine, więc będzie go szukać w określonej metodzie. Wywali błąd bo nie znajdzie walidatora, i prawidłowo.

Jeżeli chcesz wymusić aby "dzieci" posiadały określone metody to robi się to inaczej.
W obecnym rozwiązaniu nie masz pewności czy metoda istnieje w klasie dziedziczącej, najlepszym wyjściem byłoby deklarowanie tej tablicy w klasie dziedziczącej, albo stworzenie metody która zwracałaby wszystkie dostępne walidatory z tej klasy.

Mogłem gdzieś pomieszać, przepraszam.


@edit.

Jeszcze jedno:
Cytat(gitbejbe @ 17.10.2013, 13:19:20 ) *
Tutaj masz racje. filtry typu striptags/htmlspecialchar nie powinny tutaj istnieć. Jednak ten skrypt bedzie stosowany tylko dla moich potrzeb i nie robie tego "komercyjnie". Sens tych 2 metod jest znikomy - a nawet żadny, ale dodałem je - przyjnajmiej tymczasowo, dla zwykłego picu : ) Powinienem o tym był wspomnieć...


Jest taka zasada, jedna klasa, jedna funkcjonalność. Jeżeli masz wzorzec MVC, to widać to idealnie. Osobno jest kontrola odbieranych danych, osobno ich obróbka, osobno ich wyświetlenie. Tak samo powinieneś stosować się do tej zasady i jeżeli masz klasę do walidacji, to powinna ona tylko sprawdzać poprawność danych czyli zwracać true jak jest OK lub false jak nie jest OK, i ewentualnie błędy. Jeżeli masz klasę filtrowania danych to tak samo, albo zwracasz dane w odpowiednim formacie, albo zwracasz false/błąd/cokolwiek żeby wiedzieć że danych nie da się przetworzyć do odpowiedniego formatu.

Ten post edytował buliq 17.10.2013, 12:55:12


--------------------
KTOŚ TU PACZY???

Kompedium wiedzy
Go to the top of the page
+Quote Post
gitbejbe
post 19.10.2013, 11:55:34
Post #10





Grupa: Zarejestrowani
Postów: 515
Pomógł: 63
Dołączył: 27.08.2012

Ostrzeżenie: (0%)
-----


ok bede poprawiać. Chciałbym aby ta klasa była napisana raz a porządnie, abym mógł z niej korzystać w każdym moim projekcie.

dla mnie najistotniejszym elementem jest samo wywołanie validacji. chciałbym aby było to jak najprostrze i intuicyjne do wykonania.

co w takim razie proponujesz ?

chodzi mi o samo to jak mam najlepiej jest wywołać walidajcje, np:

$val-> addValue(['imie' => $_POST['imie']]) -> addRules('req,min=3,max=20,login');

albo

$val-> addValue(['imie' => $_POST['imie']]) -> _required() -> max(6);

albo

$val-> addValue([
'imie' => $_POST['imie'],
'login' => $_POST['login']
])
-> _required() -> max(6);

$val-> addKey(phone') addValue($_POST['imie']) -> _isInt();

albo

$val-> addKey('imie') addValue($_POST['imie']) -> _required() -> max(6);

itd itp

Kombinacji moze być wiele, dostosować klase tez nie jest trudno, chodzi mi tylko o to jaki z tych wywołań będzie najbardziej praktyczny i wygodny. Ogólnie od samego początku widzi mi się aby każda wartość do sprawdzenia była zapisana tylko w jednej linijce - nawet jesli kazda wartosc do sprawdzenia w nowej linijce bedzie musia miec np powielony walidator required. Nie chce robić bardaku w kodzie a takie rozwiązanie uważam, że jest bardzo wygodne. Od razu widać co się dzieje.


EDIT:

przemyślałem to i uważam, ze:

$val -> new Validation();
$val -> addKey('imie') -> addValue($_POST['imie']) -> required() -> max(5) -> min(10);
$val -> addKey('login') -> addValue($_POST['login']) -> required() -> max(5) -> min(10);
itd
if(empty($val->errors)) {echo 'ok';}

bedzie najlepszym rozwiązaniem


EDIT:2

przerobiłem. Szybko mi to poszlo : )

https://gist.github.com/gitbejbe/6762020

oczywiście pięknie działa

Ten post edytował gitbejbe 19.10.2013, 14:01:00
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Wersja Lo-Fi Aktualny czas: 28.03.2024 - 11:07