Po prostu PHP. Techniki zaawansowane
-
Upload
wydawnictwo-helion -
Category
Technology
-
view
909 -
download
4
description
Transcript of Po prostu PHP. Techniki zaawansowane
Wydawnictwo Helion
ul. Chopina 6
44-100 Gliwice
tel. (32)230-98-63
e-mail: [email protected]
PRZYK£ADOWY ROZDZIA£PRZYK£ADOWY ROZDZIA£
IDZ DOIDZ DO
ZAMÓW DRUKOWANY KATALOGZAMÓW DRUKOWANY KATALOG
KATALOG KSI¥¯EKKATALOG KSI¥¯EK
TWÓJ KOSZYKTWÓJ KOSZYK
CENNIK I INFORMACJECENNIK I INFORMACJE
ZAMÓW INFORMACJEO NOWO�CIACH
ZAMÓW INFORMACJEO NOWO�CIACH
ZAMÓW CENNIKZAMÓW CENNIK
CZYTELNIACZYTELNIA
FRAGMENTY KSI¥¯EK ONLINEFRAGMENTY KSI¥¯EK ONLINE
SPIS TRE�CISPIS TRE�CI
DODAJ DO KOSZYKADODAJ DO KOSZYKA
KATALOG ONLINEKATALOG ONLINE
Po prostu PHP.
Techniki zaawansowane Autor: Larry Ullman
T³umaczenie: Rados³aw Meryk
ISBN: 83-7197-775-1
Tytu³ orygina³u: PHP Advanced For The World Wide Web.
Visual QuickPro Guide
Format: B5, stron: 492
Jêzyk programowania PHP stanowi dla wielu osób przepustkê w �wiat pisania aplikacji
dzia³aj¹cych po stronie serwera WWW. £atwo�æ z jak¹ przychodzi nauczenie siê tego
jêzyka, sprawi³a, ¿e u¿ywaj¹ go setki tysiêcy amatorów i profesjonalistów na ca³ym
�wiecie.
Po pewnym czasie wiedza wyniesiona z podrêczników opisuj¹cych podstawy PHP
jêzyka przestaje wystarczaæ. Niniejsza ksi¹¿ka pomo¿e Ci w wykonaniu kolejnego
kroku: kroku w kierunku pisania zaawansowanych aplikacji. Dziêki niej wzbogacisz
swoj¹ wiedzê i staniesz siê prawdziwym ekspertem programowania w PHP,
poszukiwanym na rynku pracy.
• Poznasz tajniki programowania obiektowego.
• Nauczysz siê korzystaæ z baz danych.
• Dowiesz siê, w jaki sposób zabezpieczaæ stworzone przez siebie aplikacje.
• Napiszesz w³asny sklep internetowy, korzystaj¹c z sesji i bazy SQL.
• Poznasz sposoby uruchamiania programów PHP w oderwaniu od serwera WWW.
• Nauczysz siê generowaæ nie tylko strony WWW, ale tak¿e grafikê i pliki PDF.
• Dowiesz siê, jak i po co u¿ywaæ jêzyka XML.
• Skorzystasz z wielu rozszerzeñ jêzyka, które u³atwiaj¹ rozwi¹zywanie z³o¿onych
problemów.
Pomo¿e Ci w tym prosty jêzyk w jakim napisana jest ksi¹¿ka oraz liczne przyk³ady
kodu, a tak¿e osoba autora, do�wiadczonego programisty i wyk³adowcy PHP na
Uniwersytecie Kalifornijskim w Berkeley.
Spis treści
5
Spis tre
ści
WSTĘP 9
Rozdział 1. Zaawansowane programowanie w PHP 19
Struktura i dokumentowanie kodu ............................................................ 20
Tablice ...................................................................................................... 28
Stałe .......................................................................................................... 37
Funkcje rekurencyjne i zmienne statyczne ............................................... 42
Funkcje a odwołania ................................................................................. 52
Rozdział 2. Programowanie obiektowe 59
Definiowanie klas ..................................................................................... 61
Tworzenie obiektu .................................................................................... 64
Tworzenie konstruktorów ......................................................................... 70
Dziedziczenie............................................................................................ 76
Użycie metod klas bez ich egzemplarzy ................................................... 82
Szeregowanie obiektów ............................................................................ 84
Usuwanie obiektów................................................................................... 93
Rozdział 3. Bazy danych 97
Projekt bazy danych i normalizacja .......................................................... 99
Tworzenie bazy danych .......................................................................... 108
Generowanie wyników zapytań .............................................................. 113
Rozdział 4. Bezpieczeństwo 139
Sprawdzanie poprawności danych w formularzach................................ 141
Sprawdzanie danych w formularzu za pomocą skryptów JavaScript ..... 155
Mcrypt..................................................................................................... 164
Uwierzytelnianie HTTP .......................................................................... 175
Bezpieczeństwo serwera WWW............................................................. 181
Rozdział 5. Projektowanie aplikacji WWW 185
Projekt bazy danych................................................................................ 186
Struktura ośrodka .................................................................................... 190
PHP a szablony obiektowe...................................................................... 202
Spis treści
Spis treści
6
Spis treści
Obsługa sesji ........................................................................................... 224
Wykorzystanie sesji bez znaczników cookie .......................................... 233
Uruchamianie diagnostyczne .................................................................. 243
Rejestrowanie i zgłaszanie błędów ......................................................... 244
Rozdział 6. E-commerce 247
Tworzenie bazy danych .......................................................................... 249
Administracja.......................................................................................... 255
Wyświetlanie towarów online................................................................. 271
Implementacja koszyka na zakupy ......................................................... 279
Rozdział 7. PHP w sieci 289
Wykrywanie przeglądarki ....................................................................... 290
Dostęp do innych ośrodków WWW za pomocą PHP............................. 298
Wykorzystanie fsockopen() .................................................................... 303
Rozdział 8. PHP a serwer 309
Uruchamianie skryptów za pomocą usługi cron ..................................... 310
Kompresja plików za pomocą PHP ........................................................ 317
Wykorzystanie modułu COM w PHP..................................................... 322
Rozdział 9. XML i PHP 331
Czym jest XML?..................................................................................... 332
Składnia języka XML ............................................................................. 334
Definicje typu dokumentów.................................................................... 337
Analiza dokumentów XML za pomocą PHP oraz Expat........................ 344
Obsługa błędów w XML......................................................................... 351
Rozdział 10. Generowanie grafiki 355
Tworzenie prostej grafiki ........................................................................ 357
Zastosowanie czcionek TrueType........................................................... 368
Tworzenie wykresów na podstawie danych z bazy danych.................... 376
Zapisywanie i modyfikowanie istniejących grafik ................................. 387
Rozdział 11. Tworzenie plików PDF 395
Tworzenie prostego dokumentu PDF ..................................................... 397
Wprowadzanie tekstu w dokumentach PDF ........................................... 403
Rysowanie figur ...................................................................................... 416
Wykorzystanie ilustracji graficznych...................................................... 424
Tworzenie wielostronicowych dokumentów PDF.................................. 431
Spis treści
7
Spis tre
ści
Rozdział 12. Rozszerzenia PHP 439
PEAR ...................................................................................................... 440
Zend ........................................................................................................ 447
PHP-GTK................................................................................................ 451
Kod źródłowy PHP ................................................................................. 464
Dodatek A Instalacja 465
Instalacja PHP wraz z serwerem Apache w systemie Linux .................. 466
Instalacja PHP z serwerem Xitami w systemie Windows ...................... 472
Dodatek B Bazy danych 475
Aplikacje systemów zarządzania bazami danych ................................... 476
SQL......................................................................................................... 477
Informacje dotyczące bazy danych MySQL........................................... 480
Inne zasoby ............................................................................................. 482
Dodatek C Zasoby ogólne 483
Ośrodki WWW poświęcone PHP ........................................................... 484
Dodatkowe biblioteki.............................................................................. 486
Bezpieczeństwo....................................................................................... 488
Inne zasoby ............................................................................................. 489
Skorowidz 493
Zaawansowane programowanie w PHP
19
Zaawansowane programowanie w PHPNa najprostszym poziomie dobre programowanie wyraża się tym, czy
aplikacja lub skrypt działa zgodnie z zamiarem. Początkujący programiści
pozostaną na tym poziomie i nie ma w takim podejściu nic złego.
Jednakże zaawansowany programista będzie próbował pójść nieco
dalej. Będzie dążył do zapewnienia lepszej wydajności, niezawodności,
bezpieczeństwa i przenośności. Ta książka nauczy nas, w jaki sposób
rozwinąć umiejętności zaawansowanego programisty PHP.
Ten rozdział opisuje niektóre nowe funkcje i właściwości języka PHP
w wersji 4., techniki, jakie będą stosowane w tej książce, oraz kilka
wskazówek i sztuczek rzemiosła. Chociaż zapewne już wiemy, w jaki
sposób korzystać z tablic, to prawdopodobnie jeszcze nie znamy
konstrukcji ������� lub starszej, ale wciąż bardzo użytecznej funkcji
�������� �. Prawdopodobnie mieliśmy już okazję zapisać własną
funkcję, ale być może nie do końca wiemy, w jaki sposób wykorzystywać
rekurencję oraz zmienne statyczne. W rozdziale tym opiszemy te
elementy, a także inne podstawowe informacje, jak: dokumentowanie
kodu, tworzenie jego struktury, stałe oraz powiązania. Wyjaśnimy też
różnice pomiędzy wykorzystaniem funkcji ����� � a funkcji ���� �,a także w jaki sposób tworzyć aliasy zmiennych — technikę, która
jest nowa dla języka PHP w wersji 4. Ostatecznie w procesie pisania
przykładowych skryptów dowiemy się, że można tworzyć dynamiczne
aplikacje WWW, stosując bazę danych w prostym pliku tekstowym.
W rozdziale tym utworzymy kilka skryptów, służących do utworzenia
i zarządzania ośrodkiem totalizatora sportowego online, gdzie użytkownicy
odgadują zwycięskie zespoły. W każdym tygodniu oraz w całym
sezonie obliczany jest współczynnik poprawnych typów dla każdego
z użytkowników. Wymaga to wykonania niewielu czynności
administracyjnych. Wybrałem ten przykład nie ze względu na to, że
odpowiada tematowi, ale również dlatego, że sięga on czasów moich
początków w PHP. Nauczyłem się tego języka (po przejściu z języka
Perl) przy okazji tworzenia podobnej aplikacji. Oczywiście wtedy
zakończyłem pracę, kiedy tylko skrypt zaczął działać. Nie muszę
dodawać, że skrypty zaprezentowane w tym rozdziale są bardziej
wydajne, niezawodne, bezpieczne oraz przenośne niż te skrypty,
które opracowałem wtedy.
Zaawansowaneprogramowanie w PHP
Zaawanso
wane programowanie w
PHP
Rozdział 1.
20
Strukturai dokumentowanie kodu
Właściwa struktura kodu oraz jego
dokumentowanie, mimo że nie ma wpływu
na działanie aplikacji, stanowi podstawę
zaawansowanego programowania w PHP.
Właściwa struktura oraz dokumentowanie
jest elementem, który należy zastosować
dla wygody własnej oraz naszych klientów
i współpracowników, a także dla programisty,
który w przyszłości będzie być może zmuszony
poprawiać nasz kod.
Kiedy piszę o strukturze kodu, mam na myśli
sposób fizycznej organizacji kodu PHP w samym
dokumencie (W rozdziale 5., „Projektowanie
aplikacji WWW” omówię zagadnienie szersze
— strukturę witryny). Porównajmy skrypty 1.1
oraz 1.2. Obydwa są poprawnymi dokumentami
PHP, ale który z nich wolelibyśmy przeglądać
i poprawiać?
Podstawy budowania struktury kodu odnoszą
się do sposobu stosowania wcięć w kodzie,
pozostawiania pustych wierszy, używania
nawiasów zwykłych i klamrowych itp.
Ogólne zasady są następujące:
� należy stosować wcięcia bloków kodu
(np. wyników instrukcji warunkowych
lub zawartość funkcji) o szerokości jednej
tabulacji lub czterech spacji (w zasadzie
powinno się stosować spacje, a nie tabulatory,
ale programiści stosują wygodniejsze
tabulacje);
� określone fragmenty kodu należy oddzielać
pustym wierszem, aby wyróżnić je wizualnie;
� należy wprowadzać spacje pomiędzy
słowami, argumentami funkcji, operatorami
itp. (generalnie, choć nie zawsze, w języku
PHP liczba spacji nie ma znaczenia);
� funkcje należy umieszczać na początku
dokumentu.
Struktura i dokumentowanie kodu
Skrypt 1.1. Ten skrypt będzie działać prawidłowo,ale znacznie trudniej go poprawiać i zrozumieć niżskrypt 1.2
�������������� ��������������������������������������� !" "# ������$������ %&��'''�'��#�(��)�$����)���*� ���������$�����$+�����*� ���� �� !" "# ���, ,�-������� ���*�� !.�� %&��'''�'��#�(��///�*� ���-0������1�,-2����� " �1-�# ��"3� #��%"45��!5"�� " �1-+�������1�,-6�����7#,8-9�����:%�%�;�!<�"% =��=���%�%/����,1>" 1�?���@�A'BC�����>D < "# �'�" 1=,� ��?AE@�A5@�A>%B�F�����! � "<�A>�C�$���">�?�A>�B�F�����>%D !�?A>%@���"1�!3�� ��%�G �BC�0���A>��.��)��C�2���H�+���>%D !�?A>%@��AEG �BC�6���H�9���A>�.�I$����%"<5!=I�������I=�" 1�!=� * IC���/���">�?A>%�.�J>#%1 �?A>@��'�BB�F$��������8='��5�?A'@�I'�" 1=,� �I@�A>%BC$����><�#!1�?A>%BC$$���1<�#�IK�%"!� #�3'8<"L3<M'��7�-��7�-IC$����H�1�!1�F$0���1<�#��N"1��#O ��# '#�38P�%�"5D�A>������N��1O8�D%1' "P�!"L@�O1�3�"1 �����'�� #QP��������7�-��7�-�C$2���H$+���>D < "# ��1�,=%"<5!�?A,%@�A,B�F$6���(�#7���A%C$9���">�?A> �.��1�,,"��?A,%BB�F$/���">�?!D7! �?A> @��@�+B�..��%"<5!=�B�F�����A%> �.�1*%�#,1�?�=�@�A> BC�����">�??A%> R�S�..��B�� ,�?A%> R$S��.�������" 1�!�BB�F���$���AD �.�A%> R$SC�����A >�.�A,���A> C�0���AD%�.�>"�1�?A >BC�2���A%RAD S�.�AD%C�+���H�6���H�9 �1�,=%"<5!�?A,%@�A,BC�/���H0����H0����A%�.�����8?BC0$���A,�.�I$����IC
Zaawansowane programowanie w PHP
21
Po utworzeniu struktury naszego kodu
powinniśmy zapewnić, aby był on dobrze
udokumentowany. Dokumentowanie kodu jest
programowym odpowiednikiem umieszczania
notatek na żółtych, samoprzylepnych
karteczkach. Można zaryzykować stwierdzenie,
że dokumentowania pracy nigdy za dużo.
Należy opisać działanie funkcji, zmiennych,
fragmentów kodu oraz całych stron. W skrypcie
1.3 pokazałem, jak wyglądałby skrypt 1.2,
gdyby zawierał komentarze. Oto kilka rad
dotyczących dokumentowania kodu:
� zapisujmy przeznaczenie zmiennych, chyba
że ich przeznaczenie nie jest oczywiste
nawet dla początkujących programistów;
� opisujmy zastosowanie funkcji;
� wyjaśniajmy, jaki jest cel działania
fragmentów kodu;
� wymieniajmy pliki, z którymi program się
komunikuje, których wymaga itp.;
� oznaczajmy zamykające nawiasy klamrowe
dla złożonych funkcji oraz struktur sterujących
(instrukcji warunkowych, pętli itp.).
Struktura i d
okumentowanie kodu
Skrypt 1.1. ciąg dalszy
0����A,%�.�#%1 ,"��?A,BC00����1�,=%"<5!�?A,%@�A,BC02���<�#!1,"��?A,%BC0+06���'�"�1�?�"! �?A5@�AEB�.�1�<��?A%BB�F09���A'!�.��C0/���A�!�.��C2����'�"�1�?�"! �?A5$@�AE$B�.�1�<��?AEBB�F2����AE$�.�!D7! ��?AE$@��@�?! ��1 ?AE$B����BBC2$���">�??AE$�..�A'RA5$SB�� ,�?A5$��.��BB�F2����A'!TTC20���H�1�!1">�?A5$��.���B�F22���A�!TTC2+���H26���H29���A�RA5S�.�����8�?I'!I�.-�A'!@�I�!I�.-�A�!BC2/���H+����5!#� �?A�BC+����>D < "# �'�" 1=�1!D� !�?AE@�A5@�A>%B�F+$���! � "<�A>�$C+����">�?�A>�$B�F+0���>%D !�?A>%@���O8 5#' "5G '!G �!G �BC+2���A>�$�.��)��C++���H+6���A,�.�"�%�#,1�?�G �@�AEBC+9���>%D !�?A>%@��A5G A,G �BC+/6����A>$�.�I$�����1!D� !=I�������I=� * IC6����">�?A>%$�.�J>#%1 �?A>$@��'�BB�F6$�������8='��5�?A�@�I'�" 1=�1!D� !I@�A>%$BC��6����><�#!1�?A>%$BC����K��5 "L<"1�%�"5D�60���1<�#�IK�%"!� #�'8 "5"��7�-��7�-IC62���H�1�!1�F6+���1<�#��N"1��#O ��D '#�38P�%�"5D�����3� 8(#, "#'8�"�'8 "5��"@�A>$��7�-��7�-�C66���H69���:-6/�����7#,8-9������� ��-
Rozdział 1.
22
Struktura i dokumentowanie kodu
Skrypt 1.2. Wstawienie pustych wierszy i tabulatorówznacznie zwiększa czytelność skryptu
�������������� ��������������������������������������� !" "# ������$������ %&��'''�'��#�(��)�$���������)���*� ����$�����$+�����*� ��������� �� !" "# ���, ,�-������� ���*�� !.�� %&��'''�'��#�(��///�*� ���-0������1�,-2�������� " �1-��# ��"3� #��%"45��!5"��� " �1-+�������1�,-6�����7#,8-9�����:%�%/�����,1>" 1�?����U�@�A'115BC���$���>D < "# �'�" 1=,� ��?AE��D1@�A518@�A>%B�F���0������! � "<�A>"�! =�" 1C�2�+������">�?�A>"�! =�" 1B�F�6���������>%D !�?A>%@���"1�!3�� ��%��G �BC�9���������A>"�! =�" 1�.��)��C�/������H$�$�������>%D !�?A>%@��AE��D1G �BC$$���H$�$0���A>"�1�.�I$����%"<5!=I������U�������I=�" 1�!=� * IC��$2$+���">�?A>%�.�J>#%1 �?A>"�1@��'�BB�F$6$9����������8='��5�?A'" 1�!@�I'�" 1=,� �I@��������A>%BC$/������><�#!1�?A>%BC����������1<�#�IK�%"!� #�3'8<"L3<M'����������7�-��7�-IC�$�����H�1�!1�F�0������1<�#��N"1��#O ��# '#�38P�%�"5D�A>���������N��1O8�D%1' "P�!"L@�O1�3�"1 ������������'�� #QP����������7�-��7�-�C�2���H�+�6���>D < "# ��1�,=%"<5!�?A,%@�A,"�1< #�8B�F�9�/������(�#7���A%"<5!C0�0�������">�?A>"�1= ��1�.��1�,,"��?A,%BB�F0$0����������">�?!D7! �?A>"�1= ��1@��@�+B�..������������%"<5!=�B�F
Skrypt 1.2. ciąg dalszy
0002������������A%��!1=>"�1= ��1�.�1*%�#,1��������������?�=�@�A>"�1= ��1BC0+06������������">�??A%��!1=>"�1= ��1R�S�..������������������UB�� ,�?A%��!1=>"�1= ��1R$S��.����������������" 1�!�BB�F��090/���������������AD!1� ��1�.�����������������A%��!1=>"�1= ��1R$SC2����������������A �1=>"�1�.�A,"�1< #�8�������������������A>"�1= ��1C2����������������AD!1�!=%"<5!�.�>"�1�����������������?A �1=>"�1BC2$���������������A%"<5!RAD!1� ��1S�.�����������������AD!1�!=%"<5!C2�������������H20���������H222+����������1�,=%"<5!�?A,%@�A,"�1< #�8BC26������H29���H2/+����A%"<5!�.�����8?BC+�+$���A,"�1< #�8�.�I$����IC+����A,%�.�#%1 ,"��?A,"�1< #�8BC+0����1�,=%"<5!�?A,%@�A,"�1< #�8BC+2���<�#!1,"��?A,%BC+++6+9���'�"�1�?�"! �?A518@�AE��D1B�.�1�<������?A%"<5!BB�F+/6�������A'" !�.��C6�������A�#!!1!�.��C6$6�������'�"�1�?�"! �?A518$@�AE��D1$B�.�1�<���������?AE��D1BB�F6062���������AE��D1$�.�!D7! ��?AE��D1$@��@�����������?! ��1 ?AE��D1$B����BBC6+66���������">�??AE��D1$�..�A'" 1�!RA518$SB������������ ,�?A518$��.��BB�F69������������A'" !TTC6/���������H�1�!1">�?A518$��.���B�F9� A�#!!1!TTC9����������H9$������H9�90������A�1!D� !RA518S�.�����8�?I'" !I�.-��������A'" !@�I�#!!1!I�.-�A�#!!1!BC92���H
Zaawansowane programowanie w PHP
23
Struktura i d
okumentowanie kodu
Skrypt 1.2. ciąg dalszy
9+96���5!#� �?A�1!D� !BC999//����>D < "# �'�" 1=�1!D� !�?AE��D1@�A518@�����A>%B�F/�/$������! � "<�A>"�! =�" 1$C/�/0������">�?�A>"�! =�" 1$B�F/2���������>%D !�?A>%@���O8 5#' "5G �8%8�����������%#%��' 1G �8%8�74L, 1G �BC/+���������A>"�! =�" 1$�.��)��C/6������H/9//������A,� ��.�"�%�#,1�?�G �@�AE��D1BC��������>%D !�?A>%@��A518G A,� �G �BC�����$�����A>"�1$�.�I$�����1!D� !=I������U�������I=� * IC��0��2��">�?A>%$�.�J>#%1 �?A>"�1$@��'�BB�F��+��6���������8='��5�?A�1!D� !@��������I'�" 1=�1!D� !I@�A>%$BC����9�����><�#!1�?A>%$BC����K��5 "L<"1�%�"5D���/�����1<�#�IK�%"!� #�'8 "5"��7�-��7�-IC��������H�1�!1�F��$��������1<�#��N"1��#O ��# '#�38P�%�"5D��������3� 8(#, "#'8�"�'8 "5��"@��������A>"�1$��7�-��7�-�C��0��H��2��:-��+����7#,8-��6����� ��-
Skrypt 1.3. Ta wersja skryptu 1.2 została właściwieudokumentowana, ale oczywiście jest miejscena dodanie dodatkowych notatek
������:%�%�;�!<�"% =��=���%�%$�������VVVVVVVVVVVVVVVVVVVVVVVVVVVVV��������W"1<"#'8�!8! 1�� # ��"3� #�������%"45��!5"1(#02��������%��<#'�4&�����8��������� +6�������K�%"!� #��&�W"1�%"1X�$���9�������#%��'"# #&��0�!"1�% "��$���/��������U# �< &�%�%J���" !"(� !�<#����$������W �# ��%�#<1!!='" 1�!�%�%�#7!4D(DY1�����! �# L�%"<5='" 1�!�%�%�%�(1�������5�1Q���# ��!5D 1<3 #QP� 8%M'�����%#!3<31(M� 8<��(��<38�"�3�%"!DY1� 1�����" >#���<Y1�'�%�"5D� 15! #'8�����0������VVVVVVVVVVVVVVVVVVVVVVVVVVVVV�2���:-�+������������ ��������������������������������������� !" "# �������6����� %&��'''�'��#�(��)�$����)���*� ���������$�����$+�����*� ���� �� !" "# ���, ,�-�9����� ���*�� !.�� %&��'''�'��#�(��///�*� ���-�/�����1�,-$�������� " �1-�# ��"3� #��%"45��!5"�� " �1-$�������1�,-$$����7#,8-$�����:%�%$0$2�������! �'"1 "1�! �41Y�'115�$+���,1>" 1�?����U�@�A'115BC$6$9����V������������������������������V�$/����V�K�%"!�3'8<"L3<M'�'�%�"5D�����V�������V������������������������������V����$���>D < "# �'�" 1=,� ��?AE��D1@�A518@�A>%B�F��������ZD 5<Y��'�" 1=,� ��3�%"!DY1� 8%8�����'�%�"5D����0������! � "<�A>"�! =�" 1C�2�+������">�?�A>"�! =�" 1B�F����K�%"!� "1��������%"1�'!31(#�'"1�!3��� ��%8@���1� 8�5#����������3��6���������>%D !�?A>%@���"1�!3�� ��%�G �BC�9���������A>"�! =�" 1�.��)��C�/������H0�
Rozdział 1.
24
Struktura i dokumentowanie kodu
Skrypt 1.3. ciąg dalszy
0�������>%D !�?A>%@��AE��D1G �BC�����#,� "1��������3 �5D��1 D� @��78�5�O,8�3�%"!�3 ���34��������!"L�'�#!#7 8��'"1�!3D�0$���H0�00���A>"�1�.�I$����%"<5!=I������U�������I=�" 1�!=� * IC�����!5�3� "1� �3'8�����%�"5D�'�>#���<"1�I%"<5!=�=�" 1�!=� * I�020+���">�?A>%�.�J>#%1 �?A>"�1@��'�BB�F���������31<38 � "1�%�"5D�,#� �7�"<8�0609����������8='��5�?A'" 1�!@�I'�" 1=,� �I@��������A>%BC�����8!4� "1�<�41Y� �7�"<8��������,#�>D 5<Y"�'�" 1=,� ��0/������><�#!1�?A>%BC����K��5 "L<"1�%�"5D�2�2�������1<�#�IK�%"!� #�3'8<"L3<M'��7�-��7�-IC2$2����H�1�!1�F�����8Q'"1 �1 "1�74L,D�'�%�38%�,5D@�����(,878�# '��<"1�%�"5D�784#� "1�#O�"'1�20������1<�#��N"1��#O ��# '#�38P�%�"5D�A>"�1����������#!3L�D%1' "P�!"L@�O1�3�"1 ��'115�����������'�� #QP��7�-��7�-�C22���H2+2629����V������������������������������V�2/����V�#7�� "1� 8%M'�(��<38��������V�+�����V������������������������������V�+�+$���>D < "# ��1�,=%"<5!�?A,%@�A,"�1< #�8B�F��������38 #QP� L�'85# DY1�>D 5<Y���1�,=%"<5!�+�+0������(�#7���A%"<5!C+2++������">�?A>"�1= ��1�.��1�,,"��?A,%BB�F�����������W%��',31 "1�5�O,1(#�%�"5D�'�5� ��#(D�+6+9���������">�?!D7! �?A>"�1= ��1@��@�+B�..������������%"<5!=�B�F����U# 8 D�<Y�@�����������'�%�38%�,5D�#, ��13"1 "��%�"5D�����������3� 8%��"�+/6�������������A%��!1=>"�1= ��1�.�1*%�#,1��������������?�=�@�A>"�1= ��1BC������������������315!3 �4<1 "1� �3'8�%�"5D�������������� ��#,%#'"1, "�>#��� �6�6$������������">�??A%��!1=>"�1= ��1R�S�..�����������������UB�� ,�?A%��!1=>"�1= ��1R$S���������������.���" 1�!�BB�F����[1O1�"� #�������������� "1�Y1! �%�"5�3�,� 8�"��������������#�3'8<"L3<�<�@��� D�1�� 8(#, "���������������Y1! �'4�Q<"'8���
Skrypt 1.3. ciąg dalszy
6�60���������������AD!1� ��1�.�����������������A%��!1=>"�1= ��1R$SC62���������������A �1=>"�1�.�A,"�1< #�8�������������������A>"�1= ��1C6+���������������AD!1�!=%"<5!�.�>"�1�����������������?A �1=>"�1BC66���������������A%"<5!RAD!1� ��1S�.�����������������AD!1�!=%"<5!C69������������H6/���������H9�9� �1�,=%"<5!�?A,%@�A,"�1< #�8BC���
U#�1Y ��" 1��<Y��>D 5<Y"�9$������H9����H9092���A%"<5!�.�����8?BC����K�" "<Y#'� "1�����(4M' 1Y�3�"1 1Y�9+96���A,"�1< #�8�.�I$����IC99���A,%�.�#%1 ,"��?A,"�1< #�8BC9/����1�,=%"<5!�?A,%@�A,"�1< #�8BC/����<�#!1,"��?A,%BC/�/$/�����V����������������������������������V�/0����V��7�"<31 "1� 8(#, "#'8<��'8 "5M'��V�/2����V����������������������������������V�/+/6���'�"�1�?�"! �?A518@�AE��D1B�.�1�<������?A%"<5!BB�F����L ���,���'8 "5M'�����'�(4M' 1Y� �7�"<8�/9//������A'" !�.��C�����! �'"1 "1� ��'�� #QP����������,���5�O,1Y� �7�"<8���������A�#!!1!�.��C�����! �'"1 "1� ��'�� #QP����������,���5�O,1Y� �7�"<8������$�����'�"�1�?�"! �?A518$@�AE��D1$B�.�1�<���������?AE��D1BB�F����L ���,���5�O,1Y�������� �7�"<8�DO8 5#' "5�������0��������AE��D1$�.�!D7! ��?AE��D1$@��@�����������?! ��1 ?AE��D1$B����BBC���������������!D "L<"1�3 �5D��1 D� ���2��+��������">�??AE��D1$�..�A'" 1�!RA518$SB������������ ,�?A518$��.��BB�F����[1O1�"� 8%�����������DO8 5#' "5��Y1! �'4�Q<"'8@�����������%�383 �Y1�8��D�%D 5 @���1� "1������������"<38�8�'"1�!3�� ������6�����������A'" !TTC��9��������H�1�!1">�?A518$��.���B�F��/�����������A�#!!1!TTC
Zaawansowane programowanie w PHP
25
Struktura i d
okumentowanie kodu
Skrypt 1.3. ciąg dalszy
�����������H��������H��$��������A�1!D� !RA518S�.�����8�?I'" !I�.-��������A'" !@�I�#!!1!I�.-�A�#!!1!BC�����������K�%"!� "1�'8 "5M'�5�O,1(#��������3�DO8 5#' "5M'�'� �7�"<8���0��H��2��+��5!#� �?A�1!D� !BC�����%#�3\,5#'� "1����� �7�"<8���>�71 8<3 "1���6��9��/���V���������������������������������V��$����V�K�%"!� "1� 8(#, "#'8<��'8 "5M'��V��$����V���������������������������������V��$$�$���>D < "# �'�" 1=�1!D� !�?AE��D1@�A518@�����A>%B�F����K�%"!DY1�'8 "5"�,#�%�"5D��$0�$2�����! � "<�A>"�! =�" 1$C�$+�$6�����">�?�A>"�! =�" 1$B�F����K�%"!� "1��������%"1�'!31(#�'"1�!3��� ��%8@���1� 8�5#����������3��$9��������>%D !�?A>%@��]��<3G %#%��' 1G����������� 74L, 1G �BC�����#,� "1�3 �5D������������1 D� � �5@��78�5�O,8�3�%"!�����������3 ���34�!"L�'�#!#7 8��'"1�!3D��$/��������A>"�! =�" 1$�.��)��C��������H�����$�����A,� ��.�"�%�#,1�?�G �@�AE��D1BC��������>%D !�?A>%@��A518G A,� �G �BC������������#,� "1�3 �5D��1 D� � �5@��78��������5�O,8�3�%"!�3 ���34�!"L�'�#!#7 8���������'"1�!3D���0��H��2��+��A>"�1$�.�I$�����1!D� !=I������U�������I=� * IC�����!5�3� "1� �3'8�%�"5D�����'�>#���<"1�I�1!D� !=�=� * I���6��9��">�?A>%$�.�J>#%1 �?A>"�1$@��'�BB�F��������� '��<"1�%�"5D�,#�3�%"!D���/�0����������8='��5�?A�1!D� !@��������I'�" 1=�1!D� !I@�A>%$BC�����8!4� "1��������3�'�� #Q<"�<�41Y� �7�"<8�,#�>D 5<Y"��������'�" 1=�1!D� !��0������><�#!1�?A>%$BC����K��5 "L<"1�%�"5D��0$�����1<�#�I�8 "5"�3�%"!� #��7�-��7�-IC�0�
Skrypt 1.3. ciąg dalszy
�00��H�1�!1�F�����8Q'"1 �1 "1�5#�D "5� D�����#�74L,3"1@�Y1O1�"�# '��<"1�%�"5D����� "1�%#'"#,4#�!"L��02�0+�����1<�#��N"1��#O ��# '#�38P�%�"5D��������3� 8(#, "#'8�"�'8 "5��"@��������A>"�1$��7�-��7�-�C�06��H�09��:-�0/����7#,8-�2������ ��-
Rozdział 1.
26
Poruszyliśmy już sporo zagadnień, dotyczącychdobrej struktury kodu oraz właściwego jegodokumentowania. Zwięzły dokument poświęconytemu tematowi — Standard kodowania w PHP(PHP Coding Standard) można znaleźć podadresem www.DMCinsights.com/phpadv/coding_standard.php (rysunki 1.1 oraz 1.2).
W dokumencie tym opisano formalnereguły zapisywania kodu w PHP wraz z ichuzasadnieniem. W tej książce będę wskazywałmiejsca, gdzie przestrzegam konwencji, i te,gdzie je łamię. Należy jednak pamiętać o trzechsprawach.
Po pierwsze, chciałbym podkreślić, że bezwzględu na to, czy będziemy przestrzegaćstandardu kodowania PHP, czy moichprzyzwyczajeń, najważniejsze jest zachowaniespójności. Niespójność nie tylko jest na bakierz każdym standardem, ale prowadzi do błędówi z pewnością spowoduje konieczność spędzeniadodatkowych godzin w czasie prób uruchamiania.Poza tym, jeżeli pracujemy w zespole, musimyopracować plan, którego powinni przestrzegaćwszyscy członkowie zespołu. Jeżeliprogramujemy dla klienta, powinniśmypozostawić przejrzystą, spójną dokumentację,tak aby klient lub inny programista mógłz łatwością zrozumieć naszą pracę.
Po drugie, struktura kodu i jego dokumentowaniejest elementem, który powinniśmy stosowaćod momentu rozpoczęcia kodowaniai kontynuować w czasie pracy. Próby tworzeniakomentarzy po zapisaniu kodu nigdy nie będątak skuteczne, a często w ogóle nie będą podjęte.To, co wydaje się oczywiste w trakcie tworzenia,stanie się niejasne trzy miesiące później. Jeżelijeszcze tego nie doświadczyliśmy, to z pewnościązdarzy się to nam pewnego dnia.
Po trzecie, ze względu na ograniczenia formatuksiążkowego, skrypty opracowane w tej książceod tego momentu nie będą tak dobrze ułożone,ani udokumentowane, jak to być powinno.Istnieje przecież limit wykorzystania cennejprzestrzeni książkowej na zapiski typu��������������������������������
Osobiście zawsze stosuję się do trzechwymienionych niżej konwencji(będę to robił także w tej książce):
Rysunek 1.1. „PHP Coding Standard”
(Standard kodowania w PHP) jest przewodnikiem
„gramatycznym” programowania w PHP
Rysunek 1.2. „PHP Coding Standard” (Standardkodowania w PHP) doskonale opisuje reguły,uzasadnia je i demonstruje, w jaki sposób
przestrzegać tych zasad podczas tworzenia kodu
Struktura i dokumentowanie kodu
Zaawansowane programowanie w PHP
27
Rysunek 1.3. Program PHPDoc opracowanow celu zautomatyzowania procesu dokumentowaniakodu. Program wykorzystuje wyrażenia regularnedo analizowania kodu i wstawiania opisów
Rysunek 1.4. Jeżeli programujemy z wykorzystaniem
biblioteki PEAR, powinniśmy przestrzegać
specyficznych zasad dokumentowania i tworzeniastruktury kodu (http://pear.php.net/manual/en/
standards.php).
� Nazwy zmiennych powinny być zapisywane
małymi literami ze znakiem podkreślenia
jako separatorem słów. Niektórzy zalecają,
aby nazwy zmiennych globalnych zaczynały
się na literę g, ale ja nie stosuję tej zasady.
� Ponieważ w języku XML skrócone wersje
znaczników (� oraz !) są wykorzystywane,
zatem jeżeli korzystamy z XML-a,
powinniśmy stosować formalne znaczniki
PHP (� ��� !). Przekonamy się o tym
w rozdziale 9., „XML”. Zalecam, aby zawsze
stosować znaczniki formalne, ponieważ jest
to najlepszy sposób zachowania zgodności
pomiędzy serwerami.
� Dla stron, które mają być interpretowane
jako skrypty PHP, zaleca się wykorzystywanie
rozszerzenia .php (dla plików włączanych,
jak np. klas i stron konfiguracyjnych, można
wykorzystywać inne rozszerzenia).
Dopuszczalne rozszerzenia plików są
określone przez konfigurację serwera
WWW, ale w społeczności PHP domyślnie
przyjmuje się rozszerzenie .php (rozszerzenie
stosowane w PHP w wersji 3. — .php3
będzie działać w większości serwerów
z PHP4, ale wydaje się, że ze względu
na istnienie nowych wersji, stosowanie tego
rozszerzenia jest nieuzasadnione).
Wskazówki
� Program PHPDoc jest aplikacją typu
open source, wspomagającą pracę w PHP.
Opracowano go na podstawie popularnego
programu JavaDoc (służącego
do dokumentowania programów w języku
Java). Program ten jest przeznaczony
do wspomagania procesu dokumentowania
kodu. Więcej informacji na temat tego
programu można znaleźć pod adresem
www.PHPDoc.de (rysunek 1.3).
� Jeżeli zamierzamy stworzyć kod, który
będzie wykorzystywany wraz z pakietem
PEAR (zobacz rozdział 12., „Rozszerzanie
PHP”), wówczas powinniśmy przestrzegać
reguł formatowania obowiązujących dla tego
pakietu (rysunek 1.4).
Struktura i d
okumentowanie kodu
Rozdział 1.
28
Tablice
Tablice są specjalnego rodzaju zmiennymi,
które mogą działać jak tabele w arkuszu
kalkulacyjnym. Ze względu na możliwości,
jakie oferują, oraz elastyczność, tablice są
powszechnie wykorzystywane w zaawansowanym
programowaniu w PHP. W tym podrozdziale
opiszemy kilka najbardziej powszechnych
funkcji obsługi tablic.
Nowością w PHP4 jest konstrukcja �������,którą opracowano w celu umożliwienia
łatwiejszego dostępu do wszystkich indeksów
i wartości tablicy. Zakładając, że mamy tablicę
o nazwie "�����, możemy uzyskać dostęp
do każdego jej elementu za pomocą
następującego kodu:
>#�1�<��?A����8��!�A518�.-�AE��D1B�F��������5#,H
Osobiście do obsługi tablic wykorzystuję
konstrukcję ������� i będę to robił także w tej
książce. Jeżeli korzystamy z wcześniejszej
wersji PHP, będziemy musieli przepisać
powyższy kod na następującą postać:
�1!1 ?A����8BC'�"�1�?�"! ?A518@�AE��D1B�.�1�<�?A����8BB�F�������5#,H
Podstawową różnicą pomiędzy konstrukcją
������� oraz ���� jest fakt, że pierwsza z tych
pętli automatycznie ponownie ustawia tablicę
na pozycję początkową, natomiast druga tego
nie robi.
Inną funkcją obsługi tablic, którą często
wykorzystuję, chociaż nie jest to nowość wersji
PHP4, jest �������� �. Funkcja ta pozwala na
podstawienie każdego elementu tablicy
do funkcji zdefiniowanej przez użytkownika.
>D < "# �%�" =��7D�!?AE��D1@�A518B�F����1<�#�AE��D1�����7��-G HA����8.����8?��7�#��# 18�@���1��1 ,!�@���U��#�%D 1��@��U",�^�@��^� 1!"�<�BC����8='��5?A����8@I%�" =��7D�!IBC
Zgodnie ze składnią funkcja �������� �pobiera tablicę jako pierwszy parametr oraz
nazwę funkcji bez żadnych nawiasów ani
argumentów jako drugi parametr. W czasie
wykonywania iteracji funkcji �������� �funkcja będzie otrzymywać kolejne indeksy
tablicy oraz wartości. Powyższy kod spowoduje
wygenerowanie następującego wyniku:
�7�#��# 18��7���-��1��1 ,!��7���-�U��#�%D 1���7���-U",�^��7���-^� 1!"�<��7���-
Ze skryptów znajdujących się w dalszej części
książki dowiemy się, w jaki sposób przekazać
więcej argumentów funkcji wywoływanej
za pomocą �������� �.
Zwróćmy uwagę, że funkcja �������� �działa jedynie z funkcjami definiowanymi
przez użytkownika i nie będzie działać
z wbudowanymi funkcjami PHP. Należy też
pamiętać o konieczności wykonania funkcji
��#�� w PHP4, jeżeli chcemy skorzystać
z tablicy ponownie.
Dla zademonstrowania niektórych
zaawansowanych technik obsługi tablic
zapiszemy pierwszą część aplikacji obsługującej
totalizator sportowy. Jej przeznaczeniem
jest obsługa profesjonalnego futbolu
amerykańskiego, ale można ją z łatwością
przystosować do dowolnej innej dziedziny.
Pierwsze dwa skrypty dynamicznie wygenerują
formularz, gdzie użytkownicy będą mogli
wprowadzać swoje typy. Ponieważ nie wszyscy
mamy dostęp do bazy danych, aplikacja ta
do zapisu informacji będzie wykorzystywać
jednorodny plik tekstowy.
Tablice
Zaawansowane programowanie w PHP
29
Aby skorzystać z tablic:
1. Utworzymy plik tekstowy w edytorze
tekstów.
2. Zapiszemy wiersz nagłówka (skrypt 1.4):
]#!%#,��31���]#Q<"1
W pliku tekstowym najpierw będzie
wymieniona drużyna gości, a następnie
drużyna gospodarzy. Każdy mecz będzie
zajmował oddzielny wiersz. Wiersz
nagłówkowy służy do wyznaczenia układu
tablicy oraz działa jako obejście niektórych
specyficznych właściwości tablic. Kiedy ten
plik będzie wczytany do tablicy, rozpocznie
się ona — jak zwykle w przypadku tablic
— od indeksu 0. Ponieważ wolę, aby indeksy
tablic były zgodne z numerami gier,
a chciałbym numerować wiersze od 1. do 15.
(lub 14., 16. itp.), dlatego opuszczam jeden
wiersz. Tak więc pierwsza gra jest wymieniona
w drugim wierszu, zatem będzie umieszczona
pod indeksem 1.
3. Wpiszemy kolejne gry:
N1'����1� !����D>>��#N1'�� (�� ,����" <" � "W1� �1���������1E1�� ,���%����8����������!�1 �#" �������]�11 ���8��5�� ,�������U� !�!��" 8���#�" ��������" 1!# �� ,"� �%#�"!��N�[1 !" !7D�(�����[�<5!# E"��1��"<�(#���������� "�#�1W ���#D"!������"��,1�%�"���!�" ( # ����W� ��"1(#^ �� ��������W� �Z�� <"!<#�"��"����������1 1!!11N�]"� !������1 E1�
Gry są wyszczególnione w formacie Drużyna
gości [TAB] Drużyna gospodarzy [RETURN]
(bez spacji). Znaku tabulacji użyjemy w celu
rozróżnienia dwóch elementów każdego
wiersza.
4. Zapiszemy plik jako week1.txt.
Tablice
Skrypt 1.4. Dane dla totalizatora będą zapisywanew plikach tekstowych rozdzielanych tabulatorami
jak plik przedstawiony niżej:
�����]#Q<"1������]#!%#,��31$����N1'����1� !����D>>��#�����N1'�� (�� ,����" <" � "0����W1� �1��������1E1�� ,2�������%����8�����������!+�����1 �#" ������]�11 ���86������5�� ,������U� !�!��" 89�������#�" ��������" 1!# �/����� ,"� �%#�"!���N�[1 !������" !7D�(�������[�<5!# E"��1��������"<�(#��������� "�#�1�$����W ���#D"!�������"��,1�%�"���������!�" ( # ������W� ��"1(#�0����^ �� �������W� �Z�� <"!<#�2�����"��"�������1 1!!11�+����N�]"� !�������1 E1�
Rozdział 1.
30
5. Podobne pliki stworzymy dla pozostałych
tygodni w sezonie, nazywając je na przykład
week2.txt, aż do week17.txt. Jeżeli śledzimy
ten przykład bez zmian, możemy pobrać
wszystkie te pliki z witryny pod adresem
www.DMCinsights.com/phpadv. W plikach
tych nie należy wprowadzać żadnych
komentarzy, ponieważ kolidowałoby to
ze sposobem ich wykorzystania (i tak
będą odczytywane tylko przez PHP).
6. Stworzymy katalog 2001 na naszym serwerze
WWW. Możemy użyć dowolnej innej nazwy,
która będzie określała sezon jako całość.
7. Uprawnienia do katalogu ustawimy jako 777
(odczyt, zapis, wyszukiwanie dla wszystkich).
Ze względów bezpieczeństwa, jeżeli
to możliwe, powinniśmy umieścić ten
katalog poniżej katalogu głównego serwera.
Jeżeli już to zrobimy, powinniśmy upewnić
się, że stosujemy właściwe odwołania
do tego katalogu we wszystkich
przedstawionych poniżej skryptach (tzn.
używając odwołania../2001 zamiast 2001/).
8. Umieścimy wszystkie pliki dla
poszczególnych tygodni w katalogu 2001.
Teraz, kiedy utworzyliśmy dane zawierające
informacje o wszystkich grach sezonu, czas
zapisać skrypt, który przekształci te dane
na format HTML.
9. W edytorze tekstowym stworzymy nowy
dokument HTML (skrypt 1.5):
��������� ����������������������������������� !" "# �������������� %&��'''�'��#�(��)�$����)���*� �����$�����$+�����*� ���� �� !" "# ���, ,�-�� ���*�� !.�� %&��'''�'��#�(��///�*� ���-��1�,-���� " �1-�# ��"3� #��%"45��!5"�� " �1-���1�,-
Tablice
Zaawansowane programowanie w PHP
31
Tablice
Skrypt 1.5. Ten skrypt dynamicznie generuje formularz na podstawie pliku w formacie zwykłego tekstu
�������������� ����������������������������������� !" "# ������$������ %&��'''�'��#�(��)�$����)���*� ����$�����$+�����*� ���� �� !" "# ���, ,�-������� ���*�� !.�� %&��'''�'��#�(��///�*� ���-0������1�,-2������������� " �1-�# ��"3� #��%"45��!5"�� " �1-+�������1�,-6�����7#,8-9�����:%�%�;���51<%"=5!<>#���%�%/����?'115.�@�����?>"�1�.�A$����'115A���?'115���A� * A@�����!5�3� "1�%�"5B� ��%#,! �'"1� B�1�B� 8(#, "�����$���">�C?(��1!�..�D>"�1�C?>"�1EE�F�����=38 � "1�%�"5B�,#� �7�"=8����0��������������#�%�31=38 � "B�%�"5BG�'8H'"1 �1 "1�>#��B���3���2�����������1=�#�A�>#����= "# .�! #�1<%"=5!�%�%���1 �#,.�%#! �-�+���� �7�1�7#�,1�.����'", �.�9�I��=1��!%�=" (.�0��=1��%�,," (.�0����"( .�=1 1��-�6������������ ����"( .�=1 1���J��"( .� #%�-�9�������������������� ,�=#�!%� .����'", �.����I����"( .�=1 1���J��"( .� #%�� #'��%.� #'��%�-����������������������%�#'�,K� �3'L�BM8 5#' "5�&�/��������������������" %B � 8%1.� 1* �� ��1.�B!1� ��1��!"31.�$�����*�1 ( �.�$��-�� ,-$�������������� �-$��������������������A@$$$����>#�1�=��C?(��1!��!�?518�.-�?����8E�F����N�! #!#'� "1� �7�"=8�,#�'8H'"1 �1 "��5�M,1O�(�8�$0$2�������">�C?518��.��E�F�����"1�!3��P#H="1���P#!%#,��31� "1�'8H'"1 ���8�$+$6���������?!1=# ,<����8�.�1*%�#,1�C�Q �G�?����8E@�����315!3 �4=1 "1�5�M,1(#�'"1�!3�� �7�"=8�����������'�#,,3"1� R� �7�"=L�$9���������?�'�8�.�?!1=# ,<����8S�T@����"1�'!38�1�1�1 �#,%#'"�,��31!%#4#'"�(#H="�$/���������?�#�1�.�!B7! ��C?!1=# ,<����8S�TG��G�C! ��1 C?!1=# ,<����8S�TE����EE@����������������B("�1�1�1 �#,%#'"�,��31!%#4#'"�(#!%#,��38G���1��B!"�8�B!B RU�3 �5��1 B� �������������1=�#����������� ����"( .Q�=1 1�Q��J��"( .Q� #%Q�-�$����� ,���"( .Q��1> Q��J��"( .Q� #%Q�� #'��%.Q� #'��%Q�-�" %B � 8%1.Q���,"#Q������� ��1.Q�%"=5!S?518TQ��J��B1.Q�?�'�8Q�-?�'�8�� ,-������� ,���"( .Q�=1 1�Q��J��"( .Q� #%Q�-%�31="'�� ,-�0����� ,���"( .Q��"(� Q��J��"( .Q� #%Q�� #'��%.Q� #'��%Q�-�" %B ������ 8%1.Q���,"#Q�� ��1.Q�%"=5!S?518TQ��J��B1.Q�?�#�1Q�-?�#�1�� ,-�2������ �-Q �@�+�������V�6����V�9�/��������3B%14 "1 "1�>#��B���3��"� �71�"�0�����1=�#����������� ����"( .Q�=1 1�Q��J��"( .Q� #%Q�-0�������� ,�=#�!%� .Q��Q��'", �.Q����IQ����"( .Q�=1 1�Q��J��"( .Q� #%Q�-�" %B �������� 8%1.Q�!B7�" Q�� ��1.Q�!B7�" Q��J��B1.Q��8H�"O�Q�-0$������ �-0������ �7�1-00����" %B � 8%1.Q��",,1 Q�� ��1.Q�'115Q��J��B1.Q�?'115Q�-02�����>#��-Q �@0+06���V�1�!1�F�����8H'"1 �1 "1�5#�B "5� B�#�74L,3"1G�O1M1�"�# '��="1�%�"5B� "1�%#'"#,4#�!"L�09�������1=�#��W"1��#M ��# '#�38U�%�"5B�?>"�1��W��1M8�B%1' "U�!"LG�=38�3�"1 ��'115����B! �'"# R���������'�� #HU��7�-��7�-�@0/���V2����:-2������7#,8-2$������ ��-
Rozdział 1.
32
Instrukcje echo, print oraz cudzysłowy
W PHP istnieje kilka sposobów przesyłania tekstu do przeglądarki. Najbardziej popularnesposoby polegają na wykorzystaniu instrukcji ����� oraz ����. Istnieją tylko pewne subtelneróżnice w sposobie działania tych dwóch instrukcji. W jakich sytuacjach należy stosowaćktórą, jest raczej kwestią indywidualnego wyboru niż czegokolwiek innego.
Jedna z różnic polega na tym, że instrukcja echo jest minimalnie, prawie niezauważalnieszybsza niż instrukcja print. Wynika to stąd, że po pomyślnym wykonaniu instrukcja printzwraca wartość (1 oznacza, że instrukcja zakończyła się pomyślnie), natomiast instrukcjaecho tego nie robi.
Właściwością funkcji echo, której nie znajdziemy w funkcji print, jest możliwość łatwegoumieszczania zmiennych w kodzie HTML. Zazwyczaj (w naszych skryptach) fragmentformularza zapisanego w formacie HTML ma następującą postać:
�" %D � 8%1.� 1* �� ��1.�D!1� ��1��E��D1.��:%�%�1<�#�AD!1� ��1C�:-�
W takim przypadku możemy zastosować dwa skróty. Po pierwsze, zawsze możemypominąć ostatni średnik w skrypcie PHP, chociaż korzystanie z tego nie jest dobrą praktyką.Poza tym, stosując instrukcję echo, możemy skrócić kod, wpisując znak równościpo początkowym znaczniku PHP (ale tylko w przypadku wykorzystywania krótkiej postaciznacznika). Tak więc zapis:
�:%�%�1<�#�AD!1� ��1C�:-
przyjmie postać:
�:.�AD!1� ��1�:-
Ważniejsze od tego, z której funkcji skorzystamy (technicznie to nie są funkcje, a konstrukcjejęzyka), jest odpowiedź na pytanie, czy skorzystamy z apostrofów, czy też z cudzysłowów.
W obu instrukcjach echo oraz print można korzystać zarówno z apostrofów, jak teżz cudzysłowów. Różnica polega na sposobie interpretowania zmiennych oraz na tym,że niektóre znaki należy poprzedzić znakiem odwrotnego ukośnika. Użycie apostrofuspowoduje wyświetlenie zawartości w postaci takiej, jak jest i wymaga poprzedzeniaznakiem odwrotnego ukośnika jedynie samego znaku apostrofu. Tak więc instrukcja:
1<�#�I�����1>.�" ,1*�%�%�-�#�1���-IC
zadziała bez problemu. Odpowiednik tej instrukcji z zastosowaniem cudzysłowów przyjąłbynastępującą postać:
1<�#�������1>.G�" ,1*�%�%G�-�#�1���-�C
Aby w źródle HTML znalazł się znak cudzysłowu (co jest konieczne dla zachowaniapoprawności składni), należy go poprzedzić znakiem odwrotnego ukośnika. Z tego względuwysyłając kod HTML do przeglądarki, stosuję instrukcję echo z apostrofem.
Jednym z problemów podczas wykorzystywania apostrofów jest sposób interpretacjizmiennych i sekwencji specjalnych, które w tym przypadku są traktowane dosłownie,co oznacza, że instrukcje postaci:
A3�"1 �.I'�� #!<IC1<�#�IA3�"1 ��G IC
spowodują wyświetlenie ciągu $zmienna \n, a nie wartości zmiennej, po której następujeznak końca wiersza, co nastąpi w wyniku zastosowania poniższego kodu:
A3�"1 ��.I'�� #!<IC1<�#��A3�"1 ��G �C
Tablice
Zaawansowane programowanie w PHP
33
Instrukcje echo, print oraz cudzysłowy (ciąg dalszy)
Ten sam problem występuje w czasie przypisywania wartości do zmiennej lub przy odwołaniachdo indeksów tablic.
A3�"1 ��.I'�� #!<IC1<�#�A �7�"<�RIA3�"1 �ISC�����, #!"�!"L�,#�1�1�1 D�%#,�" ,15!1���A3�"1 ���1<�#�A �7�"<�R�A3�"1 ��SC�����, #!"�!"L�,#�1�1�1 D�%#,�" ,15!1���'�� #!<��
Biorąc pod uwagę sposób wyświetlania zmiennych, powinienem także wyjaśnić sposóbinterpretowania w PHP tablic wielowymiarowych. Zazwyczaj element tablicywielowymiarowej (tablicy złożonej z tablic) możemy zlokalizować, stosując konstrukcję:
A �3'�= �7�"<8RI �3'�= �7�='1' ISRI" ,15!= �7�='1' IS
Ale próba wyświetlenia tego elementu za pomocą instrukcji
1<�#����� #QP�'8 #!"�A �3'�= �7�"<8RI �3'�= �7�='1' ISRI" ,15!= �7�='1' IS�C
nie zadziała. W takim przypadku mamy dwie możliwości. Po pierwsze, możemy użyćoperatora konkatenacji, aby opuścić cudzysłów. Niestety, w niektórych systemach(np. Mac OS X) taka konstrukcja nie zadziała:
1<�#����� #QP�'8 #!"���A �3'�= �7�"<8RI �3'�= �7�='1' ISRI" ,15!= �7�='1' IS�C
Możemy też wykorzystać nawiasy klamrowe wewnątrz cudzysłowów:
1<�#����� #QP�'8 #!"�FA �3'�= �7�"<8RI �3'�= �7�='1' ISRI" ,15!= �7�='1' ISH�C
Dotyczy to zarówno instrukcji ����, jak też instrukcji �����.
Doskonały przewodnik dotyczący ciągów znaków, cudzysłowów, apostrofów itp. zagadnieńmożna znaleźć pod adresem www.zend.com/zend/tut/using-strings.php.
Tablice
Rozdział 1.
34
10. Rozpoczniemy wpisywanie treści
dokumentu HTML oraz umieścimy
inicjujący znacznik PHP:
�7#,8-�:%�%
11. Wskazujemy plik, który będzie
wykorzystywany:
A>"�1.I$����'115I���A'115��I� * IC
Zakłada się, że do skryptu zostanie
przekazana zmienna "��� o wartości od 1
do 17 (w moim przypadku). Tak więc
wygenerowanie formularza dla każdego
tygodnia wymaga jedynie przekazania
do tego skryptu numeru tego tygodnia.
12. Utworzymy instrukcję warunkową, w której
podejmiemy próbę odczytania określonego
pliku do tablicy:
">?A(��1!.J>"�1�?A>"�1BB�F
Jeżeli skrypt prawidłowo odczyta plik,
wówczas zostanie utworzona tablica "$���#,zawierająca informacje o wszystkich grach
danego tygodnia. Dzięki zastosowaniu
znaku % spowodujemy, że nie będą
wyświetlane komunikaty o błędach
w przypadku, gdy odczytanie pliku
nie powiedzie się (porównajmy rysunek 1.5,
gdzie nie zastosowano znaku %, z rysunkiem1.6, gdzie zastosowano ten znak).
13. Rozpoczniemy formularz HTML.
1<�#�I>#����< "# .�! #�1=%"<5!�%�%���1 �#,.��%#! �-� �7�1�7#�,1�.����'", �.�9�_��<1��!%�<" (.��0��<1��%�,," (.�0����"( .�<1 1��-� ����"( .�<1 1���E��"( .� #%�-� ,�<#�!%� .����'", �.����_����"( .�<1 1���E��"( .� #%�� #'��%.� #'��%�-�%�#'�,`� �3'L�DO8 5#' "5�&��" %D � 8%1.� 1* �� ��1.�D!1� ��1��!"31.�$�����*�1 ( �.�$��-�� ,-��� �-�IC
Rysunek 1.5. Ponieważ nie wprowadziliśmywartości zmiennej $week (zobacz wiersz adresu),to skrypt nie mógł odczytać pliku. Na rysunku 1.6pokazano uzyskany wynik, kiedy zastosowanoznak @ w celu wyłączenia komunikatu o błędziegenerowanego przez PHP
Rysunek 1.6. Zastosowanie znaku @ umożliwia
wyłączenie wyświetlania mylących i brzydkich
technicznych komunikatów o błędach
Tablice
Zaawansowane programowanie w PHP
35
Formularz HTML jest dosyć prosty,
służy do wprowadzania jedynie nazwy
użytkownika oraz typu dla każdej gry.
Później można opracować system
uwierzytelniania, który będzie działać,
zanim użytkownik wykona ten krok
(system ten mógłby następnie
automatycznie wprowadzać lub
zapisywać nazwy użytkowników).
� Uwaga: Zakończenie instrukcji echo
kończącym znakiem apostrofu w osobnym
wierszu może wydawać się dziwne, ale
w rezultacie kod HTML staje się bardziej
czytelny. Dzięki niemu mamy pewność,
że następna instrukcja HTML rozpocznie się
w osobnym wierszu, a nie od kończącego����!�
14. Utworzymy pętlę, przeglądającą tablicę,
wpisując każdą grę do formularza:
>#�1�<��?A(��1!��!�A518�.-�A����8B�F">�?A518��.��B�FA!1<# ,=����8�.�1*%�#,1�?�G �@�A����8BCA�'�8�.�A!1<# ,=����8R�SCA�#�1�.�!D7! ��?A!1<# ,=����8R�S@��@�?! ��1 ?A!1<# ,=����8R�SB����BBC1<�#����������� ����"( .G�<1 1�G��E��"( .G� #%G�-� ,���"( .G��1> G��E��"( .G� #%G�� #'��%.G� #'��%G�-�" %D � 8%1.G���,"#G�� ��1.G�%"<5!RA518SG��E��D1.G�A�'�8G�-A�'�8�� ,-� ,���"( .G�<1 1�G��E��"( .G� #%G�-%�31<"'�� ,-� ,���"( .G��"(� G��E��"( .G� #%G�� #'��%.G� #'��%G�-�" %D � 8%1.G���,"#G�� ��1.G�%"<5!RA518SG��E��D1.G�A�#�1G�-A�#�1�� ,-
�� �-G �CHH
Pierwszy wiersz w tym kodzie stanowi nowa
konstrukcja �������, której użycie stanowi
łatwą i w pewnym sensie szybszą metodę
obsługi tablic.
Drugi wiersz zapewnia, że obsługiwany
element nie jest pierwszym elementem
w pliku. Jak wynika z przykładu pokazanego
wyżej (skrypt 1.4), elementem tablicy pod
indeksem & jest wiersz o wartości '�(���)*+,-�'�#�����.�, którego nie będziemy
wyświetlać.
Jeżeli nie jest to pierwszy element tablicy,
wówczas zostanie on podzielony za pomocą
funkcji �/����� � na poszczególne części(drużynę gości oraz drużynę gospodarzy).
Każda drużyna jest formalnie
przyporządkowana osobnej zmiennej (za
każdym razem obcinany jest znak RETURN
z nazwy drużyny gospodarzy).
Ostatecznie wyświetlany jest wiersz tabeli
złożony z uzyskanych informacji.
15. Uzupełnimy kod formularza HTML
oraz tabeli.
1<�#��� ����"( .G�<1 1�G��E��"( .G� #%G�-� ,�<#�!%� .G��G��'", �.G����_G����"( .G�<1 1�G��E��"( .G� #%G�-�" %D � 8%1.G�!D7�" G�� ��1.G�!D7�" G��E��D1.G��8Q�"Y�G�-�� �-�� �7�1-�" %D � 8%1.G��",,1 G�� ��1.G�'115G��E��D1.G�A'115G�-��>#��-G �C
Należy pamiętać, aby zastosować typ 01���2w celu przechowania numeru tygodnia, aby
był on dostępny w skrypcie store_picks.php,
który obsługuje formularz.
Tablice
Rozdział 1.
36
16. Zakończymy główną instrukcję warunkową
i zamkniemy znaczniki PHP i HTML.
H�1�!1�F1<�#��N"1��#O ��# '#�38P�%�"5D�A>"�1��N��1O8�D%1' "P�!"L@�<38�3�"1 ��'115����D! �'"# \�→'�� #QP��7�-��7�-�CH:-��7#,8-��� ��
Komunikat o błędzie, wygenerowany przez
powyższy kod, jest przeznaczony bardziej
dla programisty niż dla użytkownika
(prawdopodobnie nie będziemy chcieli
wyświetlać nazwy pliku w komunikacie
o błędzie, który może być przeglądany
przez wszystkich). Komunikat ten można
przetworzyć na bardziej przyjazny
dla użytkownika w zależności od sposobu
działania naszej aplikacji.
17. Zapisujemy plik jako make_picks_form.php
i kopiujemy ten plik na nasz serwer, do tego
samego katalogu, gdzie utworzyliśmy
katalog 2001. Ładujemy go w przeglądarce
WWW, dodając do adresu URL ciąg
���34, aby skrypt mógł działać poprawnie
(rysunki 1.7 oraz 1.8). Na razie nie
korzystamy z przycisku Wyślij.
Wskazówki
� W rozdziale 5., „Projektowanie aplikacji
WWW”, zostanie omówione bardziej
szczegółowo użycie symbolu %.
� W rozdziale 4., „Bezpieczeństwo”,
opracujemy system rejestracji
użytkowników oraz uwierzytelniania,
którego będziemy mogli używać wraz z tymi
skryptami oraz z dowolnymi innymi.
Rysunek 1.7. Oto formularz utworzony przez
skrypt make_picks_form, umożliwiający
wytypowanie zwycięzcy we wszystkich 15 grach
Rysunek 1.8. Rozważne wykorzystywanie
instrukcji echo oraz spacji w skryptach PHPpowoduje, że kod źródłowy HTML staje się
bardziej czytelny
Tablice
Zaawansowane programowanie w PHP
37
Stałe
Stałe to specjalny rodzaj zmiennych, któremu— moim skromnym zdaniem — nie poświęca siędostatecznie dużo uwagi. Stałe, jak wskazuje nazwa,zawierają wartość, która nie zmienia się, ani teżnie może się zmieniać w czasie działania skryptu.Ponadto dodatkową zaletą stałych jest fakt,że w danym zakresie są one globalne, co oznacza,że są automatycznie dostępne wewnątrz funkcji.
W nazwach stałych wielkość liter ma znaczenie,podobnie jak w nazwach wszystkich zmiennychw PHP. Zasadą jest zapisywanie nazw stałychtylko wielkimi literami. W czasie nadawanianazw zmiennym należy stosować te same zasady,jak w przypadku zmiennych — litera (z wyjątkiempoczątkowego znaku dolara) lub znak podkreślenia,po którym następują litery, cyfry lub znakipodkreślenia.
Stałą tworzy się za pomocą funkcji ������ �w następujący sposób:
,1>" 1?�N^K�^=W�^a�[&@�'�� #QP�BC
Stałą można zdefiniować tylko jako liczbę(całkowitą lub zmiennoprzecinkową), albo jakociąg znaków. Nie można zdefiniować stałej jakotablicy lub jako obiektu, a po utworzeniu stałej jejwartości nie można aktualizować, tak więcnie można przekształcić stałej łańcuchowejna liczbę całkowitą. Stałą można uważaćza niezmienną zmienną.
W PHP istnieje wiele wbudowanych stałych,włącznie z 50567 (system operacyjny), 5058�97162(np. 4.0.3pl1), *9�� oraz :+�7�. Dwie zmiennewbudowane — :1�� oraz �12�oznaczające bieżącą nazwę pliku oraz numerwiersza — zmieniają się w czasie działaniaskryptu. Stałe te przydają się do uruchamianiadiagnostycznego, o czym przekonamy sięw rozdziale 5., „Projektowanie aplikacji WWW”.
Lubię wykorzystywać stałe tam, gdzie występujązmienne, które nie powinny się zmieniać, lubw przypadku, jeżeli zmienna ma być dostępnaw całym skrypcie. Jako demonstrację zdefiniowaniai wykorzystania stałych zapiszemy skrypt store_picks.php dla naszego totalizatora online. Skryptten będzie obsługiwał dane pochodzące ze stronymake_picks_form.php utworzonej poprzednio.
Stałe
Rozdział 1.
38
Aby wykorzystać stałe:
1. W edytorze tekstowym utworzymy nowy
dokument HTML (skrypt 1.6).
��������� ����������������������������������� !" "# �������� %&��'''�'��#�(��)�$����)���*� �����$�����$+�����*� ���� �� !" "# ���, ,�-�� ���*�� !.�� %&��'''�'��#�(��///�*� ���-��1�,-������ " �1-�# ��"3� #��%"45��!5"�� " �1-���1�,-
2. Rozpoczniemy wpisywanie treści dokumentu
HTML oraz umieścimy inicjujący znacznik
PHP:
�7#,8-�:�%�%
3. Zdefiniujemy stałą ;��<�
,1>" 1?����U�@�A'115BC
Ponieważ na każdej ze stron wykorzystywana
jest wartość zmiennej "���, chcemy
zapewnić, żeby zmienna ta nie zmieniała
wartości w czasie działania skryptu. Z tego
powodu zmienną tę przekształcimy na stałą.
4. Utworzymy funkcję, zapisującą typy
użytkowników.
>D < "# �'�" 1=,� ��?AE��D1@�A518@�A>%B�F���>%D !�?A>%@��AE��D1G �BCH
Funkcja �������� � będzie wykorzystywana
w połączeniu z funkcją �������� � zgodniez tym, co napisano we wcześniejszej części
tego rozdziału. Funkcja �������� �otrzymuje element tablicy, jej indeks oraz
wskaźnik do pliku. Zawartość zapisaną
do pliku będzie stanowić nazwa zespołu
wybrana przez użytkownika zakończona
znakiem RETURN. W celu wygenerowania
znaku RETURN należy wykorzystać
sekwencję =�, ponieważ alternatywna
sekwencja =� powoduje problemy
z odczytem pliku w niektórych systemach
(pierwsza sekwencja generuje znak
RETURN, natomiast druga — znak CR).
Stałe
Skrypt 1.6. Skrypt store_picks.php definiuje zmienną
���� jako stałą, aby zapewnić niezmienność jej
wartości w czasie działania skryptu
�������������� ��������������������������������������� !" "# �����N�$������ %&��'''�'��#�(��)�$����)���*� ���������$�����$+�����*� ���� �� !" "# ���, ,�-������� ���*�� !.�� %&��'''�'��#�(��///�*� ���-0������1�,-2�������� " �1-�# ��"3� #��%"45��!5"�� " �1-+�������1�,-6�����7#,8-9�����:%�%/��������1 �!5�8% �#7!4D(DY1�,� 1�31�!5�8% D�������51=%"<5!=>#���%�%������������! �'"1 "1� D�1�D� 8(#, "��Y�5#�! �41Y���������������� ������������0������ZD 5<Y��'�" 1=,� ��3�%"!DY1� 8%8�����'�%�"5D��2���>D < "# �'�" 1=,� ��?AE��D1@�A518@�A>%B�F�+������>%D !�?A>%@��AE��D1G �BC�����#,� "1��������3 �5D��1 D� @��78�D�"1Q<"P�5�O,8��������1�1�1 �'�#,,3"1� 8��'"1�!3D��6���H�9�������������������������������� ����������������� �!"�������#$#���������!%!�����������������& "!�������������'! (��#$#�$�$����">�?A>%�.�J>#%1 �?A>"�1@��'�BB�F��������� '��<"1�%�"5D�,#�3�%"!D�$$$�������>%D !�?A>%@���"1�!3���� ��%�G �BC������������ '#�31 "1�'"1�!3����� ��%8�$0����������8='��5�?A%"<5!@�I'�" 1=,� �I@��������A>%BC�����8!4� "1�<�41Y� �7�"<8��������,#�>D 5<Y"�'�" 1=,� ��$2������><�#!1�?A>%BC����K��5 "L<"1�%�"5D�$+������1<�#�I�'#Y1� 8%8�3#! �48�3�%"!� 1�IC$6$9���H�1�!1�F�����8Q'"1 �1 "1�5#�D "5� D�����#�74L,3"1@�Y1O1�"�# '��<"1�%�"5D� "1�����%#'"#,4#�!"L�$/��������1<�#��N"1��#O ��# '#�38P�%�"5D����������A>"�1��N��1O8�D%1' "P�!"L@�<38����������3�"1 ��'115����D! �'"# \�'�� #QP������������7�-��7�-�C�����H�����:-�$�����7#,8-�������� ��-
Zaawansowane programowanie w PHP
39
5. Wskazujemy plik, który będzie
wykorzystywany
A>"�1�.�I$����%"<5!=I������U���I=I���AD!1� ��1���I=� * IC
Nazwa pliku składa się z przedrostka ����#,po którym następuje numer tygodnia, znak
podkreślenia, nazwa użytkownika i ponownie
znak podkreślenia. Plik ma rozszerzenie .txt.
Nazwy stałej nie można umieścić
w apostrofach ani w cudzysłowach,
ponieważ w takim przypadku PHP
interpretowałby ją dosłownie jako ;��<,a nie jako wartość, którą stała reprezentuje.
Jeżeli katalog 2001 umieścimy poza
głównym katalogiem dokumentów WWW,
wówczas w celu właściwego odwołania się
do tego katalogu powinniśmy zastosować
odpowiednią składnię.
6. Próbujemy otworzyć plik do zapisu.
">�?A>%�.�J>#%1 �?A>"�1@��'�BB�F
Jeżeli ta instrukcja warunkowa przyjmie
wartość ���#�, wówczas należy sprawdzić,
czy poprawnie ustawiliśmy uprawnienia
do katalogu 2001 — nieprawidłowe ich
ustawienie jest najbardziej prawdopodobną
przyczyną błędu, ponieważ sam plik do tej
pory nie istniał, zatem powinna istnieć
możliwość zapisu do tego pliku. Inną
prawdopodobną przyczyną może być użycie
złego parametru, na przykład � zamiast .
7. Zapisujemy dane do pliku.
>%D !�?A>%@���"1�!3���� ��%�G �BC����8='��5�?A%"<5!@�I'�" 1=,� �I@�A>%BC
Pierwszym wierszem, który zapisujemy
do pliku, jest wiersz — atrapa, a po nim,
wykorzystując połączenie funkcji �������� � ze zdefiniowaną uprzednio funkcją
�������� �, zapisujemy pozostałe dane.
Teoretycznie moglibyśmy zdefiniować
dodatkową funkcję, która przed zapisem
danych sprawdzałaby, czy wytypowano
wszystkich zwycięzców.
Stałe
Rozdział 1.
40
8. Zamykamy plik, a po pomyślnym
jego zamknięciu wysyłamy komunikat.
><�#!1�?A>%BC����K��5 "L<"1�%�"5D�1<�#�I�'#Y1� 8%8�3#! �48�3�%"!� 1�IC
9. Kończymy instrukcję warunkową, PHP
oraz HTML.
H�1�!1�F1<�#��N"1��#O ��# '#�38P�%�"5D�A>"�1��N��1O8�D%1' "P�!"L@�<38�3�"1 ��'115����D! �'"# \�'�� #QP��7�-��7�-�CH:-��7#,8-��� ��-
10. Zapisujemy plik jako store_picks.php
i kopiujemy go na serwer, do tego samego
katalogu, gdzie zapisaliśmy skrypt make_
picks_form.php (skrypt 1.5). Uruchamiamy
ten drugi skrypt w przeglądarce WWW
(rysunek 1.7) tak, aby skrypt store_picks.php
został wykonany (rysunek 1.9).
11. Sprawdzamy w katalogu 2001, czy utworzono
nowy plik (rysunek 1.10). Możemy pobrać
nowo utworzony plik i sprawdzić jego
zawartość (skrypt 1.7).
Rysunek 1.9. Jeżeli skrypt działa prawidłowo,wówczas użytkownik uzyska ten lakonicznykomunikat
Rysunek 1.10. Katalog 2001, który jest bazą danych
plików tekstowych, zawiera wszystkie dane, włącznie
z nowo utworzonym plikiem picks_1_NAZWA_txt
Stałe
Zaawansowane programowanie w PHP
41
Wskazówki
� Aby sprawdzić, czy zdefiniowano stałą
przed jej użyciem, można skorzystać
z funkcji ������� �:
">�?,1>" 1,?N^K�^=W�^��[BB�F���
Należy uważać, aby nie pomylić funkcji
������� � z funkcją ������ �, która służydo ustawiania wartości stałej.
� Aby obejrzeć listę wszystkich zdefiniowanych
stałych, należy skorzystać z funkcji$������������#����# �.
� Chociaż posiadanie katalogu z prawem
zapisu w obrębie katalogu WWW
(uprawnienia ustawione na 777), tak jak
w powyższym przykładzie katalog 2001,
nie jest bezpieczne, to czasami jest to
konieczność. Istnieją obejścia oraz elementy,
na które należy zwracać uwagę w takich
przypadkach. Zostaną one omówione
w rozdziale 4., „Bezpieczeństwo”. Jeżeli
istnieje możliwość umieszczenia katalogu
z prawem zapisu poza katalogiem WWW,
tak będzie lepiej, chociaż niektóre firmy
świadczące usługi hostingu nie dadzą nam
takiego wyboru.
Stałe
Skrypt 1.7. Po wykonaniu skryptu make_picks_form.php oraz store_picks.php zostanie utworzonyponiższy plik, zawierający moje typy dla gierw pierwszym tygodniu
������"1�!3���� ��%�$�����D>>��#�����N1'�� (�� ,0����W1� �12�������%����8+����]�11 ���86����U� !�!��" 89�����" 1!# �/����� ,"� �%#�"!�����" !7D�(��������"<�(#�$����"��,1�%�"������W� ��"1(#�0���W� �Z�� <"!<#�2����"��"�+����1 E1�
Rozdział 1.
42
Funkcje rekurencyjnei zmienne statyczne
Programując, z pewnością będziemy mieli
okazję zdefiniowania i zastosowania własnej
funkcji — jest to doskonałe narzędzie, które
pomaga właściwie zorganizować nasz kod oraz
zaoszczędzić czas. Elementem, z którego być
może jeszcze nie korzystaliśmy, jest rekurencja
wewnątrz funkcji.
Rekurencja to właściwość wywoływania funkcji
w obrębie jej samej.
>D < "# � �3'�=>D 5<Y"�?B�F���Y�5"Q�5#,��� �3'�=>D 5<Y"?BCH
W wyniku zastosowania rekurencji uzyskamy
efekt, gdzie będziemy mogli wykorzystać
funkcję zarówno zgodnie z jej przeznaczeniem,
jak też jako pętlę.
Stosując tę technikę, należy uwzględnić jedną,
ogromnie ważną uwagę. Należy upewnić się,
że funkcja posiada warunek wyjścia. Na przykład
funkcja o kodzie pokazanym poniżej będzie
działać w nieskończoność:
>D < "# ��,,=# 1?A B�F����A TTC�������,,=# 1?A BCH�,,=# 1?�BC
Brak warunku określającego zakończenie
obliczeń funkcji tworzy olbrzymi problem
programistyczny — pętlę nieskończoną.
Porównajmy funkcję pokazaną wyżej
do następującej:
>D < "# �<#D = #=����?A B�F��">?A ��.���B�F����1<�#�A ����7�-��7�-�C��HH<#D = #=���?�BC
Funkcja ta będzie wywoływać samą siebie
dopóty, dopóki zmienna "� nie osiągniewartości większej niż 100. W tym momencie
działanie funkcji zakończy się.
Wykorzystując rekurencję lub dowolny
skrypt, gdzie ta sama funkcja wykonuje się
wiele razy, warto rozważyć zastosowanie
instrukcji #�����. Użycie tej instrukcji
powoduje, że wartości zmienne są pamiętane
pomiędzy poszczególnymi wywołaniami
funkcji bez konieczności użycia zmiennych
globalnych. Funkcję ��>����4&& �,dla zapewnienia identycznego wyniku jej
działania, można przepisać następująco:
>D < "# �<#D = #=���?B�F����! � "<�A C������">�?A �.���B�F���������1<�#�A ����7�-��7�-�C������A TTC������<#D = #=���?BC����HH
Jako kolejny krok na drodze do stworzenia
aplikacji totalizatora piłkarskiego online
zapiszemy skrypt, który wykorzystuje
rekurencję oraz instrukcję #�����. Skrypt tenbędzie umożliwiał administratorowi
wprowadzenie zwycięzców każdego meczu,
a następnie porównanie zwycięzcy z typami
poszczególnych graczy.
Funkcje rekurencyjne i zmienne statyczne
Zaawansowane programowanie w PHP
43
Aby wykorzystać rekurencjęoraz instrukcję static:
1. W edytorze tekstowym otwieramy skrypt
make_picks_form.php (skrypt 1.5).
Napiszemy skrypt nieco inny od tego,
tak aby można było dokonać wyboru
zwycięzców.
2. Modyfikujemy wiersze 15. – 21.
oryginalnego dokumentu tak, aby
formularz był obsługiwany przez inny
skrypt oraz bez możliwości wprowadzania
danych przez użytkowników (skrypt 1.8).
1<�#�I�>#����< "# .�%�#<1!!='" 1�!�%�%���1 �#,.�%#! �-� �7�1�7#�,1�.����'", �.�9�_��<1��!%�<" (.��0��<1��%�,," (.�0����"( .�<1 1��-IC
Chociaż formularz ten będzie bardzo
podobny do formularza w skrypcie
make_picks_form.php, to jednak będzie
on obsługiwany inaczej — przez skrypt
process_winner.php, który zapiszemy
jako następny.
Funkcje
rekurencyjne i zm
ienne sta
tyczn
e
Skrypt 1.8. Skrypt pick_winners.php to tylko nieznaczna modyfikacja jego poprzednika — skryptu
make_picks_form.php
�������������� ����������������������������������� !" "# ������$������ %&��'''�'��#�(��)�$����)���*� ����$�����$+�����*� ���� �� !" "# ���, ,�-������� ���*�� !.�� %&��'''�'��#�(��///�*� ���-0������1�,-2������������� " �1-�# ��"3� #��%"45��!5"�� " �1-+�������1�,-6�����7#,8-9�����:%�%�;���51=%"<5!=>#���%�%/�����A>"�1�.�I$����'115I���A'115���I� * IC�����!5�3� "1�%�"5D� ��%#,! �'"1� D�1�D� 8(#, "�����$���">�?A(��1!�.�>"�1�?A>"�1BB�F�����<38 � "1�%�"5D�,#� �7�"<8����0��������������#�%�31<38 � "D�%�"5D@�'8Q'"1 �1 "1�>#��D���3���)�������������*&��+�& "�!�#�&��� &���������� ���*��"�#*&���&�#,�-���+#!.���.& �� ������#*�/�0�������!���1�2������!����1�2�!��1�����#� ,�3����������������9�/�����������>#�1�<��?A(��1!��!�A518�.-�A����8B�F����K�! #!#'� "1� �7�"<8�,#�'8Q'"1 �1 "��5�O,1Y�(�8�$�$��������������">�?A518��.��B�F�����"1�!3��]#Q<"1���]#!%#,��31� "1�'8Q'"1 ���8�$$$�����������������A!1<# ,=����8�.�1*%�#,1�?�G �@�A����8BC�����315!3 �4<1 "1�5�O,1(#�'"1�!3������������������� �7�"<8�'�#,,3"1� \� �7�"<L�$0����������������A�'�8�.�A!1<# ,=����8R�SC����"1�'!38�1�1�1 �#,%#'"�,��31!%#4#'"�(#Q<"�$2����������������A�#�1�.�!D7! ��?A!1<# ,=����8R�S@��@�?! ��1 ?A!1<# ,=����8R�SB����BBC�����������������������D("�1�1�1 �#,%#'"�,��31!%#4#'"�(#!%#,��38@���1��D!"�8�D!D \P�3 �5��1 D� �$+�3������������������*&���������+# �!��1��4���#� 4�5!��1��4#&�4,�/����������+#��!��1��4���#4�5!��1��4#&�4��&� !��4�&� !�4,+����#�#(���4 !��&4�������������!"��4����� �6���(74�5!����4�!�!(4,�!�!(+�#�,������������+#��!��1��4���#� 4�5!��1��4#&�4,� %����+�#�,8�����������+#��!��1��4 �1*#4�5!��1��4#&�4��&� !��4�&� !�4,+����#�#(���4 !��&4�������������!"��4����� �6���(74�5!����4�*&"�4,�*&"�+�#�,8������+�# ,4��
Rozdział 1.
44
3. Modyfikujemy wiersze 31. – 35. oryginalnego
skryptu tak, aby wygenerowana tablica miała
nazwę "�����#.
1<�#���� ����"( .G�<1 1�G��E��"( .G� #%G�-� ,���"( .G��1> G��E��"( .G� #%G�� #'��%.G�� #'��%G�-�" %D � 8%1.G���,"#G�� ��1.G��'" 1�!RA518SG��E��D1.G�A�'�8G�-A�'�8�� ,-� ,���"( .G�<1 1�G��E��"( .G� #%G��-%�31<"'�� ,-� ,���"( .G��"(� G��E��"( .G� #%G�� #'��%.�G� #'��%G�-�" %D � 8%1.G���,"#G�� ��1.�G�'" 1�!RA518SG��E��D1.G�A�#�1G��-A�#�1�� ,-�� �-G �C
Ten krok nie jest absolutnie konieczny
poza tym, że skrypt process_winners.php,
obsługujący ten formularz, powinien
otrzymać bardziej odpowiednie nazwy
zmiennych ("�����#, a nie "����#).
4. Zapisujemy skrypt jako pick_winners.php.
Zapiszemy teraz skrypt, obsługujący dane
z formularza pick_winners.php.
5. W edytorze tekstowym utworzymy nowy
dokument HTML (skrypt 1.9).
��������� ����������������������������������� !" "# �������� %&��'''�'��#�(��)�$����)���*� �����$�����$+�����*� ���� �� !" "# ���, ,�-�� ���*�� !.�� %&��'''�'��#�(��///�*� ���-��1�,-������ " �1-�# ��"3� #��%"45��!5"�� " �1-���1�,-
Funkcje rekurencyjne i zmienne statyczne
Skrypt 1.8. ciąg dalszy
�$���������H������H�0�2����������3D%14 "1 "1�>#��D���3��"� �71�"��+������1<�#����������� ����"( .G�<1 1�G���������E��"( .G� #%G�-�6����������� ,�<#�!%� .G��G��'", �.G����_G���������������"( .G�<1 1�G��E��"( .G� #%G�-�������������" %D ������������� 8%1.G�!D7�" G�� ��1.G�!D7�" G��������������E��D1.G��8Q�"Y�G�-�9�������� �-�/����� �7�1-0�����" %D � 8%1.G��",,1 G�� ��1.G�'115G������E��D1.G�A'115G�-0������>#��-G �C0$0����H�1�!1�F�����8Q'"1 �1 "1�5#�D "5� D�����#�74L,3"1@�Y1O1�"�# '��<"1�%�"5D����� "1�%#'"#,4#�!"L�00���1<�#��N"1��#O ��# '#�38P�%�"5D�A>"�1������N��1O8�D%1' "P�!"L@�<38�3�"1 ��'115��������D! �'"# \�'�� #QP��7�-��7�-�C02���H0+���:-06�����7#,8-09������ ��-
Zaawansowane programowanie w PHP
45
Funkcje
rekurencyjne i zm
ienne sta
tyczn
e
Skrypt 1.9. W tym dość długim skrypcie wykorzystano zmienne statyczne oraz rekurencję w celu zapisudo plików, odczytywania danych z plików oraz wykonywania obliczeń
��������������� ����������������������������������� !" "# ������$������� %&��'''�'��#�(��)�$����)���*� ����$�����$+�����*� ���� �� !" "# ���, ,�-�������� ���*�� !.�� %&��'''�'��#�(��///�*� ���-0�������1�,-2��������� " �1-�# ��"3� #��%"45��!5"�� " �1-+��������1�,-6������7#,8-9������:%�%/����������! �'"1 "1� D�1�D� 8(#, "��Y�5#�! �41Y�������,1>" 1�?����U�@�A'115BC�$�������V������������������������������V��0�����V�K�%"!�3'8<"L3<M'�'�%�"5D�����V��2�����V������������������������������V��+�6����>D < "# �'�" 1=,� ��?AE��D1@�A518@�A>%B�F����ZD 5<Y��'�" 1=,� ��3�%"!DY1� 8%8�'�%�"5D��9����������#!#������ �#������$�$��������">�?�A>"�! =�" 1B�F����K�%"!� "1�%"1�'!31(#�'"1�!3��� ��%8@���1� 8�5#���3�$$����������>%D !�?A>%@���"1�!3�� ��%�G �BC$�����������A>"�! =�" 1�.��)��C$0�������H$2$+�������>%D !�?A>%@��AE��D1G �BC�����#,� "1�3 �5D��1 D� @��78�5�O,8�3�%"!�3 ���34�!"L���������'�#!#7 8��'"1�!3D�$6����H$9$/����A>"�1�.�I$����%"<5!=I������U���I=�" 1�!=� * IC�����!5�3� "1� �3'8�%�"5D�'�>#���<"1������I%"<5!=�=�" 1�!=� * I���������">�?A>%�.�J>#%1 �?A>"�1@��'�BB�F����� '��<"1�%�"5D�,#�3�%"!D��$�������������8='��5�?A'" 1�!@�I'�" 1=,� �I@�A>%BC�����8!4� "1�<�41Y� �7�"<8�,#�>D 5<Y"���������'�" 1=,� ���0�������><�#!1�?A>%BC����K��5 "L<"1�%�"5D��2�+�������1<�#�IK�%"!� #�3'8<"L3<M'��7�-��7�-IC�6�9����H�1�!1�F�����8Q'"1 �1 "1�74L,D@�'�%�38%�,5D@�(,878�# '��<"1�%�"5D�784#� "1�#O�"'1��/�������1<�#��N"1��#O ��# '#�38P�%�"5D�A>"�1���#!3L�D%1' "P�!"L@�O1�3�"1 ��'115����'�� #QP�����������7�-��7�-�C0�����H0�0$0������V������������������������������V�00�����V�#7�� "1� 8%M'�(��<38��������V�02�����V������������������������������V�
Rozdział 1.
46
1
1 Jeżeli uruchamiamy skrypt w systemie Windows, wówczas należy zapisać ten wiersz jako�AE��D1$�.!D7! ��?AE��D1$@��@�?! ��1 ?AE��D1$B����BB@�ponieważ znak RETURN składa się w systemie Windows
z dwóch znaków (CR+LF) — przyp. tłum.
Funkcje rekurencyjne i zmienne statyczne
Skrypt 1.9. ciąg dalszy
0+06����>D < "# ��1�,=%"<5!�?A,%@�A,"�1< #�8B�F�����38 #QP� L�'85# DY1�>D 5<Y���1�,=%"<5!�090/�������(�#7���A%"<5!C2�2������">�?A>"�1= ��1�.��1�,,"��?A,%BB�F����W%��',31 "1�5�O,1(#�%�"5D�'�5� ��#(D�2$2��������">�?!D7! �?A>"�1= ��1@��@�+B�..��%"<5!=�B�F����U# 8 D�<Y�@�'�%�38%�,5D�#, ��13"1 "����������%�"5D�3� 8%��"�2022���������A%��!1=>"�1= ��1�.�1*%�#,1�?�=�@�A>"�1= ��1BC�����315!3 �4<1 "1� �3'8�%�"5D����������� ��#,%#'"1, "�>#��� �2+26����������">�??A%��!1=>"�1= ��1R�S�..����UB�� ,�?A%��!1=>"�1= ��1R$S��.���" 1�!�BB�F���������������[1O1�"� #� "1�Y1! �%�"5�3�,� 8�"�#�3'8<"L3<�<�@��� D�1�� 8(#, "��Y1! �'4�Q<"'8���292/�������������AD!1� ��1�.�A%��!1=>"�1= ��1R$SC+��������������A �1=>"�1�.�A,"�1< #�8���A>"�1= ��1C+��������������AD!1�!=%"<5!�.�>"�1�?A �1=>"�1BC+$�������������A%"<5!RAD!1� ��1S�.�AD!1�!=%"<5!C+�����������H+0���������H+2--������� �!���������������� ��#& (������ &��9�!��#� !�9!������9��+6�����H+9���H+/6����A%"<5!�.�����8?BC����K�" "<Y#'� "1�(4M' 1Y�3�"1 1Y�6�6$���A,"�1< #�8�.�I$����IC6����A,%�.�#%1 ,"��?A,"�1< #�8BC60����1�,=%"<5!�?A,%@�A,"�1< #�8BC62���<�#!1,"��?A,%BC6+6669����V�����������������������������������V�6/����V��7�"<31 "1� 8(#, "#'8<��'8 "5M'���V�9�����V�����������������������������������V�9�9$���'�"�1�?�"! �?A518@�AE��D1B�.�1�<��?A%"<5!BB�F����L ���,���'8 "5M'�'�(4M' 1Y� �7�"<8�9�90�������A'" !�.��C�����! �'"1 "1� ��'�� #QP���,���5�O,1Y� �7�"<8�92�������A�#!!1!�.��C�����! �'"1 "1� ��'�� #QP���,���5�O,1Y� �7�"<8�9+96�������'�"�1�?�"! �?A518$@�AE��D1$B�.�1�<��?AE��D1BB�F����L ���,���5�O,1Y� �7�"<8�DO8 5#' "5��999/����������AE��D1$�.�!D7! ��?AE��D1$@��@�?! ��1 ?AE��D1$B����BBC�����!D "L<"1�3 �5D��1 D� ��/�/��������">�??AE��D1$�..�A'" 1�!RA518$SB�� ,�?A518$��.��BB�F����[1O1�"� 8%�DO8 5#' "5��Y1! ���������'4�Q<"'8@�%�383 �Y1�8��D�%D 5 @���1� "1��"<38�8�'"1�!3�� ����
Zaawansowane programowanie w PHP
47
Funkcje
rekurencyjne i zm
ienne sta
tyczn
e
Skrypt 1.9. ciąg dalszy
/$����������A'" !TTC/��������H�1�!1">�?A518$��.���B�F/0����������A�#!!1!TTC/2�������H/+����H/6/9����A�1!D� !RA518S�.�����8�?I'" !I�.-�A'" !@�I�#!!1!I�.-�A�#!!1!BC����K�%"!� "1�'8 "5M'������5�O,1(#�3�DO8 5#' "5M'�'� �7�"<8�//����H����������5!#� �?A�1!D� !BC�����%#�3\,5#'� "1� �7�"<8���>�71 8<3 "1���$�����0�����V���������������������������������V���2�����V�K�%"!� "1� 8(#, "#'8<��'8 "5M'��V���+�����V���������������������������������V���6��9����>D < "# �'�" 1=�1!D� !�?AE��D1@�A518@�A>%B�F����K�%"!DY1�'8 "5"�,#�%�"5D���/�����������#!#������ �#������������$�������">�?�A>"�! =�" 1$B�F����K�%"!� "1�%"1�'!31(#�'"1�!3��� ��%8@���1� 8�5#���3��������������>%D !�?A>%@��]��<3G %#%��' 1G 74L, 1G �BC�����#,� "1�3 �5D��1 D� � �5@��78�5�O,8�������������3�%"!�3 ���34�!"L�'�#!#7 8��'"1�!3D���0����������A>"�! =�" 1$�.��)��C��2�������H��+��6�������A,� ��.�"�%�#,1�?�G �@�AE��D1BC��9�������>%D !�?A>%@��A518G A,� �G �BC�����#,� "1�3 �5D��1 D� � �5@��78�5�O,8�3�%"!�������������3 ���34�!"L�'�#!#7 8��'"1�!3D���/����H�$��$�����A>"�1$�.�I$�����1!D� !=I������U���I=� * IC�����!5�3� "1� �3'8�%�"5D�'�����������������������������������������������������>#���<"1�I�1!D� !=�=� * I��$$�$�����">�?A>%$�.�J>#%1 �?A>"�1$@��'�BB�F����� '��<"1�%�"5D�,#�3�%"!D��$0�$2�����������8='��5�?A�1!D� !@�I'�" 1=�1!D� !I@�A>%$BC�����8!4� "1�3�'�� #Q<"�<�41Y� �7�"<8����������,#�>D 5<Y"�'�" 1=�1!D� !��$+�������><�#!1�?A>%$BC����K��5 "L<"1�%�"5D��$6�������1<�#�I�8 "5"�3�%"!� #��7�-��7�-IC�$9�$/����H�1�!1�F�����8Q'"1 �1 "1�5#�D "5� D�#�74L,3"1@�Y1O1�"�# '��<"1�%�"5D� "1�%#'"#,4#�!"L��������������1<�#��N"1��#O ��# '#�38P�%�"5D�3� 8(#, "#'8�"�'8 "5��"@�A>"�1$��7�-��7�-�C��$����H�������:-��0������7#,8-��2������� ��-
Rozdział 1.
48
6. Rozpoczniemy wpisywanie treści dokumentu
HTML oraz umieścimy inicjujący znacznik
PHP:
�7#,8-�:�%�%
7. Zdefiniujemy stałą WEEK
,1>" 1?����U�@�A'115BC
Ponieważ nie chcemy, aby ta wartość ulegała
zmianie oraz ze względu na to, że musi ona
być dostępna dla wielu funkcji, ustawiamy ją
jako stałą.
8. Stworzymy funkcję zapisującą listę
zwycięzców.
>D < "# �'�" 1=,� ��?AE��D1@�A518@�A>%B�F! � "<�A>"�! =�" 1C">�?�A>"�! =�" 1B�F>%D !�?A>%@���"1�!3�� ��%�G �BCA>"�! =�" 1�.��)��CH>%D !�?A>%@��AE��D1G �BCH
Funkcja �������� � zasadniczo zapisujewiersz tekstu do pliku. Ponieważ chcemy,
aby pierwszy wiersz pliku był wierszem
— atrapą, to stworzyliśmy instrukcję
warunkową, która zapisze ten wiersz,
ale tylko wtedy, gdy pierwszy wiersz
nie został jeszcze zapisany (nie chcielibyśmy,
aby wiersz — atrapa był zapisywany
za każdym razem, kiedy wywołujemy tę
funkcję). Ponieważ zmienna "���#�����ustawiona na wartość *9�� po zapisaniupierwszego wiersza jest zadeklarowana jako
statyczna za pomocą instrukcji #�����,zatem jej wartość będzie pamiętana w każdej
iteracji funkcji. Z tego powodu, kiedy funkcja
zostanie wywołana po raz drugi, zmienna
"���#����� będzie pamiętana jako *9��i instrukcja warunkowa nie wykona się.
9. Wybieramy plik do przetwarzania.
A>"�1�.�I$����%"<5!=I������U���I=�" 1�!=� * IC
Lista zwycięskich zespołów dla każdego
tygodnia będzie zapisywana w pliku pick_
1_Winners_.txt (jeżeli jest to tydzień nr 1).
Pliki będą umieszczone w katalogu 2001.
10. Zapiszemy instrukcję warunkową, która
otwiera plik i zapisuje w nim tablicę
zwycięzców.
">�?A>%�.�J>#%1 �?A>"�1@��'�BB�F����8='��5�?A'" 1�!@�I'�" 1=,� �I@�A>%BC><�#!1�?A>%BC����K��5 "L<"1�%�"5D�1<�#�IK�%"!� #�3'8<"L3<M'��7�-��7�-ICH�1�!1�F1<�#��N"1��#O ��# '#�38P�%�"5D�A>"�1���#!3L�D%1' "P�!"L@�O1�3�"1 ��'115���'�� #QP��7�-��7�-�CH
Kod ten jest bardzo podobny do
zapisanego w skrypcie store_picks.php.
11. Utworzymy funkcję, która pobiera
wszystkie istniejące typy użytkowników.
>D < "# ��1�,=%"<5!�?A,%@�A,"�1< #�8B�F(�#7���A%"<5!C">�?A>"�1= ��1�.��1�,,"��?A,%BB�F����W%��',31 "1�5�O,1(#�%�"5D�'�5� ��#(D�">�?!D7! �?A>"�1= ��1@��@�+B�..��%"<5!=�B�F�A%��!1=>"�1= ��1�.�1*%�#,1�?�=�@�A>"�1= ��1BC">�??A%��!1=>"�1= ��1R�S�..����UB�� ,�?A%��!1=>"�1= ��1R$S��.���" 1�!�BBAD!1� ��1�.�A%��!1=>"�1= ��1R$SCA �1=>"�1�.�A,"�1< #�8���A>"�1= ��1CAD!1�!=%"<5!�.�>"�1�?A �1=>"�1BCA%"<5!RAD!1� ��1S�.�AD!1�!=%"<5!CHH�1�,=%"<5!�?A,%@�A,"�1< #�8BCH
Funkcje rekurencyjne i zmienne statyczne
Zaawansowane programowanie w PHP
49
Funkcja ta wykonuje się w pętli (dzięki
przedostatniemu wierszowi powodującemu
rekurencję) dla wszystkich plików
w katalogu, aż do odczytania wszystkich
typów. Wtedy to warunek instrukcji
warunkowej przyjmie wartość ���#�i funkcja nie wywoła samej siebie.
W przypadku, kiedy plik spełnia kryteria
pliku zawierającego typy użytkownika
(tzn. #>�#�� "��������?&?@�3A����#A�,wówczas dane zostaną odczytane
i zapisane do globalnej tablicy "����#z wykorzystaniem nazwy użytkownika
jako indeksu.
12. Utworzymy główną tablicę, rozpoznamy
i otworzymy katalog, a następnie
wywołamy funkcję ��������# ��
A%"<5!�.�����8?BCA,"�1< #�8�.�I$����ICA,%�.�#%1 ,"��?A,"�1< #�8BC�1�,=%"<5!�?A,%@�A,"�1< #�8BC<�#!1,"��?A,%BC
13. Zapiszemy pętlę, w której sprawdzimy
trafność typów poszczególnych graczy.
'�"�1�?�"! �?A518@�AE��D1B�.�1�<��?A%"<5!BB�FA'" !�.��CA�#!!1!�.��C'�"�1�?�"! �?A518$@�AE��D1$B�.�1�<��?AE��D1BB�FAE��D1$�.�!D7! ��?AE��D1$@��@�?! ��1 ?AE��D1$B����BBC">�??AE��D1$�..�A'" 1�!RA518$SB�� ,�?A518$��.��BB�FA'" !TTCH�1�!1">�?A518$��.���B�FA�#!!1!TTCHHA�1!D� !RA518S�.�����8�?I'" !I�.-�A'" !@�I�#!!1!I�.-�A�#!!1!BCH
Mamy tu dwie pętle, pierwsza działa
dla wielowymiarowej tablicy "����#,składającej się z wyników wytypowanych
przez użytkowników w danym tygodniu.
Kolejna pętla działa w tablicy typów każdego
z graczy i sprawdza, czy gracz prawidłowo
wytypował zwycięzcę. Jeżeli tak się stało,
zmienna "��# jest zwiększana o 1, jeżeli
nie — zwiększana jest zmienna "��##�#.Ostatecznie zapisy są wprowadzane
do wielowymiarowej tablicy "��#>��#,zawierającej liczbę trafnych i błędnych
typów poszczególnych graczy.
14. Uporządkujemy alfabetycznie wyniki
według nazwy użytkownika.
5!#� ?A�1!D� !BC
Tablica "��#>��# w naszym przykładzie
składa się teraz z czterech elementów pod
indeksami Brian, Juan, Larry oraz Michael
(moi czterej użytkownicy testowi). Każdy
element wskazuje na inną tablicę, której
indeksy to ��# oraz ��##�#. Funkcja �#��� �posortuje pierwszy zestaw indeksów
— nazwy użytkowników w porządku
alfabetycznym. Sortowanie nie będzie
miało wpływu na pozostałe dane.
15. Utworzymy funkcję, która zapisze wyniki
dla określonego tygodnia.
>D < "# �'�" 1=�1!D� !�?AE��D1@�A518@�A>%B�F! � "<�A>"�! =�" 1$C">�?�A>"�! =�" 1$B�F>%D !�?A>%@��]��<3G %#%��' 1G 74L, 1G �BC�A>"�! =�" 1$�.��)��CHA,� ��.�"�%�#,1�?�G �@�AE��D1BC>%D !�?A>%@��A518G A,� �G �BC�H
Funkcja ta przypomina funkcję �������� �,z tą różnicą, że wykorzystuje inny nagłówek.
Ponownie wykorzystujemy zmienną statyczną,
aby nagłówek był zapisywany tylko raz.
Funkcje
rekurencyjne i zm
ienne sta
tyczn
e
Rozdział 1.
50
16. Wskazujemy plik wyników i tworzymy
instrukcję warunkową, która spowoduje
wysłanie danych do tego pliku.
A>"�1$�.�I$�����1!D� !=I������U���I=� * IC">�?A>%$�.�J>#%1 �?A>"�1$@��'�BB�F����8='��5�?A�1!D� !@�I'�" 1=�1!D� !I@�A>%$BC><�#!1�?A>%$BC1<�#�I�8 "5"�3�%"!� #��7�-��7�-ICH�1�!1�F1<�#��N"1��#O ��# '#�38P�%�"5D�3� 8(#, "#'8�"�'8 "5��"@�A>"�1$��7�-��7�-�CH
Jest to kolejna kopia kodu wywołującego
funkcję �������� �, który wykorzystaliśmy
we wcześniejszej części skryptu. Kiedy
funkcja �������� � wyśle tablicę "�����do funkcji ������#>��# �, wówczas
wszystkie poprawnie i błędnie wytypowane
wyniki zostaną zapisane w pliku o nazwie
results_1_.txt (dla tygodnia numer 1).
Rysunek 1.11. Strona pick_winners.php wyglądapodobnie do strony make_picks_form.php
(rysunek 1.7) z tą różnicą, że nie ma tu możliwości
wprowadzenia nazwy użytkownika
Rysunek 1.12. Jeżeli skrypt process_winners.php
wykona się poprawnie, zobaczymy te dwa komunikaty.
Wynik działania skryptu możemy sprawdzić,
zaglądając do katalogu 2001 (rysunek 1.13)
Funkcje rekurencyjne i zmienne statyczne
Zaawansowane programowanie w PHP
51
Rysunek 1.13. Katalog zawiera teraz plik pick_Winners_txt, który zawiera zwycięskie drużyny,a także plik results_1_.txt, w którym znajdują sięinformacje o trafności typów poszczególnych graczy
17. Kończymy kod PHP oraz HTML
:-��7#,8-��� ��-
18. Zapisujemy plik jako process_winners.php,
kopiujemy go do tego samego katalogu,
co skrypt pick_winners.php (skrypt 1.8),
a następnie uruchamiamy ten drugi skrypt
w przeglądarce WWW (rysunki 1.11
oraz 1.12).
19. Możemy też obejrzeć zawartość katalogu
2001 (rysunek 1.13), a także zawartość pliku
results_1_.txt (skrypt 1.10).
Funkcje
rekurencyjne i zm
ienne sta
tyczn
e
Skrypt 1.10. Skrypt process_winners.php generuje taki
oto plik z wynikami dla każdego tygodnia, dla którego
uruchomimy skrypt pick_winners.php. Plik z wynikami
zawiera nazwy wszystkich użytkowników oraz liczby
trafnych i błędnych typów dla każdego z nich
���]��<3���� %#%��' 1 74L, 1$����"� �� 9������� 6���[D� ��� �����������00������8���� �����������22���"<��1� �����������0
Rozdział 1.
52
Funkcje a odwołania
Domyślnie funkcje otrzymują argumenty
według zasady wywołanie przez wartość.
Oznacza to, że funkcja otrzymuje wartość
zmiennej, a nie samą zmienną. Aby uaktualnić
wartość zmiennej wewnątrz funkcji, należy
zastosować instrukcję $����� albo przekazaćzmienną przez odwołanie.
Oto przykład zwyczajnego działania funkcji:
>D < "# �<�� (1=E��D1?AE��"�7�1B�F���AE��"�7�1TTC���1<�#�AE��"�7�1CHAE��"�7�1�.��C<�� (1=E��D1?AE��"�7�1BC
Instrukcja echo wyświetli wartość B, ale wartość
zmiennej "�������� w dalszym ciągu wynosi 4(pamiętajmy, że zmienna "�������� wewnątrz
funkcji, oprócz wspólnej nazwy, nie jest tym
samym, czym poza nią). Jeżeli byśmy jednak
przekazali zmienną "�������� przez odwołanie,
wówczas wartość zmiennej "�������� pozafunkcją także się zmieni.
Aby przekazać zmienną przez odwołanie, a nie
przez wartość, nazwę zmiennej należy poprzedzić
znakiem C. Możemy to zrobić w wierszu,
w którym wywołujemy funkcję — w takim
przypadku dotyczyć to będzie określonej
zmiennej — lub w definicji funkcji, wówczas
będzie to dotyczyć każdej zmiennej
przekazywanej do funkcji.
>D < "# �<�� (1=E��D1?AE��"�7�1B�F���AE��"�7�1TTC���1<�#�AE��"�7�1CHAE��"�7�1�.��C<�� (1=E��D1?bAE��"�7�1BC
Teraz funkcja wyświetla wartość B. Ten sam
wynik można osiągnąć za pomocą
następującej funkcji:
>D < "# �<�� (1=E��D1?bAE��"�7�1B�F���AE��"�7�1TTC���1<�#�AE��"�7�1CHAE��"�7�1�.��C<�� (1=E��D1?AE��"�7�1BC
Różnica w tym drugim przykładzie polega
na tym, że każda zmienna wysłana do funkcji
����$����>� � automatycznie przekazywana
jest przez adres.
Zaletą wykorzystywania przekazywania
zmiennych przez adres jest fakt, że w takim
przypadku zaoszczędza nam to kłopotów
związanych z zastosowaniem zmiennych
globalnych oraz zwracaniem wartości przez
funkcje. Przekonamy się o tym, kiedy
utworzymy ostatni skrypt w naszej aplikacji
totalizatora online.
Funkcje a odwołania
Zaawansowane programowanie w PHP
53
Aliasy
Nowością w PHP4 jest możliwość przekazywania parametrów przez adres niezależnieod funkcji. Składnia instrukcji służących do wykonywania tego typu czynności jest następująca:
AE��"�7�1�.���"<�(#��D7!�C
AE��"�7�1$.AE��"�7�1�C����3�"1 ��AE��"�7�1$�Y1! �5#%"\�3�"1 1Y�AE��"�7�1�
AE��"�7�1�.b�AE��"�7�1�C����3�"1 ��AE��"�7�1��Y1! �#,'#4� "1��,#�3�"1 1Y�AE��"�7�1�
AE��"�7�1$.�N� "# ����1�(D1��1�,1�!�C����'�� #QP�3�"1 1Y�AE��"�7�1$� #��N� "# ����1�(D1����1�,1�!��'�� #QP�3�"1 1Y�AE��"�7�1�� #�'�,��!38��<"\(D����"<�(#��D7!�
AE��"�7�1��.��@�N� "# ����1�(D1��1�,1�!�C���#7"1�3�"1 1�AE��"�7�1��#��3�AE��"�7�1����Y\���'�� #QP����"<�(#��D7!@�N� "# ����1�(D1��1�,1�!�
Wykorzystując tego typu odwołania, tworzymy alias. W powyższym przykładzie zmienna"��������D jest aliasem zmiennej "��������4 (wiersz, za pomocą którego utworzyliśmyten alias, moglibyśmy także zapisać jako "��������D3C"��������4E). Dowolne zmiany,dotyczące jednej ze zmiennych, będą automatycznie uwzględnione dla drugiej.
Zastosowanie odwołań do zmiennych zamiast kopii może wpłynąć na poprawę wydajnościaplikacji, szczególnie gdy mamy do czynienia z tablicami dużych rozmiarów oraz obiektami.Podczas gdy każda kopia zmiennej zajmuje tyle samo miejsca w pamięci co oryginał, to aliaszajmuje go znacznie mniej.
Dobrą analogią do tej sytuacji jest skrót do dokumentu w naszym komputerze. Powiedzmy,że mamy dokument Venus.txt w folderze Astronomy i stworzyliśmy alias lub skrót do tegodokumentu (na przykład na pulpicie) o nazwie Evening_Star. Zarówno skrót, jak i samdokument odwołują się do tej samej wartości (zawartości otwartego dokumentu) i dowolnezmiany tej zawartości będą uwzględnione niezależnie od tego, czy otworzymy dokumentza pośrednictwem skrótu Evening_Star, czy też za pomocą oryginalnego pliku Venus.txt.Różnica jest jednak taka, że plik Venus.txt ma 40 KB, podczas gdy skrót jedynie 2 KB.
Funkcje
a odwołania
Rozdział 1.
54
Aby wykorzystać odwołania
1. W edytorze tekstowym utworzymy nowy
dokument HTML (skrypt 1.11):
��������� ����������������������������������� !" "# �������� %&��'''�'��#�(��)�$����)���*� �����$�����$+�����*� ���� �� !" "# ���, ,�-�� ���*�� !.�� %&��'''�'��#�(��///�*� ���-� " �1-�# ��"3� #��%"45��!5"�� " �1-���1�,-�7#,8-
2. Rozpoczniemy wpisywanie treści dokumentu
HTML oraz umieścimy inicjujący znacznik
PHP:
�7#,8-�:%�%
3. Zapiszemy funkcję, która będzie sumować
trafne i błędne typy.
>D < "# �,#= �1=�� ��?AE��D1@�A518@�A # ��B�F">�?A518��.��B�FA�" 1�.�1*%�#,1�?�G �@�AE��D1BCAD!1� ��1�.�A�" 1R�SCA # ��R�AD!1� ��1�SR�'" !�S�T.�A�" 1R�SCA # ��R�AD!1� ��1�SR��#!!1!�S�T.�A�" 1R$SCHH
Funkcja ta otrzymuje wartość z tablicy, jej
indeks oraz tablicę "�����. Wartość, która
jest przekazywana w formacie 2+F;+�GH*<6;21<+�)*+,-�*9+:2��)*+,-�,IJ�2�)9�*�92-, zostanie zdekomponowana pod
warunkiem, że nie jest to pierwszy element
tablicy ("���K3&) — wiersz — atrapa.
Następnie sumowane są trafne i błędne typy
danego użytkownika.
4. Utworzymy funkcję, która odczytuje
z plików wyniki ze wszystkich tygodni:
>D < "# ��1�,=�1!D� !�?A,%@�A,"�1< #�8@�bA # ��B�F">�?A>"�1= ��1�.��1�,,"��?A,%BB�F">�?!D7! �?A>"�1= ��1@��@�9B�..���1!D� !=�B�FA �1=>"�1�.�A,"�1< #�8���A>"�1= ��1C����8='��5�?>"�1�?A �1=>"�1B@�I,#= �1=�� �I@�bA # ��BCH�1�,=�1!D� !�?A,%@�A,"�1< #�8@�A # ��BCHH
Funkcja ������#>��# � otrzymuje trzy
argumenty — wskaźnik na katalog
(utworzony w momencie otwierania
katalogu), nazwę katalogu oraz tablicę
"�����. Ta ostatnia zmienna jest zawsze
przekazywana przez odwołanie, a nie przez
wartość, tak więc wszystkie dokonane
zmiany dla tej zmiennej wewnątrz funkcji
będą dotyczyły zmiennej poza funkcją.
Funkcja ������#>��# � wykonuje się
w pętli dla każdego pliku w katalogu
(zauważmy, że w funkcji zastosowano
rekurencję — funkcja wywołuje samą
siebie). W przypadku rozpoznania pliku
z wynikami, który charakteryzuje się
nazwą postaci results_WEEK_.txt, plik
ten będzie odczytany do tablicy, a tablica
zostanie przekazana przez odwołanie
do funkcji ��������� �. Dzięki temu
dowolne zmiany w tablicy "����� pozafunkcją będą odzwierciedlone w obrębie
funkcji ������#>��# �.
Funkcje a odwołania
Zaawansowane programowanie w PHP
55
Funkcje
a odwołania
Skrypt 1.11. Ostatni skrypt w tej aplikacji WWW odczytuje wszystkie pliki z wynikami. Wykorzystano w nimodwołania w celu obliczenia podsumowań dla sezonu — do aktualnej daty
��������������� ����������������������������������� !" "# ������$������� %&��'''�'��#�(��)�$����)���*� ����$�����$+�����*� ���� �� !" "# ���, ,�-�������� ���*�� !.�� %&��'''�'��#�(��///�*� ���-0��������� " �1-�# ��"3� #��%"45��!5"�� " �1-2��������1�,-+������7#,8-6������:%�%9/������V���������������������������������V��������V��7�"<31 "1�'8 "5M'�!13# D�������V��������V���������������������������������V��$������>D < "# �,#= �1=�� ��?AE��D1@�A518@�A # ��B�F����ZD 5<Y��!D�DY1� ��> 1�"�74L, 1� 8%8������DO8 5#' "5M'��0�2�������">�?A518��.��B�F�����( #�DY1�8�%"1�'!38�'"1�!3���� ��%L��+�6����������A�" 1�.�1*%�#,1�?�G �@�AE��D1BC�����8,3"1���8� �3'L�DO8 5#' "5��#��3� ��> 1������������"�74L, 1� 8%8��9����������AD!1� ��1�.�A�" 1R�SC�/����������A # ��R�AD!1� ��1�SR�'" !�S�T.�A�" 1R�SC$�����������A # ��R�AD!1� ��1�SR��#!!1!�S�T.�A�" 1R$SC$��������H$$����H$��2��������#�&�� �!�� ����#���������� ��#& (��:�#&#!���;$2$+�������">�?A>"�1= ��1�.��1�,,"��?A,%BB�F�����31!3D5"'� "1�5� ��#(D�$6����������">�?!D7! �?A>"�1= ��1@��@�9B�..���1!D� !=�B�F����[1O1�"�Y1! � #�%�"5�3�'8 "5��"����$9�������������A �1=>"�1�.�A,"�1< #�8���A>"�1= ��1C���������������! !(��!���������#*�����������&�#*��"!#*���:�#&#!��������(�&�!����&.���%�<�����������������!��!�(�*�������������H�������������1�,=�1!D� !�?A,%@�A,"�1< #�8@�A # ��BC����#' ��3� "1�#%1��<Y"�,���5#�1Y 8<��%�"5M'������������'�5� ��#(D��$�������H������H�0�2����A # ���.�����8?BC����K�" "<Y#'� "1�(4M' 1Y�3�"1 1Y��+�6����A,"�1< #�8�.�I$����IC�9����A,%�.�#%1 ,"��?A,"�1< #�8BC�/�����1�,=�1!D� !�?A,%@�A,"�1< #�8@�A # ��BC������D<�#�"1 "1�%�#<1!D�0�����<�#!1,"��?A,%BC0�����1<�#���%�1-G �C0$����%�" =��?A # ��BC����W3875"1�'8Q'"1 �1 "1�'8 "5M'�0�����1<�#����%�1-G �C00����:-02������7#,8-0+������� ��-
Rozdział 1.
56
5. Tworzymy główną zmienną, otwieramy
katalog i rozpoczynamy proces obliczeń.
A # ���.�����8?BCA,"�1< #�8�.�I$����ICA,%�.�#%1 ,"��?A,"�1< #�8BC�1�,=�1!D� !�?A,%@�A,"�1< #�8@�A # ��BC<�#!1,"��?A,%BC
6. Wyświetlamy obliczenia w przeglądarce
WWW.
1<�#���%�1-G �C%�" =��?A # ��BC1<�#����%�1-G �C
Funkcja ������ � pobiera zmienną jako
argument i wyświetla jej zawartość oraz
strukturę. Dzięki temu funkcja ta jest bardzo
użytecznym sposobem szybkiej analizy
skomplikowanych tablic i obiektów.
Moglibyśmy też pobrać tę tablicę i w celu
wyświetlenia wyników utworzyć formalną
tabelę. Funkcja ������ � jest nowością w
PHP4. Użytkownicy wcześniejszej wersji
powinni zamiast niej skorzystać z funkcji
����>�� �.
7. Zamykamy kod PHP oraz dokument HTML.
:-��7#,8-��� ��-
8. Zapisujemy ten plik pod nazwą process_
season.php, kopiujemy go na serwer
i uruchamiamy w przeglądarce WWW
(rysunek 1.14).
Rysunek 1.14. Jak widać, skrypt process_season.phppo prostu wyświetla wyniki. Po uzyskaniu tejinformacji można ją bardzo łatwo przesłaćpocztą elektroniczną
Rysunek 1.15. Funkcja var_dump() wyświetla te
same informacje, co funkcja print_r() (rysunek 1.14),
ale zawiera nieco więcej danych
Funkcje a odwołania
Zaawansowane programowanie w PHP
57
Rysunek 1.16. Próba wykonania funkcji print_rlub funkcji var_dump() bez znaczników <pre></pre>powoduje wyświetlenie brzydkiego, nieczytelnegowyniku
Rysunek 1.17. Przeglądanie źródła wyniku
pokazanego na rysunku 1.16 powoduje poprawę
jakości wyświetlania tablicy, która zostaławyświetlona przez funkcję var_dump().W zasadzie odpowiada to rysunkowi 1.15,
gdzie użyto znaczników <pre></pre>
Wskazówki
� Aby porównać funkcję ������ � z funkcją����>�� �, należy zmienić ostatni wiersz
w skrypcie process_season.php (skrypt 1.11)
na ����>�� "������, a następnie uruchomić
ten skrypt w przeglądarce (rysunek 1.15).
� Zastosowanie znaczników HTML ����!�����!powoduje wyświetlanie tablicy w przeglądarce
w formacie źródła. Na rysunku 1.16 pokazano,
jak wyglądałby wynik bez tych znaczników,
chociaż źródło (rysunek 1.17) jest czytelne.
� Więcej informacji na temat odwołań można
znaleźć pod adresem www.php.net/manual/
en/language.references.php.
Funkcje
a odwołania