PHP, zakres zmiennych

0

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

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:

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

a w takiej:

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...

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?

0

Nic dziwnego, że to nie działa

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

powinno być

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

0

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

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

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 :)

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?

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:

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

1 użytkowników online, w tym zalogowanych: 0, gości: 1