Autor Wątek: [PHP] Pytanie-ciekawostka  (Przeczytany 5766 razy)

Offline Astisus

  • Użytkownik
    • Portfolio

# Listopad 30, 2014, 23:56:26
Dziś natknąłem się na dziwny przypadek, który przypadkowo rozwiązałem, jednak nadal nie wiem co jest powodem i mam nadzieję, że ktoś zaspokoi moją ciekawość.

Miałem do zmiennej $r["imie"] przypisaną wartość, jednak wszystko wskazywało, że jest pusta. Jednak taki kod:
if (is_null($r["imie"]))
{
    echo $r["imie"];
}
wyświetlał... wartość (np. Andrzej)

Co ciekawe wpisanie od nowa nazwy zmiennej sprawiło, że wszystko wróciło do normy. Jednak, żeby nie było, że to literówka - po cofnięciu kodu nawet "szukajka" się gubiła i wyświetlała 1 znalezienie przy 2 identycznych odwołaniach.
« Ostatnia zmiana: Grudzień 01, 2014, 00:01:18 wysłana przez Astisus »

Offline Mr. Spam

  • Miłośnik przetworów mięsnych

Offline Xion

  • Moderator
    • xion.log

  • +5
# Grudzień 01, 2014, 06:12:48
Chociaż usilnie ciśnie mi się na usta "lolphp!", akurat tutaj niekoniecznie musi to być wina tego, ahem, języka. Szkoda, że nie zachowałeś oryginalnego kodu, bo z przepisanego kawałka który wkleiłeś powyżej nie da się już nic pewnego wywróżyć.

Tak czy inaczej, skrócona lista możliwych przyczyn prezentuje się następująco (kolejność przypadkowa):
  • Któryś ze znaków w nazwie zmiennej lub klucza nie jest tym, czym się wydaje na pierwszy rzut oka. Przykładowo, "e" mogło być niemal identycznym znakiem z cyrylicy. (Więcej info: http://en.wikipedia.org/wiki/IDN_homograph_attack)
  • Gdzieś w kluczu zaplątał się niedrukowalny znak o długości zero; w Unicode jest ich mnóstwo, począwszy od markerów podziału słów, a kończąc na znacznikach zmiany kierunku tekstu (LTR <-> RTL).
  • Wszystko było w porządku, "Andrzej" wyświetlał inny kawałek kodu, a ty popełniłeś jakąś gafę przy korzystaniu z Ctrl+F (zdarza się najlepszym).
  • Między is_null() a echo zmieniła się wartość tego elementu tablicy (race condition, inaczej mówiąc).
  • Odkryłeś buga w is_null(), implementacji tablic w PHP, w swoim edytorze, systemie plików, OS, etc.
  • cośtam cośtam zasięg zmiennych (pierwsze $r odwołuje się do globalnej tablicy, drugie do lokalnej, albo odwrotnie, albo jeszcze inaczej -- nie znam się, jak to działa w PHP)
  • is_null nie jest tym is_null, które myślałeś, że wywołujesz
  • etc. etc.
Część z tych przyczyn da się oczywiście wyeliminować brzytwą Ockhama (przynajmniej dopóki nie zacznie działać zasada Sherlocka Holmesa), ale IMHO przynajmniej połowa nie jest nieprawdopodobna. Jak wspomniałem wyżej, zachowanie oryginalnego kodu byłoby bardzo pomocne; bez niego zostaje raczej tylko spekulacja.

Offline conx

  • Użytkownik

# Grudzień 01, 2014, 10:38:00
Panie moderatorze to forum i cały warsztat jest na "lolphp!", jak i 60% internetu(wp,allegro,facebook, yahoo). Podaj jeden przykład, dlaczego PHP jest bee, co jest lepsze?

Nie znam się ale się wypowiem.

Rafał

Offline Xirdus

  • Redaktor

# Grudzień 01, 2014, 10:58:57
http://eev.ee/blog/2012/04/09/php-a-fractal-of-bad-design/

Osobiście skłaniałbym się do tego, że są w tym stringu jakieś znaki niedrukowalne. Napisz tego ifa na nowo i zobacz czy problem dalej występuje. Jeśli to możliwe, możesz też zamienić is_null() na array_key_exists().

Offline DarkEngineer

  • Użytkownik

# Grudzień 01, 2014, 11:44:15
to sprawdzaj czy jest jeszcze odpowiednie wyrażenie zawarte
http://php.net/manual/en/function.ctype-alpha.php albo możesz użyć wyrażenia regularnego do sprawdzenia http://php.net/manual/en/function.preg-match.php
 
ale też można to zrobić jeszcze lepiej
function IsNullOrEmptyString($question){
    return (!isset($question) || trim($question)==='');
}

is_null sprawdza tylko czy do zmiennej tego typu nie została wpisana jakakolwiek wartość, zdarza się że zmienna zawiera jakieś śmieci jeśli tak sprawi kod, co trzeba uwzględnić.

BTW Widać że na tym forum są ludzie nie potrafiący PHP (przepraszam z wytykanie jeśli to kogoś uraziło)
« Ostatnia zmiana: Grudzień 01, 2014, 12:01:39 wysłana przez DarkEngineer »

Offline Karol

  • Użytkownik

# Grudzień 01, 2014, 12:02:45
Ja bym użył isset :)

BTW Widać że na tym forum są ludzie nie potrafiący PHP (przepraszam z wytykanie jeśli to kogoś uraziło)
To chyba Ciebie coś uraziło ;) Sam lubię PHP, ale jest to język pełen dziwności i niekonsekwencji i ma swoje minusy jak i plusy. Sam fakt, że jest tyle możliwości weryfikacji czy zmienna jest świadczy o jakimś bałaganie :P

Offline conx

  • Użytkownik

# Grudzień 01, 2014, 14:37:20
Mi takie dziwne rzeczy się działy gdy coś namieszałem z referencjami np. w foreachu.
Ja też używam raczej isset ale jest też "===", można zrobić mały debug var_dump(), użyć sizeof()...
możliwości jest wiele.

ps. nie zgodzę się, że PHP jest złe bo złe czy pełne dziwności - proszę o uzasadnienie. PHP to zwykły język skryptowy bez twardego typowania do stronek www na bacendzie. Tylko tyle i aż tyle - ni zły ni dobry. Jak znasz się na OOP to możesz wszystko. Dla przykładu java oferuje: pochlania setki MB/GB RAM, jest niestabilna, wielowątkowość to loteria,nie ma czegoś takiego jak time-execution limit na serverze, straszne XMLe straszą, przekombinowana. Ludzie od designu Java mają taka paranoję na OOP, że każde małe zadanie rozbijane jest na 5-10 klas, proste zadania rosną do poziomu - Mission Impossible.

Dziękuję
« Ostatnia zmiana: Grudzień 01, 2014, 14:45:16 wysłana przez conx »

Offline Stark

  • Użytkownik

# Grudzień 01, 2014, 15:13:11
"Casting a variable to null using (unset) $var will not remove the variable or unset its value. It will only return a NULL value."

Polecam empty(). :P

https://www.virendrachandak.com/techtalk/php-isset-vs-empty-vs-is_null/

Offline Xirdus

  • Redaktor

# Grudzień 01, 2014, 16:37:51
Dyskusję o PHP jako takim wydzieliłem do osobnego wątku: http://forum.warsztat.gd/index.php?topic=29515.0

Offline Astisus

  • Użytkownik
    • Portfolio

# Grudzień 01, 2014, 16:58:02
Hm... Dobra, nie mam zamiaru brać udziału w rozmowie na temat samego PHP (brak większego doświadczenia) więc wracam do tematu.

Jako, że stary plik zachowałem, pozwoliłem sobie okroić do minimum całą funkcje, przypisać na stałe dane wejściowe i wyszło mi takie coś:
<?php
function 
TestowaFunkcja($dane) {
foreach ($dane as $r) {
echo $r["imie"] . " - ";
if (is_null($r["imie"])) {
echo "Puste<br>";
} else {
echo "Nie puste<br>";
}
}
}

$dane[0]["imie"] = "Andrzej";
$dane[1]["imie"] = "Stefan";

TestowaFunkcja($dane);
?>


Kod zwraca:
Andrzej - Puste
Stefan - Puste

Najprawdopodobniej jeden z znaków tak jak pisał Xion nie jest tym czym się wydaje lub prawdziwa jest wersja Xidrusa.  Wyraźnie odpada inny kawałek kodu, wartość też się nie zmienia. Wersja w bugiem też jest mało prawdopodobna.

isset() i empty() też nie dają rady, więc znowu potwierdza się wersja Xiona i Xidrusa.

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

if ('$r["imie"]' == '$r["imie"]')
{
echo "Równe";
} else {
        echo "Różne";
}

Natomiast ten kawałek kodu zwraca "różne", więc moja ciekawość chyba już została zaspokojona ;)

@edit:
Dobra, zmieniłem kodowanie z UTF-8 na ANSI i niektóre $r["imie"] to tak naprawdę $r["imie"], wszystkim dzięki za odpowiedzi!
« Ostatnia zmiana: Grudzień 01, 2014, 17:02:22 wysłana przez Astisus »