Drukowana wersja tematu

Kliknij tu, aby zobaczyć temat w orginalnym formacie

Forum PHP.pl _ PHP _ Zmienne lokalne i sprawdzanie argumentów

Napisany przez: Brick 14.11.2017, 13:12:45

W sumie dwa pytania:
1. Czy używacie specjalnych zmiennych lokalnych wewnątrz funkcji żeby zwiększyć czytelność kodu?
Zamiast:

  1. function convertString($string)
  2. {
  3. $string = doSomething($string);
  4. return $string;
  5. }

Coś takiego:
  1. function convertString($input_string)
  2. {
  3. $converted_string = $input_string;
  4. $converted_string = doSomething($converted_string);
  5. return $converted_string;
  6. }

W książce "Kod doskonały" autor pisze, że jest to dobry zwyczaj bo jest jasne co jest wartością zadaną a co wyjściową. Ale zastanawiam się jak to jest w praktyce.

2. Czy sprawdzanie argumentów funkcji ma zawsze sens?
Przykładowo
  1. function convertString($string)
  2. {
  3. if ($string)
  4. {
  5. $string = doSomething($string);
  6. }
  7. return $string;
  8. }

Na ogół tak robię zakładając, że nie ma sensu wykonywać jakiś operacji jeżeli nie ma na czym tego wykonać (wartość równa null). Ale może to niepotrzebne komplikowanie kodu gdyż (jak zakładam) PHP nie będzie wykonywać operacji na pustych danych?
Cały czas mam na myśli właśnie takie małe, dość proste funkcje a nie bardziej złożone gdzie kontrola argumentów jest po prostu konieczna.

Napisany przez: viking 14.11.2017, 13:21:01

1. zależy od kontekstu. Ja używam zazwyczaj tylko jak potrzebuję oryginalną zmienną gdzieś jeszcze. I kod też od razu zamiast return $string, return some();
2. Wiesz że jest PHP 7 i to co opisałeś załatwia się bezpośrednio? https://seld.be/notes/php-versions-stats-2017-2-edition Według statystyk packagist PHP 7 to już prawie 70% wszystkich wersji. Może pora przestać udawać że nie istnieje?

Napisany przez: Pyton_000 14.11.2017, 13:40:57

1. Każdy sobie jak woli.

2. Tu type hint załatwia sprawę.Oczywiście PHP7.

Napisany przez: Brick 14.11.2017, 22:19:54

A jak nie macie na serwerze dostępnej wersji PHP 7? Niestety trafiają mi się takie serwery (np. na jakiejś uczelni).
Nie bierzecie takich zleceń?

A w czasach gdy nie było PHP 7 to jak robiliście? Sprawdzaliście czy nie? Ciekawy jestem czy PHP wykona jakąś dodatkową pracę jeżeli zmienna nie będzie pusta a sama funkcja będzie dość rozbudowana tj wiele będzie wykonywać wiele różnych operacji na tej zmiennej.

Napisany przez: Tomplus 15.11.2017, 06:43:19

To zalezy od rozbudowania kodu.
Jeżeli masz bardzo dużo zmiennych których trzeba sprawdzić, to oczywiście taka funkcja będzie potrzebna.

Ale czasem nawet w wersjach starszych wystarczy:
isset($string) ? $string : 'brak_stringa';

A co do wersji PHP, szczególnie uczelnie powinny mieć aktualne wersje PHP, jeżeli nie mają należy im to zgłosić, zwykle administratorzy uczelnianych serwerów zabierają się do pracy gdy jest takie zapotrzebowanie. Znam to z autopsji.

Napisany przez: Pyton_000 15.11.2017, 08:49:10

Ogólnie metoda powinna sprawdzać to co dostaje w myśl zasady "Nigdy nie wierz użytkownikowi", więc jeśli nie masz silnego typowania np. string, array, int to ta, trzeba to sprawdzać ręcznie wg. wymogów metody. A jak to juz wedle widzimisię. Ale wygodne jest np. użycie lib: https://github.com/beberlei/assert

Napisany przez: Brick 15.11.2017, 11:01:44

Chodzi mi o przypadek w którym wartość w argumencie w ogóle nie jest wymagana, tzn prawidłowe działanie funkcji też jest takie że nic nie zwraca. Czyli np string wsadowy może być pusty i wtedy funkcja zwróci pusty wynik. I to jest ok tylko czy te wszystkie operacje które wykona na pustym stringu będą jakimś obciążeniem dla serwera?

Może trzeba by zapytać twórców PHP jak to właściwie działa ...

Ciekawa ta biblioteka beberlei/assert. Używa się tego tylko do pisania testów czy normalnie w produkcji?

Co do wersji PHP na serwerach to różnie z tym bywa. Z mojego doświadczenia wynika że im większa uczelnia tym większa bezwładność i biurokracja. Są takie które zaktualizują a są takie w których odpowiedź jest "nie przewidujemy obecnie aktualizacji" i tyle. Zresztą czasem od razu w specyfikacji zapytania ofertowego jest określona wersja PHP.

Są też firmy, które mają swoje serwery i wychodzą z założenia że jak działa to nic nie trzeba ruszać (poza aktualizacjami bezpieczeństwa). No i zadają proste pytanie: "A na starszej wersji PHP to da się zrobić? Jak się da to o co chodzi?".

Trochę zjeżdżam z tematu ale chyba nie ma sensu zakładać nowego wątku choć zagadnienie ciekawe.

Napisany przez: Pyton_000 15.11.2017, 11:10:44

beberlei/assert normalnie na prod. właśnie żeby nie robić ifów, po prostu pakujesz wartość i jak coś nie gra to rzuca wyjątkiem.

Co do sprawdzania powiem jeszcze raz, sprawdzaj zawsze bo jesli oczekujesz string jako input to tak ma być, a każda inna powoduje jakąś akcję albo exception, albo zwrot domyślnego return.

Napisany przez: nospor 15.11.2017, 12:53:11

Cytat
function convertString($input_string)
{
$converted_string = $input_string;
$converted_string = doSomething($converted_string);
return $converted_string;
}


W książce "Kod doskonały" autor pisze, że jest to dobry zwyczaj bo jest jasne co jest wartością zadaną a co wyjściową. Ale zastanawiam się jak to jest w praktyce.

Przyklad co podales, to powinien wygladac w ogole tak:

  1. function convertString($input_string)
  2. {
  3. return doSomething($input_string);
  4. }
  5.  



zas to co zrobiles tutaj
$converted_string = $input_string;
to juz totalna bzdura. Musiales zle zrozumiec co napisali w ksiazce wink.gif

zas co do przykladu:

Cytat
function convertString($string)
{
if ($string)
{
$string = doSomething($string);
}
return $string;
}

To unikaj zagniezdzen i koncz funkcje jesli nie ma racji bytu reszta logiki, np:

  1. function convertString($string)
  2. {
  3. if (!$string) {
  4. return null;
  5. }
  6.  
  7. return doSomething($string);
  8. }

Napisany przez: Brick 15.11.2017, 14:25:07

Dzięki za odpowiedzi.

W książce chodziło trochę o inny przypadek, gdy argument funkcji nazywa się inputValue i potem w ciele funkcji robi się na nim różne działania i na końcu jest zwracana zmienna, dalej nazywająca się inputValue. To jest jasny przypadek, że tak nie powinno się robić bo wprowadza w błąd. Ale zastanawiałem się czy ma sens pójście krok dalej czyli trochę sztuczne dodatkowe nazywanie zmiennych. W moim przykładzie "doSomething" jest oczywiście bardziej złożoną procedurą, więc użycie zmiennej robi się konieczne.

No ale chyba macie rację, takie kombinowanie sztuczne z nazwami nie ma sensu.

Napisany przez: Pyton_000 15.11.2017, 14:28:39

A to też zależy. Bo np metodlogia pracy z valueObject zakłada że każda modyfikacja produkuje nowy element.

Więc np:

  1. <?php
  2.  
  3. function magicMethot($value) {
  4. $transformed = transform($value);
  5. $reversed = reverse($transformed);
  6.  
  7. return $reversed;
  8. }

To oczywiscie bardzo szkicowy przykład i pozostawia wiele do życzenia ale chodzi o koncept.

Napisany przez: nospor 15.11.2017, 14:34:25

Cytat
ale chodzi o koncept.
A mozesz wyjasnic jasniej ten koncept? Bo ja szczerze nie zrozumialem, zas kod co tu masz to bym napisal poprostu tak:

  1. function magicMethot($value) {
  2. return reverse(transform($value));
  3. }


Od biedy tak:

  1. function magicMethot($value) {
  2. $transformed = transform($value);
  3.  
  4. return reverse($transformed);
  5. }

smile.gif

Napisany przez: Pyton_000 15.11.2017, 14:47:22

Value Object czyli że każda modyfikacja obiektu prowadzi do utworzenia nowego obiekktu.
Tutaj to jest dość prosty przykład.

Ale mając dużo większą logikę w metodzie rozbicie wejścia na kilka zmiennych opisujących ich stan da nam obraz kiedy i gdzie zmienia się stan naszej zmiennej wejściowej.

Napisany przez: nospor 15.11.2017, 14:49:14

Cytat
Value Object czyli że każda modyfikacja obiektu prowadzi do utworzenia nowego obiekktu.
Ja to wiem (bylismy na tej samej sesji wink.gif ). Nie wiem jednak jak ma sie do tego twoj kod, temu pytam smile.gif

Napisany przez: Pyton_000 15.11.2017, 15:07:15

Tak że transformacja generuje nowy zestaw danych. Chodzi po prostu o rozróżnianie co jest czym.
Nie mówię też że zawsze i wszędzie takie podejście bo tutaj w przypadku takim co podałem faktycznie nie ma to sensu bo metoda jest do ogarnięcia.
Ale jesli już metoda ma wielkość ekranu to robi się bardziej zawile.

Napisany przez: nospor 15.11.2017, 15:17:44

No dobrze, ale niewazne czy masz ValueObject czy poprostu tekst, to przy bardzo zawilym kodzie, odpowiednie nazewnictwo zmiennych ma znaczenie tak czy siak smile.gif

takze zmierzam do tego, ze uzywanie ValueObject nie wymusza na nas zmieniania nazw zmiennych. Zmiana nazw zmiennych jest potrzebna dla czytelnosci tylko, prosty przyklad

  1. class valueObjectClass
  2. {
  3. private $v1;
  4.  
  5. public function __construct($v1)
  6. {
  7. $this->v1 = $v1;
  8. }
  9.  
  10. public function display()
  11. {
  12. http://www.php.net/echo $this->v1;
  13. }
  14.  
  15. public function modify($v1)
  16. {
  17. return new self($v1);
  18. }
  19. }
  20.  
  21. $vo1 = new valueObjectClass(1);
  22. http://www.php.net/echo 'After creation: ';
  23. $vo1->display();
  24.  
  25. $vo2 = $vo1->modify(2);
  26. http://www.php.net/echo 'After modification: ';
  27. $vo2->display();
  28. http://www.php.net/echo 'And again original: ';
  29. $vo1->display();
  30.  
  31. http://www.php.net/echo 'Ok, now we will not change name of the variable';
  32. $keepOriginal = $vo1;
  33. $vo1 = $vo1->modify(22);
  34. http://www.php.net/echo 'After modification: ';
  35. $vo1->display();
  36. http://www.php.net/echo 'And original not changed: ';
  37. $keepOriginal->display();
  38.  

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)