r04-02.doc

(3464 KB) Pobierz
Oto przykłady stylów nagłówków:

Rozdział 4.
PHP a obsługa informacji

 

W niniejszym rozdziale omówimy następujące tematy:

·         Podstawy użycia łańcuchów znakowych w PHP.

·         Łączenie łańcuchów i użycie zmiennych w łańcuchach.

·         Najważniejsze i najbardziej użyteczne funkcje powiązane z łańcuchami znakowymi.

·         Tworzenie prostej, lecz efektywnej aplikacji podświetlania tekstu.

 

Prędzej czy później, pisząc własne skrypty, stwierdzimy, że potrzebna jest nam możliwość analizowania i manipulowania łańcuchami znakowymi. Temat łańcuchów przewinął się już kilkakrotnie w poprzednich rozdziałach, ale w rozdziale bieżącym zajmiemy się nimi dogłębnie! Omówimy sposoby konwertowania łańcuchów do określonego formatu, a także funkcje manipulujące nimi, dostępne w PHP.

Może zaskoczyć nas fakt, że na temat łańcuchów można powiedzieć znacznie więcej, niż się wydaje. Opanowaliśmy już podstawy — wiemy, że łańcuchów znakowych można użyć w skryptach i przechowywać w nich informacje tekstowe — w poprzednich rozdziałach widzieliśmy również przykłady zastosowania łańcuchów w praktyce. Rozbudowując swoją znajomość łańcuchów, zobaczymy ponadto, że można je stosować także w ActionScript i choć ich implementacja w tym języku jest zupełnie inna, niż w PHP, pozwoli nam to zrozumieć zasady leżące u podstaw wykorzystania łańcuchów i poznać typy operacji, jakie możemy przeprowadzać z ich udziałem.

Skoro posiedliśmy już podstawowe wiadomości dotyczące łańcuchów, przyjrzyjmy się funkcjom, które pozwalają nimi manipulować. PHP oferuje wiele takich funkcji — niektóre z nich są tak proste, że trudno znaleźć dla nich zastosowanie, inne zaś są tak użyteczne, że życie bez nich byłoby nie do wytrzymania! No, może nie tak, ale prawdą jest, że nasz żywot, jako projektantów witryn sieci Web, byłby o wiele trudniejszy.

No dobrze, dość już gadania — przejdźmy do rzeczy!

 

Podstawy

Łańcuch, mówiąc najprościej, to ciąg znaków, stanowiący dane tekstowe... PHP nie stawia żadnych praktycznych ograniczeń co do długości łańcuchów, co pozwala umieszczać w łańcuchach dowolne ilości informacji. Jednak właściciel serwera może nie być zachwycony, gdy zużyjemy całą pamięć RAM, decydując się na przetestowanie tej teorii.

PHP, jako łańcuch, interpretuje każdy wpis ujęty w parę cudzysłowów lub apostrofów.

 

"To jest łańcuch"

'To także!'

 

Nie trzeba chyba wspominać, że znaki te muszą być dokładnie sparowane, gdyż w przeciwnym razie PHP odrzuci łańcuch! Jest to błąd powszechnie popełniany przez początkujących programistów PHP, a zdarza się od czasu do czasu każdemu.

 

Łańcuchy ujmowane w apostrofy są nieco wydajniejsze pod względem operatywności, ponieważ PHP nie musi przetwarzać mnóstwa znaków specjalnych ani też rozwijać zawartych w nich zmiennych. A zatem, apostrofów należy używać wszędzie tam, gdzie to tylko możliwe. Jeśli jednak zależy nam na potraktowaniu łańcucha jako wartości zmiennej lub na użyciu sekwencji unikowej (o czym za chwilę), wtedy trzeba użyć cudzysłowów!

 

W normalnych okolicznościach, gdy PHP napotyka znak stanowiący parę ze znakiem rozpoczynającym łańcuch, przyjmuje, że jest to koniec łańcucha, a wszystko, co znajdzie dalej, przetwarza jak zwykły kod PHP. Jeśli zechcemy umieścić takie znaki wewnątrz łańcucha, wówczas pojawia się problem. Na szczęście jednak, istnieje sposób na jego obejście.

 

Znaki unikowe

Dwa przedstawione poniżej łańcuchy stanowią ilustrację problemów, jakie możemy napotkać, umieszczając znaki cudzysłowu lub apostrofy w łańcuchach.

 

$string1 = "Why won't "this" work?";

 

$string2 = 'Why won't this work?';

 

W pierwszym przypadku, umieszczenie apostrofu w słowie won't nie powoduje żadnych problemów, gdyż jako ograniczniki łańcucha użyte zostały cudzysłowy. Kłopot polega na ujęciu w cudzysłowy wyrazu this. Kiedy PHP napotka pierwszy cudzysłów po rozpoczęciu łańcucha, uzna, że doszedł do jego końca. W efekcie, słowo this stanie się zlepkiem znaków, których znaczenia PHP nie rozumie.

W drugim łańcuchu, w odróżnieniu od pierwszego, pojawia się problem wynikający z użycia apostrofu w wyrazie won't. Podobnie w tym przypadku, wszystkie znaki znajdujące się za tym apostrofem zostaną staną się niezrozumiałe, powodując wygenerowanie błędu, o ile łańcuch ten umieścilibyśmy wewnątrz skryptu.

Aby móc użyć cudzysłowów i apostrofów, a także innych znaków specjalnych, jako części łańcucha, należy każdy z nich poprzedzić znakiem ukośnika (\) — znak taki określamy jako unikowy. Spójrzmy na kolejne dwa przykładowe łańcuchy, by zobaczyć praktyczne zastosowanie tej techniki.

 

$string1 = "This one \"will\" work!";

 

$string2 = 'So will \'this\' one!';

 

Poprzez dopełnienie ukośnikiem każdego ze sprawiających kłopoty znaków, utworzyliśmy parę poprawnych, wolnych od problemów, łańcuchów.

Rysunek 116.1.

Łączenie łańcuchów

W Rozdziale 2. spotkaliśmy się już z operatorem konkatenacji łańcuchów, ale warto powrócić do tego zagadnienia w obecnie dyskutowanym kontekście. Konkatenacja (dołączenie) jednego lub więcej łańcuchów jest możliwa dzięki operatorowi konkatenacji — zwykłej kropki (.).

 

$firstName = "Steve";

$lastName = "Webster";

 

$fullName = $firstName . ' ' . $lastName

echo $fullName;   // Prints "Steve Webster"

 

W powyższym kodzie pobierane są wartości zmiennych $firstName oraz $lastName, następnie konkatenowane wraz ze spacją rozdzielającą (pomiędzy znakami ' '), po czym wartość wynikowa zostaje przechowana w zmiennej $fullName. Wartość tejże zmiennej, na końcu kodu jest równa "Steve Webster", a tego typu operacje są dość często przeprowadzane na danych użytkownika.

 

Użycie zmiennych w łańcuchach

PHP zezwala na umieszczanie wartości zmiennych wewnątrz łańcuchów ujętych w cudzysłowy. Oznacza to, że w tak prostych operacjach, jak opisana powyżej, nie trzeba stosować operatora konkatenacji.

Na przykład, poniższe dwie linie kodu dadzą taką samą wartość zmiennej $fullName...

 

$firstName = "Steve";

$lastName = "Webster";

 

$fullName = $firstName . ' ' . $lastName;

$fullName = "$firstName $lastName";

 

echo $fullName;   // Wyświetla "Steve Webster"

Rysunek 117.1.

Mówiąc najprościej, po napotkaniu znaku $ w łańcuchu zamkniętym w cudzysłowach, PHP formuje z dalszych znaków nazwę zmiennej. Aby jasno określić ostateczną nazwę zmiennej w łańcuchu, należy ująć ją w całości, wraz z symbolem $, w klamry.

 

<?

$drink = "ED Cola";

 

echo "I think $drink's great" . "<br>\n";

echo "I need to get some chilled $drinks from the shop" . "<br>\n";

echo "I have many {$drink}s every day" . "<br>\n";

?>

 

Pierwsza instrukcja echo da oczekiwany wynik, gdyż znak apostrofu nie może być częścią poprawnej nazwy zmiennej.

Rysunek 118.1.

Druga instrukcja echo nie przyniesie pozytywnego wyniku, ponieważ PHP potraktuje literę s na końcu nazwy zmiennej $drink jako część tejże nazwy. Ponieważ zmienna $drinks nie została zdefiniowana, na ekranie pojawi się napis:

 

I need to get some chilled from the shop

 

Problem ten ulega rozwiązaniu w trzecim wywołaniu instrukcji echo, poprzez ujęcie nazwy zmiennej w nawiasy klamrowe.

Rysunek 118.2.

Wpis $drinks nie został rozpoznany jako nazwa zmiennej i w związku z tym jest ignorowany.

 

Interpreter PHP traktuje cudzysłowy i apostrofy w odmienny sposób. Główna różnica polega na tym, że łańcuchy w cudzysłowach są interpretowane, natomiast te, które ujmujemy w apostrofy, są traktowane niemal dosłownie.

Na przykład, wspominając o technice znaków unikowych, nie mówiliśmy o tym, że dzięki niej możemy umieszczać znaki specjalne w łańcuchach, poprzez użycie innych znaków. Rozwiązanie to pozwala wstawiać znaki, których nie mogą być reprezentowane wizualnie (znaki niedrukowalne), takie jak powrót karetki czy tabulacja. Spójrzmy na poniższą tabelkę, która wymienia kilka z możliwości.

 

Sekwencja

Znaczenie

\n

Przejście do nowego wiersza (LF)

\r

Powrót karetki (CR)

\t

Tabulacja pozioma

\\

Znak ukośnika

\$

Znak dolara

 

Zwróćmy uwagę, że ponieważ ukośnik wsteczny i symbol dolara mają specjalne znaczenie w łańcuchu, aby uzyskać należyty efekt, należy poprzedzić je znakiem unikowym, nawet jeśli w pliku źródłowym mogą one być reprezentowane wizualnie.

 

Jednakże powyższe sekwencje unikowe są interpretowane w ten sposób jedynie wówczas, gdy łańcuch jest ujęty w cudzysłowy. Wynika to stąd, że łańcuchy zamykane apostrofami nie są przetwarzane pod kątem tego typu informacji. Jedynymi wyjątkami od tej reguły są apostrofy unikowe, o których wspominaliśmy wcześniej, oraz ukośniki.

Spójrzmy na poniższy przykład, dzięki czemu wszystko powinno stać się jasne...

 

echo "Line1\nLine2\nLine3";

 

echo 'Line1\nLine2\nLine3';

 

Pierwsza instrukcja daje oczekiwany wynik:

 

Line1

Line2

Line3

 

Zwróćmy uwagę na fakt, o którym wzmiankowaliśmy w Rozdziale 2., że przejście do kolejnych wierszy nie ujawnia się w przeglądarce (ale działa po przekazaniu do Flasha). W związku z tym, jeśli przetestujemy powyższy kod w przeglądarce, zamiast łamania wierszy, zobaczymy jedynie spacje rozdzielające kolejne wyrazy!

 

Ponieważ \n w łańcuchu zamkniętym w apostrofy nie ma żadnego znaczenia, wynik drugiej instrukcji będzie dokładnym odwzorowaniem wpisanego kodu:

 

Line1\nLine2\nLine3

 

Rysunek 120.1.

Morał z tej historyjki jest taki, że do określonych zadań należy stosować odpowiednie znaki!

 

Funkcje związane z łańcuchami

 

W chwili pisania niniejszej książki, język PHP oferuje 72 funkcje odnoszące się do łańcuchów i nie jest możliwe, abyśmy omówili je wszystkie — rozdział stałby się przez to niesamowicie nudny i można by go używać w szpitalu jako tani środek znieczulający. Skoncentrujemy się więc jedynie na najbardziej użytecznych funkcjach, z których korzystać będziemy najczęściej.

 

Ci, którzy chcieliby poznać takie dziwolągi jak obliczanie podobieństwa dwóch łańcuchów metodą Levenshteina, pełny wykaz funkcji działających na łańcuchach znajdą na witrynie pod adresem www.php.net lub w dokumentacji elektronicznej dostarczanej wraz z PHP.

 

print() i echo()

Funkcje print oraz echo korzystają z dokładnie tych samych argumentów i wykonują takie same operacje.

 

print(string)

echo(string)

 

Pobierają one łańcuch string i odsyłają wynik do klienta (czyli do przeglądarki sieciowej). Zapis tych funkcji może mieć następującą formę:

 

print('This is output to the client');

echo("Welcome back $firstName");

 

Ponieważ łańcuch przekazany funkcji print nie wymaga przetwarzania w zakresie znaków specjalnych ani zmiennych, został ujęty parą apostrofów. Podobnie, z uwagi na wplecenie zmiennej $firstName w łańcuch przekazany funkcji echo, ujęliśmy go w cudzysłowy.

Interesującym i wartym wskazania faktem jest natomiast to, że ani print ani echo nie są funkcjami w ścisłym tego słowa znaczeniu, a jedynie konstrukcjami językowymi. Oznacza to, że można ich użyć z pominięciem nawiasów.

 

print "Welcome back $firstName";

echo 'This is output to the client';

 

Jak wspominaliśmy, omawiając konwencje nazewnictwa, należy przyjąć jeden styl kodowania i stosować go konsekwentnie we wszystkich skryptach. Zaoszczędzimy sobie tym sposobem wiele wysiłku, a skrypty będą czytelniejsze.

 

printf() i sprintf()

Funkcje printf i sprintf pozwalają nam tworzyć łańcuchy formatowane zgodnie z zestawem instrukcji. Różnica w ich działaniu polega na tym, że printf przekazuje łańcuch wynikowy klientowi, zwracając true lub false, w zależności od rezultatu operacji. Funkcja sprintf z kolei zwraca łańcuch wynikowy, nie przekazując go klientowi, dzięki czemu można go przechować w zmiennej lub użyć w wyrażeniu.

 

printf(format string [, args...]);

 

sprintf(format string [, args...]);

 

Za pomocą format string przekazujemy funkcji instrukcje formatowania listy argumentów (args) w łańcuchu wynikowym. Będzie ona, ogólnie rzecz biorąc, miksturą standardowych znaków, umieszczonych w łańcuchu wynikowym, w takiej formie, w jakiej zostały wpisane, wraz z czymś, co określa się często jako specyfikacja konwersji, która służy do formatowania argumentów.

Specyfikacja konwersji rozpoczyna się od znaku "%", po którym następuje pięć specyfikatorów. Oto one, wyliczając od lewej do prawej:

 

·         Opcjonalny specyfikator dopełniania, wskazujący znak, który zostanie użyty do dopełnienia łańcucha w celu osiągnięcia przez niego zadanej długości. Może nim być znak spacji lub 0 (zero). Domyślnym znakiem dopełniającym jest spacja. Znak alternatywny można określić wpisując go wraz z poprzedzającym apostrofem.

·         Opcjonalny specyfikator wyrównania, który decyduje o tym, czy wynikowy łańcuch znaków ma zostać wyrównany do lewej czy prawej strony. Domyślnym ustawieniem jest wyrównanie do prawej; wpisanie znaku "-" powoduje wyrównanie łańcucha do lewej.

·         Opcjonalny specyfikator szerokości — podaje minimalną liczbę znaków w łańcuchu po konwersji.

·         Opcjonalny specyfikator dokładności wyznacza liczbę miejsc dziesiętnych, wyświetlanych w liczbach zmiennoprzecinkowych. Opcja ta nie działa w przypadku innych typów danych niż liczby double. (Inną funkcją użyteczną w formatowaniu liczb jest number_format).

·         Specyfikator typu informuje o sposobie, w jaki powinny być traktowane dane zawarte w argumencie. Poniżej możemy zapoznać się z listą najpowszechniej stosowanych specyfikatorów:

 

%              znak procenta. Nie wymaga żadnego argumentu.

d              argument traktowany jest jako liczba całkowita i prezentowany w postaci oznaczonej liczby dziesiętnej.

u              argument jest traktowany jako liczba całkowita i prezentowany w formie nieoznaczonej liczby dziesiętnej.

f              argument jest traktowany jako liczba double i prezentowany w postaci liczby zmiennoprzecinkowej.

s              argument jest traktowany i prezentowany jako łańcuch znakowy.

 

Typowe wyrażenie, bez użycia printf, może mieć jedną z poniższych form:

 

$month = 1;

$day = 7;

$year = 2042;

 

echo "$month/$day/$year";

 

Powyższy kod da w wyniku datę, reprezentowaną przez zmienne, w formacie m/d/rrrr:

 

1/7/2042

 

Rysunek 122.1.

Jednakże, datę można wyświetlić również w formacie mm/dd/rrrr i tu jest miejsce do popisu dla funkcji printf. Jeśli wiersz echo z poprzedniego kodu zastosowalibyśmy dla następującego wywołania funkcji printf, otrzymalibyśmy żądany wynik.

 

printf("%02d/%02d/%d", $month, $day, $year);

...

Zgłoś jeśli naruszono regulamin