$n = '[email protected]'; $dl = strlen($n); $i = 0; while ($i < $dl && $n[$i] != '@') { echo $n[$i]; $i++; } Fragment kodu w języku PHP wypisze
$n = '[email protected]'; $dl = strlen($n); $i = 0; while ($i < $dl && $n[$i] != '@') { echo $n[$i]; $i++; }Fragment kodu w języku PHP wypisze
A. samą nazwę konta, czyli 'adres'
B. samą nazwę domeny, czyli 'host.pl'
C. nazwę konta ze znakiem @, czyli 'adres@'
D. cały adres e-mail, czyli '[email protected]'
Pytanie z egzaminu CKE, październik 2016 (arkusz E.14-X-16.08).
Kod wypisze samą nazwę konta, czyli 'adres', ponieważ pętla while przechodzi po znakach tekstu od początku łańcucha aż do momentu napotkania znaku '@'. Zmienna $n przechowuje adres '[email protected]', a $dl = strlen($n) oblicza jego długość. Indeks $i startuje od 0, więc najpierw pobierany jest znak $n[0], potem $n[1] itd. Warunek pętli ma dwie części: $i < $dl zabezpiecza przed wyjściem poza koniec napisu, a $n[$i] != '@' sprawdza, czy aktualny znak nie jest separatorem między nazwą konta a domeną. Dopóki znak nie jest małpą, instrukcja echo wypisuje go na ekran. Gdy $i dojdzie do znaku '@', warunek przestaje być spełniony i pętla się kończy, więc '@' nie zostanie wypisane. Moim zdaniem to bardzo klasyczny przykład ręcznego parsowania tekstu, przydatny do zrozumienia indeksowania napisów i działania pętli. W praktycznym PHP do takiego zadania często używa się funkcji explode('@', $email) albo strstr, ale warto rozumieć ten mechanizm od podstaw. Dobra praktyka przy prawdziwych adresach e-mail to też wcześniejsza walidacja, np. przez filter_var($email, FILTER_VALIDATE_EMAIL), bo samo znalezienie znaku '@' nie oznacza jeszcze poprawnego adresu.
W tym fragmencie łatwo pomylić się, jeśli patrzy się tylko na cały zapis '[email protected]' i zakłada, że echo wypisze wszystko, co znajduje się w zmiennej. Tak jednak nie jest, bo echo znajduje się wewnątrz pętli, a pętla ma bardzo konkretny warunek zatrzymania. Program nie wypisuje całego adresu e-mail, ponieważ wykonywanie pętli kończy się dokładnie wtedy, gdy aktualnym znakiem staje się '@'. To ważny szczegół: znak jest sprawdzany w warunku przed wejściem do ciała pętli, więc jeśli $n[$i] ma wartość '@', instrukcja echo nie zostanie już wykonana dla tego znaku. Dlatego wynik nie może zawierać ani domeny, ani samego znaku '@'. Błędne jest też założenie, że kod wypisze nazwę konta razem z małpą. Taki wynik pojawiłby się dopiero wtedy, gdyby echo było wykonane przed sprawdzeniem warunku albo gdyby warunek był skonstruowany inaczej. Tutaj separator '@' pełni rolę znaku kończącego odczyt, a nie znaku do wypisania. Niepoprawna jest również interpretacja, że kod zwróci domenę 'host.pl'. Indeks $i zaczyna się od zera, czyli od pierwszego znaku napisu, a nie od pozycji po '@'. Program nie ma żadnej instrukcji, która przeskakuje za separator i zaczyna wypisywanie od domeny. Typowy błąd myślowy polega tu na skojarzeniu adresu e-mail z częścią po znaku '@', ale algorytm idzie od lewej do prawej i kończy pracę przed domeną. Warto zapamiętać, że w PHP dostęp do znaków przez $n[$i] działa jak indeksowanie tekstu, a operator && wymaga spełnienia obu warunków naraz. To jest fundament przy analizie podobnych pętli przetwarzających napisy znak po znaku.