PHP, zakres zmiennych

PHP, zakres zmiennych
KR
  • Rejestracja:prawie 16 lat
  • Ostatnio:6 miesięcy
  • Postów:2514
0

Witam, dzisiaj się spotkałem z dość nietypowym dla mnie zjawiskiem, otóż w swoim kodzie miałem taki zapis:

Kopiuj
for ($tab as &$val)
  {
   ...
  }

i w dalszej części kodu potrzebowałem użyć zmiennej tymczasowej i nazwałem ją $val, po czym w dalszej części kodu zaczęły się dziać rzeczy które dziać się nie powinny... zaczęłem zastanawiać się o co chodzi i zaczęłem komentować różne partie kodu i doszedłem do wniosku, że kod w takiej postaci działa:

Kopiuj
/*for ($tab as &$val)
  {
   ...
  }*/

a w takiej:

Kopiuj
for ($tab as &$val)
  {
   /*...*/ // <-- zakomentowane wnętrze pętli
  }

już nie!

oczywiście jedyna myśl, która człowiekowi przychodzi w takiej chwili to: WTF?

zatem zaczęłem sprawdzać o co chodzi, używając var_dump przed i po pętli doszedłem do wniosku, że ostatni element tablicy nie jest tym obiektem co powinien być tylko referencją do niego (ampersand& przed array (...)).

Po tym nie dużo czasu zajęło mi znalezienie jak poradzić sobie z tym "zjawiskiem".

Wystarczy poza pętlą pozbyć się referencji...

Kopiuj
unset($val);

na pierwszy rzut oka wydawało mi się, że zapis ten usunie mi cały obiekt, jednak (na szczęście) zadziałał poprawnie.

I teraz pojawia się moje pytanie: Czy twórcy PHP w ogóle (k..a) wiedzą co to jest zakres zmiennych? Czy takie dziwolągi tego języka komukolwiek przynoszą korzyści?


░█░█░█░█░█░█░█░█░█░█░█░
KR
"foreach" powinno być wszędzie zamiast "for"
KO
  • Rejestracja:ponad 14 lat
  • Ostatnio:około 10 lat
  • Postów:114
0

Nic dziwnego, że to nie działa

Kopiuj
for ($tab as &$val)
  {
   /*...*/ // <-- zakomentowane wnętrze pętli
  }

powinno być

Kopiuj
foreach ($tab as &$val)
  {
   /*...*/ // <-- zakomentowane wnętrze pętli
  }

No chyba, że moje apache jest zesrane i nie wie o czymś o czym ja również nie wiem

KR
  • Rejestracja:prawie 16 lat
  • Ostatnio:6 miesięcy
  • Postów:2514
0

tak miałem u siebie tylko odruchowo jeszcze "for" piszę :P


░█░█░█░█░█░█░█░█░█░█░█░
KO
  • Rejestracja:ponad 14 lat
  • Ostatnio:około 10 lat
  • Postów:114
0

No dla mnie php jest nie logiczne :P

ostatnio if('sssss' == 0) echo 1; dało oczywiście 1, według mnie logicznie jest tak jak to powiedziałem w moim temacie

"...po prostu wydało mi się oczywiste że przy porównywaniu stringa z liczba to liczba zostanie zamieniona na stringa po przecież każda liczba może być stringiem ale nie każdy string może być liczba..."

a zasięg zmiennych jest chyba tylko w klasach i funkcjach :P

KR
to jest akurat logiczne, w C++ albo by się to nie skompilowało albo co gorsza zaczęłoby porównywać wskaźnik.
KO
dla mnie to nie jest logiczne, rzutując int na stringa zawsze dostaniemy tą samą liczbę, a na odwrót nie, bo 'ssss' nie jest liczba
KR
tak, ale na logike to porównywanie tekstu z liczbą jest głupie, poza tym najczęściej jednak konwertuje się w drugą stronę
0

na pierwszy rzut oka wydawało mi się, że zapis ten usunie mi cały obiekt, jednak (na szczęście) zadziałał poprawnie.

No bo w końcu to jest referencja, nie?

http://php.net/manual/en/control-structures.foreach.php
http://i-code-today.blogspot.com/2009/02/php-array-foreach-loop-with-references.html

Coś mi się wydaje, że takie problemy to do newbie. Tak, w tym wypadku twórcy php dali ciała, nie pierwszy, nie ostatni raz z resztą...

PS. Manual przyjacielem programisty... szkoda marnować czas na pisanie tematu.

0

@konrados
Poznaj różnicę między == a ===.
A zakres zmiennych nie dotyczy tylko klas -.-, co najwyżej modyfikatory dostępu :)

KO
A ty poznaj to, że to właśnie miał być string ... tylko po prostu myślałem, że php zrobi z tej liczby stringa a nie odwrotnie -_- operator === dał by mi zły wynik, bo string nie równe integer
0

Wyrażę się jaśniej. Operator == to operator porównywania, jeśli porównuje się dwie zmienne o różnych typach, jedna z nich jest rzutowana na typ drugiej. Operator === to operator identyczności, nie wykonuje się rzutowana, po prostu sprawdza się czy zmienne są identyczne. Zmienne różnych typów nie są identyczne, jak z resztą podpowiada logika.
Twój przykład był niefortunny, ponieważ stringi niezawierające żadnej cyfry są rzutowane jako 0 (dokładnie nie pamiętam, więc mogę się mylić) - stąd też takie cuda.
O tę właśnie różnicę chodziło w moim poście.

Jaki problem sprawia zaznaczenie, że to int ma być rzutowany na stringa? W takim przypadku === / == nie nie dają różnicy?

Kopiuj
if ('12' === (string)12) echo 'Równe'; //'Równe'
if ('12' === 12) echo 'Równe'; //''
if ('12' == (string)12) echo 'Równe'; //'Równe'
if ('12' == 12) echo 'Równe'; //'Równe''
if ('12' === 12) echo 'Równe'; //''
if ('12' === (string)12) echo 'Równe'; //'Równe'

Przy czym:

Kopiuj
if ('12s' == (string)12) echo 'Równe'; //''
if ((int)'12s' == 12) echo 'Równe'; //'Równe'
KR
może załóżcie sobie temat osobny :P
KO
dobra weź człowieku się ogarnij nie mam dwóch latek żebyś mi tłumaczył różnice między === a == zapisałem liczbę jako string jak się dowiedziałem, że string się zamienia na 0 "Jaki problem sprawia zaznaczenie, że to int ma być rzutowany na stringa?" taki, że myślałem, że php sam rzutuje int'a na stringa

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.