Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Sprawdzanie poprawności danych.
Forum PHP.pl > Forum > PHP > Object-oriented programming
Rysh
Zainteresowałem się ostatnio silnikiem gry ezRPG i w nim mam taką oto klasę:
  1. <?php
  2. //This file cannot be viewed, it must be included
  3. defined('IN_EZRPG') or exit;
  4.  
  5. /*
  6.   Class: Module_Members
  7.   Shows a list of members.
  8. */
  9. class Module_Members extends Base_Module
  10. {
  11. /*
  12.   Function: start
  13.   Displays the members list page.
  14.   */
  15. public function start()
  16. {
  17. //Require login
  18. requireLogin();
  19.  
  20. if (isset($_GET['page']))
  21. $page = (intval($_GET['page']) > 0) ? intval($_GET['page']) : 0;
  22. else
  23. $page = 0;
  24.  
  25. $query = $this->db->execute('SELECT `username`, `level` FROM `<ezrpg>players` ORDER BY `id` ASC LIMIT ?,50', array($page * 50));
  26. $members = $this->db->fetchAll($query);
  27.  
  28. $prevpage = (($page - 1) >= 0) ? ($page - 1) : 0;
  29.  
  30. $this->tpl->assign('nextpage', ++$page);
  31. $this->tpl->assign('prevpage', $prevpage);
  32. $this->tpl->assign('members', $members);
  33. $this->tpl->display('members.tpl');
  34. }
  35. }
  36. ?>

Czy sprawdzanie takich danych jak $_GET['page'] (czy liczba), powinno znajdować się wewnątrz klasy czy na zewnątrz?
I drugie pytanie przy okazji, czy dane takie jak $_GET nie powinny być przesyłane za pomocą zmiennej do klasy tak jak do zwykłej funkcji:
  1. $klasa->funkcja($_GET['cos'])
Sephirus
Nie ma jednoznacznej odpowiedzi na twoje pytania ale postaram Ci się nakreślić temat smile.gif

Ogólnie przyjęło się robić w ten sposób, że metody klasy jak i sama klasa powinna być zamknięta na zewnątrz. Co oznacza, że nie powinno się używać raczej zmiennych typu $_GET itp w jej wnętrzu. Aby zachować przejrzystość i uniwersalność takiej metody/klasy należy jej żądane parametry przekazać (jeśli boisz się o pamięć - można referencyjnie). Grunt aby dana metoda przyjmowała w argumentach swoich to - co jest jej potrzebne do działania. Przykładowo jeśli masz swoją klase i pracujesz na tablicy $_GET to zmiana na $_POST to kwestia kilku linijek - jeśli dawałbyś to $_GET jako argument metody i dalej pracował na zmiennej lokalnej to zmiana na $_POST była by tylko w jednym miejscu - co więcej można by tam było wrzucać dowolne rzeczy - tak więc mamy uniwersalność smile.gif

Co do samego sprawdzania zmiennych to są w zasadzie trzy drogi z czego moim zdaniem jedna jest najlepsza:

1. Walidacja danych przed wrzuceniem do metody - zaletą jest to że metoda staje się lżejsza, brak w niej kodu odpowiadającego za walidację stąd też lepiej widać jej samą funkcjonalność. Wadą natomiast jest to, że przed każdym wywołaniem metody musisz walidować dane - można się zapomnieć.

Wyjątkiem od tej wady jest opcja gdy dana metoda jest zawsze wywoływana przez inną, która to zawsze przekazuje już zwalidowane dane. Wtedy oczywiście ta metoda jest najlepsza (po co walidować coś dwa razy?)

2. Walidacja wewnątrz metody i klasy - Na początku metody mamy walidację danych potem kod funkcjonalny samej metody. Zaleta - dane zawsze są walidowane - wada - zaciemnia i powiększa to kod metody.

3. Walidacja wenątrz klasy ale nie metody - W klasie tworzysz dodatkową metodę (prywatną odpowiadającą za walidację danych). W swojej metodzie na początku przekazujesz dane do metody walidującej i dalej wykonujesz kod samej metody. Zaleta jest taka że masz zawsze walidację oraz fakt że dana metoda walidująca może być użyta w wielu miejscach bądź nawet uniwersalna. Dodatkowa zaleta jest taka że masz zawsze walidację w jednym miejscu. Wadą (minimalną) jest to, że w danej metodzie znajduje się "jedna linijka" walidująca dane - lecz nie jest to takie straszne.

Podsumowując - moje propozycje:
ad. 1 - Waliduj wewnątrz klasy - jeśli się uda to zrób dodatkową metodę walidującą aby nie zaciemniać kodu twojej metody
ad. 2 - Przekazuj zmienne w argumentach - uzyszkasz większą skalowalność oraz uniwersalność - plus łatwość zmian parametrów wejściowych (klasa będzie działać zawsze tak samo - Ty wtedy decydujesz na jakich danych w szybki i prosty sposócool.gif
Crozin
1. Powinieneś zawsze stronić od stanu globalnego i w miarę możliwości/zdrowego rozsądku od stanu statycznego. $_GET to zmienna superglobalna - chyba nie trzeba komentować jak zła zatem jest. wink.gif
2. Sprawdzanie poprawności danych to tak szerokie zagadnienie, obejmujące tak różne struktury danych/konstrukcje, że nie da się przyjąć jakiegoś ogólnego modelu i podsumować go jednym zdaniem. Dla tego konkretnego przypadku powinno to raczej być:
  1. /**
  2.  * @param int $chunk Numer strony/porcji zwracanych danych
  3.  */
  4. public function start($chunk) {
  5. if ($chunk < 0) {
  6. throw new InvalidArgumentException('...');
  7. }
  8. }
Tak więc w tym konkretnym przypadku metoda powinna już oczekiwać liczby (niestety język nie pozwala na wygodne zapisanie czegoś takiego*), ale we własnym zakresie może sprawdzić czy aby przypadkiem nie podano nieprawidłowego argumentu.

* od biedy można wewnątrz metody zrzutować sobie zmienna na dany typ: $chunk = (int) $chunk.
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.