Podręcznik PHP

Mehdi Achour
Friedhelm Betz
Antony Dovgal
Nuno Lopes
Philip Olson
Georg Richter
Damien Seguy
Jakub Vrana
I kilka innych
Marcin Dąbrowski
Michał Grzechowiak
Michał Jany
Leszek Krupiński
Adam Major
Paweł Paprota
Michał Pena
Sławomir Pucia
Jarek Tabor
Tomasz Wójtowicz

2006-05-25

Copyright

Prawa autorskie do tego podręcznika © 1997 - 2006 należą do PHP Documentation Group. Materiał ten może być rozprowadzany tylko pod warunkami określonymi w Open Publication License, v1.0 lub nowszych. Kopia Open Publication License jest dystrybuowana z tym podręcznikiem. Najnowsza wersja jest aktualnie dostępna pod adresem http://www.opencontent.org/openpub/.

Dystrybucja zmodyfikowanych wersji tego dokumentu jest zabroniona, chyba że jednostka będąca właścicielem praw autorskich jawnie udzieliła pozwolenia.

Dystrybucja tej pracy lub jej pochodnej w jakiejkolwiek standardowej (papierowej) formie jest możliwa tylko po udzieleniu jawnego pozwolenia przez jednostka będąca właścicielem praw autorskich.

W przypadku zainteresowania redystrybucją lub publikowaniem tego dokumentu w całości lub jego części, zmodyfikowanego czy niezmodyfikowanego, wszystkie pytania należy zadawać posiadaczom praw autorskich do niego pod adresem doc-license@lists.php.net. Adres ten jest podłączony do publicznie archiwizowanej listy dyskusyjnej.

Rozdział Rozdział 46 jest oparty o początkowy wkład firmy Zend Technologies.


Spis treści
Preface
Autorzy i współpracownicy
I. Na początek
1. Wprowadzenie
2. Mały przewodnik
II. Instalacja i konfiguracja
3. General Installation Considerations
4. Installation on Unix systems
5. Installation on Mac OS X
6. Installation on Windows systems
7. Installation of PECL extensions
8. Problems?
9. Runtime Configuration
III. Opis języka
10. Podstawowa składnia
11. Typy danych
12. Zmienne
13. Stałe
14. Wyrażenia
15. Operatory
16. Struktury kontrolne
17. Funkcje
18. Klasy i obiekty (PHP 4)
19. Classes and Objects (PHP 5)
20. Exceptions
21. Referencje
IV. Bezpieczeństwo
22. Introduction
23. General considerations
24. Installed as CGI binary
25. Installed as an Apache module
26. Filesystem Security
27. Database Security
28. Error Reporting
29. Using Register Globals
30. User Submitted Data
31. Magic Quotes
32. Hiding PHP
33. Keeping Current
V. Możliwości
34. Uwierzytelnianie HTTP w PHP
35. Ciasteczka (cookies)
36. Sessions
37. Dealing with XForms
38. Handling file uploads
39. Korzystanie ze zdalnych plików
40. Obsługa połączeń
41. Stałe połączenia z bazami danych
42. Tryb bezpieczny
43. Using PHP from the command line
VI. Opis funkcji
I. .NET Functions
II. Apache serwer
III. Alternative PHP Cache
IV. Advanced PHP debugger
V. Tablice
VI. Aspell [przestarzałe]
VII. BCMath - arytmetyka liczb dużej precyzji
VIII. PHP bytecode Compiler
IX. Kompresja Bzip2
X. Calendar Functions
XI. CCVS API Functions [deprecated]
XII. Klasy/Obiekty
XIII. Classkit Functions
XIV. ClibPDF Functions
XV. COM and .Net (Windows)
XVI. Crack Functions
XVII. Character Type Functions
XVIII. CURL, Client URL Library Functions
XIX. Cybercash Payment Functions
XX. Credit Mutuel CyberMUT functions
XXI. Cyrus IMAP administration Functions
XXII. Data i Czas
XXIII. DB++ Functions
XXIV. Database (dbm-style) Abstraction Layer Functions
XXV. dBase Functions
XXVI. DBM Functions [deprecated]
XXVII. dbx Functions
XXVIII. Direct IO Functions
XXIX. Obsługa katalogów
XXX. DOM Functions
XXXI. DOM XML Functions
XXXII. Identyfikacja błędów i kontrola pracy
XXXIII. Exif Functions
XXXIV. Expect Functions
XXXV. File Alteration Monitor Functions
XXXVI. Forms Data Format Functions
XXXVII. Fileinfo Functions
XXXVIII. filePro Functions
XXXIX. System plików
XL. Filter Functions
XLI. Firebird/InterBase Functions
XLII. Firebird/Interbase Functions (PDO_FIREBIRD)
XLIII. FriBiDi Functions
XLIV. FrontBase Functions
XLV. FTP
XLVI. Function Handling Functions
XLVII. Gettext
XLVIII. GMP Functions
XLIX. gnupg Funkcje
L. Net_Gopher
LI. hash Functions
LII. HTTP - obsługa protokołu
LIII. Hyperwave Functions
LIV. Hyperwave API Functions
LV. IBM DB2, Cloudscape and Apache Derby Functions
LVI. ICAP Functions [deprecated]
LVII. iconv
LVIII. ID3 Functions
LIX. IIS Administration Functions
LX. Image Functions
LXI. IMAP, POP3 and NNTP Functions
LXII. Informix Functions
LXIII. Informix Functions (PDO_INFORMIX)
LXIV. Ingres II Functions
LXV. IRC Gateway Functions
LXVI. PHP / Java Integration
LXVII. KADM5
LXVIII. LDAP Functions
LXIX. libxml Functions
LXX. Lotus Notes Functions
LXXI. LZF Functions
LXXII. Poczta elektroniczna
LXXIII. mailparse Functions
LXXIV. Matematyka
LXXV. MaxDB PHP Extension
LXXVI. MCAL Functions
LXXVII. Mcrypt Encryption Functions
LXXVIII. MCVE (Monetra) Payment Functions
LXXIX. Memcache Functions
LXXX. Mhash Functions
LXXXI. Mimetype Functions
LXXXII. Ming functions for Flash
LXXXIII. Miscellaneous Functions
LXXXIV. mnoGoSearch Functions
LXXXV. Microsoft SQL Server Functions
LXXXVI. Microsoft SQL Server and Sybase Functions (PDO_DBLIB)
LXXXVII. Mohawk Software Session Handler Functions
LXXXVIII. mSQL Functions
LXXXIX. Multibyte String Functions
XC. muscat Functions
XCI. MySQL
XCII. MySQL Functions (PDO_MYSQL)
XCIII. MySQL Improved Extension
XCIV. Ncurses Terminal Screen Control Functions
XCV. Network Functions
XCVI. Newt Functions
XCVII. NSAPI-specific Functions
XCVIII. Object Aggregation/Composition Functions
XCIX. Przeciążanie właściwości obiektów i wołania ich metod
C. Oracle Functions
CI. ODBC Functions (Unified)
CII. ODBC and DB2 Functions (PDO_ODBC)
CIII. oggvorbis
CIV. OpenAL Audio Bindings
CV. OpenSSL Functions
CVI. Oracle Functions [deprecated]
CVII. Oracle Functions (PDO_OCI)
CVIII. Output Control Functions
CIX. Ovrimos SQL Functions
CX. Paradox File Access
CXI. Parsekit Functions
CXII. Process Control Functions
CXIII. Regular Expression Functions (Perl-Compatible)
CXIV. PDF Funkcje
CXV. PDO Functions
CXVI. PHP Options&Information
CXVII. POSIX Functions
CXVIII. Regular Expression Functions (POSIX Extended)
CXIX. PostgreSQL
CXX. PostgreSQL Functions (PDO_PGSQL)
CXXI. Printer Functions
CXXII. Program Execution Functions
CXXIII. PostScript document creation
CXXIV. Pspell Functions
CXXV. qtdom Functions
CXXVI. Radius
CXXVII. Rar Functions
CXXVIII. GNU Readline
CXXIX. GNU Recode Functions
CXXX. RPM Header Reading Funkcje
CXXXI. runkit Functions
CXXXII. Satellite CORBA client extension [deprecated]
CXXXIII. SDO Functions
CXXXIV. SDO XML Data Access Service Functions
CXXXV. SDO Relational Data Access Service Functions
CXXXVI. Semaphore, Shared Memory and IPC Functions
CXXXVII. SESAM Database Functions
CXXXVIII. PostgreSQL Session Save Handler
CXXXIX. Sesje
CXL. Shared Memory Functions
CXLI. SimpleXML functions
CXLII. SNMP Functions
CXLIII. SOAP Functions
CXLIV. Socket Functions
CXLV. Standard PHP Library (SPL) Functions
CXLVI. SQLite Functions
CXLVII. SQLite Functions (PDO_SQLITE)
CXLVIII. Secure Shell2 Functions
CXLIX. Statistics Functions
CL. Stream Functions
CLI. Funkcje łańcuchów znaków
CLII. Shockwave Flash Functions
CLIII. Sybase Functions
CLIV. TCP Wrappers Functions
CLV. Tidy Functions
CLVI. Funkcje Tokenizera
CLVII. Unicode Functions
CLVIII. URL
CLIX. Variable Handling Functions
CLX. Verisign Payflow Pro Functions
CLXI. vpopmail Functions
CLXII. W32api Functions
CLXIII. WDDX Functions
CLXIV. win32ps Functions
CLXV. win32service Functions
CLXVI. xattr Functions
CLXVII. xdiff Functions
CLXVIII. XML Parser Functions
CLXIX. XML-RPC Functions
CLXX. XMLReader functions
CLXXI. xmlwriter Functions
CLXXII. XSL functions
CLXXIII. XSLT Functions
CLXXIV. YAZ Functions
CLXXV. YP/NIS Functions
CLXXVI. Zip File Functions (Read Only Access)
CLXXVII. Zlib Compression Functions
VII. PHP i struktura wewnętrzna Zend Engine
44. Streams API for PHP Extension Authors
45. PDO Driver How-To
46. Zend API: Hackowanie rdzenia PHP
47. TSRM API
48. Extending PHP 3
VIII. FAQ: Frequently Asked Questions
49. General Information
50. Mailing lists
51. Obtaining PHP
52. Database issues
53. Installation FAQ
54. Build Problems
55. Using PHP
56. PHP and HTML
57. PHP and COM
58. PHP i inne języki
59. Migracja z PHP 2 na PHP 3
60. Migracja z PHP 3 na PHP 4
61. Migrating from PHP 4 to PHP 5
62. Miscellaneous Questions
IX. Dodatki
A. History of PHP and related projects
B. Migrating from PHP 4 to PHP 5
C. Migrating from PHP 3 to PHP 4
D. Migrating from PHP/FI 2 to PHP 3
E. Debugging PHP
F. Configure options
G. php.ini directives
H. List of Supported Timezones
I. Extension Categorization
J. Lista aliasów funkcji
K. List of Reserved Words
L. Lista Rodzajów Zasobów
M. List of Supported Protocols/Wrappers
N. List of Available Filters
O. List of Supported Socket Transports
P. PHP type comparison tables
Q. List of Parser Tokens
R. About the manual
S. Open Publication License
T. Indeks funkcji
U. Braki

Preface

PHP, co jest skrótem od "PHP: Hypertext Preprocessor", jest powszechnie używanym językiem skryptowym ogólnego przeznaczenia, który jest szczególnie przystosowany do tworzenia aplikacji Webowych, także poprzez zagnieżdżenie wewnątrz języka HTML. Składnia, wywodząca się z języków C, Java i Perl, jest łatwa do nauczenia się. Głównym celem języka jest umożliwienie programistom szybkiego tworzenia stron internetowych, ale PHP umożliwia znacznie więcej.

Podręcznik ten składa się głównie z opisu funkcji, ale zawiera także opis języka, objaśnienie niektórych z głównych cech PHP, jak również kilka dodatkowych informacji.

Podręcznik można pobrać w kilku formatach spod adresu http://www.php.net/download-docs.php. Więcej informacji na temat prac nad tym podręcznikiem można znaleźć w rozdziale 'O podręczniku'. Osobom zainteresowanym historią PHP polecamy odpowiedni dodatek.


Autorzy i współpracownicy

Wyróżniamy najbardziej aktywnych twórców na pierwszej stronie podręcznika, ale jest wielu innych współpracowników, którzy pomagają w pracach, lub włożyli wiele pracy w przeszłości. Jest wielu bezimiennych pomocników, którzy wnieśli swój udział komentarzami do podręcznika, które cały czas są uwzględniane w odnośnikach, i za które to uwagi także dziękujemy. Wszystkie poniższe listy uporządkowane są alfabetycznie.


Autorzy i edytorzy

Poniżsi współpracownicy powinni zostali wyróżnieni za wpływ jaki mieli (lub ciągle mają) w rozwijanie podręcznika: Jouni Ahto, Alexander Aulbach, Daniel Beckham, Stig Bakken, Jesus M. Castagnetto, Ron Chmara, Sean Coates, John Coggeshall, Simone Cortesi, Markus Fischer, Wez Furlong, Sara Golemon, Rui Hirokawa, Brad House, Moriyoshi Koizumi, Rasmus Lerdorf, Andrew Lindeman, Stanislav Malyshev, Rafael Martinez, Yasuo Ohgaki, Derick Rethans, Sander Roobol, Egon Schmid, Thomas Schoefbeck, Sascha Schumann, Dan Scott, Lars Torben Wilson, Jim Winstead, Jeroen van Wolffelaar i Andrei Zmievski.

Poniżsi współpracownicy włożyli wiele pracy przy edycji podręcznika: Stig Bakken, Gabor Hojtsy, Hartmut Holzgraefe i Egon Schmid.


Opiekunowie notatek

Aktualnie najbardziej aktywni opiekunowie to: Mehdi Achour, Friedhelm Betz, Vincent Gevers, Aidan Lister, Nuno Lopes i Tom Sommer.

Te osoby także pracowały nad zarządzaniem notatkami: Daniel Beckham, Victor Boivie, Jesus M. Castagnetto, Nicolas Chaillan, Ron Chmara, James Cox, Sara Golemon, Zak Greant, Szabolcs Heilig, Oliver Hinckel, Hartmut Holzgraefe, Rasmus Lerdorf, Andrew Lindeman, Maxim Maletsky, James Moore, Sebastian Picklum, Derick Rethans, Sander Roobol, Damien Seguy, Jason Sheets, Jani Taskinen, Yasuo Ohgaki, Philip Olson, Lars Torben Wilson, Jim Winstead, Jared Wyles i Jeroen van Wolffelaar.

I. Na początek


Rozdział 1. Wprowadzenie

Czym jest PHP?

PHP (akronim rekursywny "PHP: Hypertext Preprocessor"), jest szeroko używanym językiem skryptowym ogólnego zastosowania, tworzonym na zasadach Open Source, dopasowanym do potrzeb aplikacji WWW, z możliwością zagnieżdżania w HTML.

Prosta odpowiedź, ale co to znaczy? Przykład:

Przykład 1-1. Wprowadzający przykład

<html>
    <head>
        <title>Przykład</title>
    </head>
    <body>

        <?php 
        echo "Cześć! Jestem skryptem PHP!"; 
        ?>

    </body>
</html>

Zauważ jak bardzo różni się to od skryptów pisanych w innych językach, takich jak C czy Perl -- zamiast pisać program, zawierający mnóstwo komend tylko do wypisania HTML, piszesz kod HTML zawierający troche zagnieżdżonego kodu, który robi coś konkretnego (w powyższym przypadku wypisuje jakiś tekst). Kod PHP jest zawarty pomiędzy specjalnymi znacznikami otwierającymi i zamykającymi które pozwalają na wchodzenie do i wychodzenie z "trybu PHP".

PHP różni się od skryptów wykonywanych po stronie klienta takich jak np. JavaScript tym, że cały kod PHP wykonywany jest na serwerze. Jeśli masz na serwerze skrypt podobny do przedstawionego wyżej, klient dostanie tylko rezultat wykonania skryptu, bez możliwości stwierdzenia jak wygląda generujący go kod. Możesz nawet skonfigurować serwer WWW, tak aby wszystkie pliki HTML były przetwarzane przez PHP. A wtedy nie ma sposobu, aby użytkownik mógł stwierdzić jakie asy trzymasz w rękawie.

Najlepszą rzeczą w używaniu PHP jest to, że jest bardzo łatwy w opanowaniu dla początkującego, ale oferuje także wiele zaawansowanych właściwości zaawansowanym programistom. Nie bój się przeglądając długą listę możliwości PHP. PHP można się szybko nauczyć i już po kilku godzinach pisać proste skrypty.

Pomimo że PHP jest rozwijane pod kątem skryptowania server-side, może on znacznie więcej. Przeczytaj rozdział Co potrafi PHP aby uzyskać więcej informacji, albo samouczek w przypadku zainteresowania tylko programowaniem dla celów www.


Co potrafi PHP?

Wszystko. PHP jest rozwijane pod kątem pisania skryptów server-side, więc możesz zrobić wszystko co potrafią inne programy CGI, jak na przykład odbierać dane z formularzy, generować dynamicznie zawartość strony, lub odbierać i wysyłać ciasteczka. Ale PHP może o wiele więcej.

Istnieją trzy główne pola użytkowania skryptów PHP.

  • Pisanie skryptów server-side. Jest to najbardziej tradycyjne i główne pole działania PHP. Potrzebujesz 3 rzeczy aby to robić: parser PHP (plik wykonywalny CGI lub moduł serwera), serwer WWW i przeglądarka. Musisz uruchomić serwer WWW połączony z PHP. Dane wyjściowe programów PHP możesz oglądać korzystając z przeglądarki poprzez serwer. Wszystko to można uruchomić na swoim domowym komputerze. Zobacz rozdział Instalacja aby uzyskać więcej informacji.

  • Pisanie skryptów uruchamianych z linii poleceń. Moższ napisać skrypt PHP i uruchomić go bez serwera i przeglądarki. Potrzebujesz do tego tylko parsera PHP. Ten typ użytkowania jest idealny do uruchamiania skryptów regularnie poprzez crona (systemy Uniksowe) lub menedżer zadań (systemy Windows), lub przetwarzania tekstu. Zobacz rozdział Uruchamianie PHP z linii poleceń aby uzyskać więcej informacji.

  • Pisanie aplikacji client-side z interfejsem użytkownika. PHP jest prawdopodobnie nienajlepszym językiem do pisania okienkowych aplikacji, ale jeśli bardzo dobrze znasz PHP i chcesz skorzystać z zaawansowanych możliwości PHP w swojej aplikacji client-side, możesz także użyć pakiet PHP-GTK do pisania takich programów. Z PHP-GTK Masz także możliwość pisania aplikacji wieloplatformowych. PHP-GTK jest rozszerzeniem PHP i nie jest dostępne w głównej dystrybucji. Jeśli jesteś zainteresowany PHP-GTK, odwiedź stronę domową projektu.

PHP może być także użyty w większości najważniejszych systemów operacyjnych, takich jak Linux, wiele wariantów systemu Unix (włączając w to HP-UX, Solaris i OpenBSD), Microsoft Windows, Mac OS X, RISC OS i prawdopodobnie wiele innych. PHP w chwili obecnej obsługuje większość serwerów HTTP, włączając w to Apache, Microsoft Internet Information Server, Personal Web Server, serwery Netscape i iPlanet, Oreilly Website Pro, Caudium, Xitami, OmniHTTPd i wiele innych. Dla więszości z nich PHP dostępne jest jako moduły serwera, dla pozostałych jako program CGI. PHP może pracować jako procesor CGI.

A więc z PHP istnieje wolność wyboru systemu operacyjnego i serwera WWW. Można także wybrać pomiędzy programowaniem proceduralnym a obiektowym, lub pomieszaniem ich obu. Pomimo że nie wszystkie standardy OOP są obsługiwane w PHP 4, wiele bibliotek i dużych aplikacji (włączając w to biblioteki PEAR) jest napisanych całkowicie w sposób obiektowy. W PHP 5 naprawiono niedomagania OOP istniejące w PHP 4, implementując pełny model obiektowy.

W PHP nie ma ograniczenia, że na wyjściu musi być HTML. Możliwości PHP obejmują tworzenie obrazów, plików PDF, a nawet animacji Flash (używając libswf i Ming) generowanych "w locie". Możesz także wyprowadzać na wyjście dowolne dane tekstowe, jak na przykład XHTML czy dowolny inny plik XMLowy. PHP może autogenerować te pliki i zapisywać je w systemie plików zamiast wysyłać je na wyjście, tworząc pamięć podręczną dla twojej dynamicznej zawartości.

Jedną z najmocniejszych i najbardziej znaczących możliwości PHP jest obsługa wielu rodzajów baz danych. Pisanie strony WWW wykorzystującej bazę danych jest niewiarygodnie proste. Obecnie obsługiwane są następujące bazy danych:

Adabas DInterBasePostgreSQL
dBaseFrontBaseSQLite
EmpressmSQLSolid
FilePro (tylko do odczytu)Direct MS-SQLSybase
HyperwaveMySQLVelocis
IBM DB2ODBCUnix dbm
InformixOracle (OCI7 i OCI8) 
IngresOvrimos 

Istenieje także abstrakcyjne rozszerzenie DBX pozwalające na przezroczyste używanie dowolnej bazy danych obsługiwanych przez to rozszerzenie. Dodatkowo PHP obsługuje standard ODBC (Open Database Connection), przez co możesz połączyć się do dowolnej innej bazy danych obsługującej ten popularny standard.

PHP obsługuje również inne serwisy używające protokołów takich jak IMAP, SNMP, NNTP, POP3, HTTP, COM (pod systemami Windows) i wiele innych. Możesz także otwierać surowe gniazda sieciowe i korzystać z innych protokołów. PHP obsługuje WDDX - kompleksowy model wymiany danych pomiędzy praktycznie wszystkimi sieciowymi językami programowania. PHP obsługuje także obiekty Java i może korzystać z nich przezroczyście - tak jak z obiektów PHP. Możesz także skorzystać z rozszerzenia Corba aby użyskać dostęp do zdalnych obiektów.

PHP mam niezwykle przydatne możliwości do obróbki tekstów, od POSIX'owych i PERL'owych wyrażeń regularnych po parsowanie dokumentów XML. Do parsowania i uzyskiwania dostępu do dokumentów XML w PHP 4 wykorzystywane są standardy SAX i DOM, można także użyć rozszerzeń XSLT do przetwarzania dokumentów XML. PHP 5 standaryzuje wszystkie rozszerzenia XML na solidnej podstawie libxml2 i poszerza gamę możliwości dodając wsparcie dla SimpleXML i XMLReader.

PHP może być używane w sferze e-commerce, ponieważ obsługuje płatności Cybercash, a także funkcje CyberMUT, VeriSign Payflow Pro i MCVE, przydatne przy płatnościach on-line.

Na koniec warto wspomnieć, że w PHP istnieje wiele innych interesujących rozszerzeń, takich jak funkcje przeszukiwawcze mnoGoSearch, funkcje bramki IRC, wiele narzędzi do kompresji (gzip, bz2), konwersji kalendarza, tłumaczeń...

To co widać na tej stronie, to nie jest wszystko co ma do zaoferowanie PHP. Przeczytaj rozdział o instalacji i zobacz przegląd funkcji jeśli chcesz dowiedzieć się więcej o rozszerzeniach tutaj wspomnianych.


Rozdział 2. Mały przewodnik

W tym małym przewodniku chcielibyśmy przybliżyć ci podstawy PHP. Rozdział ten opisuje tylko tworzenie dynamicznych stron internetowych, ale PHP ma także inne zastosowania. Więcej informacji znajdziesz w rozdziale Co potrafi PHP.

Strony zawierające skrypty PHP nie różnią się zbytnio od zwykłych dokumentów HTML, co oznacza, że w ten sam sposób możesz je tworzyć i modyfikować.


Czego potrzebujesz?

Zakładamy, że twój serwer ma włączoną obsługę PHP i wszystkie pliki o rozszerzeniu .php są przetwarzane przez interpreter PHP. Na wielu serwerach jest to domyślne rozszerzenie dla skryptów, ale mimo wszystko warto zasięgnąć informacji u administratora. Jeżeli twój serwer obsługuje PHP, nie musisz wykonywać żadnych dodatkowych czynności. Po prostu twórz swoje pliki .php i umieszczaj je w dowolnych katalogach na serwerze. Nie musisz nic kompilować ani instalować żadnych dodatkowych narzędzi. Pomyśl o skryptach PHP jak o zwyczajnych dokumentach HTML wykorzystujących całą gamę nowych znaczników, które dają ci praktycznie nieograniczone możliwości. Większość komercyjnych i część niekomercyjnych serwerów WWW obsługuje skrypty PHP, jednak jeśli twój serwer do tej grupy nie należy, możesz poszukać odpowiedniej oferty w jednym z kilku katalogów, których adresy znajdziesz w sekcji linki.

Powiedzmy, że chcesz budować i uruchamiać swoje skrypty na własnym komputerze. W tym wypadku, będzisz musiał zainstalować serwer WWW np. Apache i oczywiście PHP. Najprawdopodobniej będziesz chciał także umożliwić skryptom dostęp do bazy danych, takiej jak MySQL. Elementy te możesz zainstalować odzielnie lub w łatwiejszy sposób, korzystając z pakietu, który zarówno zainstaluje jak i skonfiguruje wszystkie składniki. Instalacja serwera WWW z obsługą PHP nie nie jest trudna zarówno w systemach Linux jak i Windows. Jeśli używasz systemu Linux, możesz skorzystać z wyszukiwarki rpmfind w celu odnalezienia wymaganych pakietów RPM.


Twój pierwszy skrypt PHP

Utwórz w głównym katalogu serwera (DOCUMENT_ROOT) plik o nazwie hello.php i następującej treści:

Przykład 2-1. Twój pierwszy skrypt PHP: hello.php

<html>
 <head>
  <title>Test PHP</title>
 </head>
 <body>
 <?php echo "<p>Witaj Świecie !</p>"; ?>
 </body>
</html>

Teraz korzystając z przeglądarki internetowej otwórz wcześniej utworzony plik, podając jego pełny adres URL (np. http://twoj.serwer.pl/hello.php). Jeżeli testujesz swój skrypt lokalnie, jego adres URL to, zależnie od konfiguracji serwera, http://localhost/hello.php lub http://127.0.0.1/hello.php. Zwróć uwagę na dyrektywy DocumentRoot i ServerName w pliku konfiguracyjnym twojego serwera (dla serwera Apache jest to plik httpd.conf). Jeśli wszystko jest poprawnie skonfigurowane, interpreter PHP przetworzy plik i wyśle do przeglądarki następujące dane:

<html>
 <head>
  <title>Test PHP</title>
 </head>
 <body>
 <p>Witaj Świecie !</p>
 </body>
</html>

Zauważ jak bardzo to się różni od skryptów CGI. Plik nie musi być kompilowany ani poddawany jakimkolwiek innym przetworzeniom.

To chyba najprostszy program, jaki można sobie wyobrazić i chyba naprawdę nigdy nie będziesz musiał używać PHP do tworzenia stron takich jak ta. Całe jego zadanie polega na wyświetleniu zdania: Witaj Świecie ! przy użyciu wbudowanej w PHP instrukcji echo().

Jeżeli po wypróbowaniu tego przykładu w przeglądarce pojawiła się pusta strona, otworzyło się okno z pytaniem o zapisanie pliku lub też wyświetliła się cała zawartość hello.php, bardzo możliwe, że serwer ma wyłączoną obsługę PHP (lub też nie ma jej wcale). W takim wypadku poproś administratora o jej aktywowanie przy pomocy wskazówek z rozdziału Instalacja. Jeśli tworzysz skrypty lokalnie, również powinieneś zapoznać się z treścią tego rozdziału, aby upewnić się czy wszystko jest poprawnie skonfigurowane. Gdy problem mimo wszystko w dalszym ciągu się powtarza, skorzystaj z informacji zawartych na stronie Pomocy technicznej PHP.

Głównym celem tego przykładu było pokazanie specyficznej składni PHP. Najpierw użyliśmy znacznika <?php, aby poinformować interpreter, że w tym miejscu rozpoczyna się kod PHP. Następnie wprowadziliśmy instrukcję wyświetlającą napis Witaj Świecie ! i zakończyliśmy skrypt znacznikiem ?>. W ten właśnie sposób możesz mieszać kod PHP ze znacznikami HTML. Więcej informacji o składni PHP znajdziesz w rozdziale Podstawowa składnia.

Edytory tekstowe: Istnieje wiele tekstowych edytorów i zintegrowanych środowisk programistycznych (IDE), których możesz użyć do tworzenia, modyfikowania i zarządzania skryptami PHP. Obszerna lista takich programów znajduje się na stronie http://www.thelinuxconsultancy.co.uk/phpeditors.php. Jeżeli chciałbyś polecić innym jakiś edytor, zajrzyj na powyższą stronę i poproś jej właściciela o dodanie programu do spisu.

Procesory tekstu: Programy takie jak StarOffice Writer, Microsoft Word i Abiword nie nadają się zbytnio do pracy ze skryptami PHP. Jeżeli mimo to chcesz korzystać z którejś z wymienionych aplikacji, musisz mieć pewność, że kod skrypu zapisywany jest jako zwykły tekst. W przeciwnym wypadku PHP nie będzie w stanie przetworzyć pliku.

Notatnik Windows: Jeśli piszesz skrypty w Windowsowym Notatniku, sprawdzaj czy pliki zapisywane są z rozszerzeniem .php (Notatnik domyślnie zapisuje wszystkie pliki dodając rozszerzenie .txt). Kiedy zapisujesz plik i program wyświetla okno dialogowe z pytaniem o nazwę pliku, umieść tę nazwę w cudzysłowie (np. "hello.php"). Drugim sposobem jest wybranie z rozwijanej listy 'Zapisz jako typ' w tym samym oknie opcji 'Wszystkie pliki' (zamiast ustawionej domyślnie 'Dokumenty tekstowe (*.txt)'). Teraz możesz podać nazwę pliku bez cudzysłowów.

Teraz kiedy napisałeś już pierwszy działający program, czas stworzyć chyba najbardziej znany skrypt PHP! Stwórz nowy plik, umieść w nim znaczniki PHP i wywołaj funkcję phpinfo(). Po uruchomienia skryptu, ujrzysz w swojej przeglądarce długą stronę zawierającą wiele przydatnych informacji o twoim systemie operacyjnym i ustawieniach takich jak zmienne predefiniowane, załadowane moduły PHP, i opcje konfiguracji. Poświęć trochę czasu na przejrzenie tych informacji.


Coś użytecznego

Zabierzmy się teraz za coś, co może się nam do czegoś przydać. Chcemy sprawdzić w jakiej przeglądarce internetowej użytkownik ogląda naszą stronę. W tym celu odczytamy nagłówek User-Agent, który został przesłany w żądaniu HTTP przez przeglądarkę użytkownika. Informacja ta znajduje się w zmiennej. Nazwy zmiennych są w PHP poprzedzone znakiem dolara "$". Zmienna, która nas interesuje, to $_SERVER["HTTP_USER_AGENT"].

Zmienne superglobalne: $_SERVER jest specjalną zmienną PHP, która zawiera informacje związane z serwerem i środowiskiem uruchomieniowym danego skryptu. Zmienna ta jest nazywana superglobalną (bądź autoglobalną). Co to oznacza, dowiesz się na stronie poświęconej zmiennym predefiniowanym. Zmienne superglobalne wprowadzono w PHP w wersji 4.1.0. Przedtem wykorzystywane były tablice $HTTP_*_VARS, takie jak $HTTP_SERVER_VARS. Chociaż używanie ich nie jest zalecane, są one w dalszym ciągu dostępne w PHP (przeczytaj także notatkę dotyczącą używania starej składni).

Możemy w łatwy sposób wyświetlić wartość tej zmiennej:

Przykład 2-2. Wyświetlanie wartości zmiennej (elementu tablicy)

<?php echo $_SERVER["HTTP_USER_AGENT"]; ?>

Przykładowym wynikiem działania tego skryptu może być:
Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)

W PHP istnieje wiele typów zmiennych. W powyższym przykładzie wyświetliliśmy wartość elementu tablicy. Tablice mogą mieć wiele zastosowań.

$_SERVER jest tylko jedną ze zmiennych, które zawsze są dostępne dla skryptów PHP. Lista wszystkich takich zmiennych znajduje się w sekcji Predefiniowane zmienne, możesz także wygenerować ją przy pomocy prostego skryptu:

Przykład 2-3. Pokaż wszystkie zmienne predefiniowane

<?php phpinfo(); ?>

Po wywołaniu skryptu, ujrzysz w swojej przeglądarce stronę zawierającą wiele informacji o PHP łącznie z kompletną listą zmiennych predefiniowanych.

Pomiędzy znacznikami skryptu PHP możesz umieścić wiele różnych instrukcji, nie tylko echo(). Przykładowo, jeśli chcesz sprawdzić czy przeglądarka użytkownika to Internet Explorer, możesz napisać taki skrypt:

Przykład 2-4. Przykład wykorzystania struktur kontrolnych i funkcji

<?php
if (strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE') !== false) {
	echo 'Używasz Internet Explorera<br />';
}
?>

Jak nietrudno się domyślić, skrypt może wyświetlić:
Używasz Internet Explorera<br />

W powyższym przykładzie wprowadziliśmy kilka nowych rozwiązań. Przede wszystkim mamy tutaj instrukcję if. Dla osób znających podstawową składnię języka C powinna ona wyglądać znajomo. Jeśli nie rozumiesz do czego ta instrukcja służy, nie obejdzie się bez lektury rozdziału Opis języka. W początkowej fazie nauki języka pomocne mogą być także książki opisujące PHP od podstaw. Spis publikacji poświęconych PHP znajduje się pod adresem http://www.php.net/books.php.

Następnym nowym rozwiązaniem jest wywołanie funkcji strpos(). strpos() jest funkcją wbudowaną w PHP, służy do wyszukiwania jednego łańcucha znaków w drugim. W naszym przykładzie próbowaliśmy odnaleźć "MSIE" w zmiennej $_SERVER["HTTP_USER_AGENT"]. Jeżeli ciąg ten został odnaleziony, funkcja zwróciła jego pozycję w łańcuchu $_SERVER["HTTP_USER_AGENT"]. Jeśli funkcja nie zwróciła wartości FALSE, wykonywany był kod umieszczony wewnątrz nawiasów klamrowych instrukcji if. W przeciwnym wypadku, gdy strpos() zwróciła wartość FALSE, kod był pomijany. Spróbuj napisać kilka podobnych przykładów z wykorzystaniem instrukcji if, else oraz funkcji takich jak strtoupper() lub strlen(). Każda ze stron opisujących te metody zawiera także przykłady, które pomogą ci zrozumieć ich działanie. Jeżeli nie jesteś pewny jak używać funkcji, zajrzyj na stronę wyjaśniającą jak czytać opisy funkcji i do rozdziału Funkcje.

Przejdźmy teraz krok dalej i zobaczmy w jaki sposób możemy przeplatać kod HTML instrukcjami języka PHP:

Przykład 2-5. Mieszanie HTML z PHP

<?php
if (strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE') !== false) {
?>
<h3>Funkcja strpos zwróciła wartość inną niż &false;</h3>
<center><b>Używasz Internet Explorera</b></center>
<?php
} else {
?>
<h3>Funkcja strpos zwróciła wartość false</h3>
<center><b>Nie używasz Internet Explorera</b></center>
<?php
}
?>

Wynikiem działania tego skryptu może być:
<h3>Funkcja strpos zwróciła wartość true</h3>
<center><b>Używasz Internet Explorera</b></center>

Tym razem zamiast instrukcji echo() skorzystaliśmy z innej możliwości - wymieszaliśmy ze sobą kod HTML i PHP. W tym miejscu warto zaznaczyć, że skrypt mimo dużych zmian w zastosowanej składni, nadal działa tak samo. W zależności od tego, co zwróci funkcja strpos(), wyświetlony zostanie tylko jeden blok kodu HTML. Innymi słowy, wszystko zależy od tego, czy ciąg MSIE zostanie odnaleziony w łańcuchu $_SERVER["HTTP_USER_AGENT"].


PHP i formularze

Obsługa formularzy HTML to jedno z podstawowych zadań skryptów PHP. Najprościej mówiąc, wartości wszystkich elementów formularza (pól tekstowych, pól checkbox i radio, list rozwijanych itp.) są automatycznie udostępniane skryptom PHP. Przykłady i informacje na ten temat znajdziesz w sekcji Zmienne spoza PHP. Oto przykładowy formularz HTML:

Przykład 2-6. Prosty formularz HTML

<form action="action.php" method="post">
 Twoje imię: <input type="text" name="imie" />
 Data urodzenia: <input type="text" name="rok" />
 <input type="submit" />
</form>

Nie ma tu nic niezwykłego. To po prostu zwyczajny formularz zbudowany ze standardowych znaczników języka HTML. Gdy użytkownik wypełni pola tekstowe i kliknie przycisk, informacje zostaną przesłane do skryptu action.php. W tym pliku mógłbyś umieścić coś takiego:

Przykład 2-7. Wyświetlanie danych z formularza

Cześć <?php echo $_POST['imie']; ?>.
Urodziłeś się w <?php echo $_POST['rok']; ?> roku.

Wynikiem wykonania takiego skryptu może być:

Cześć Zenek. Urodziłeś się w 1980 roku.

Chyba nie trzeba tłumaczyć do czego służy powyższy skrypt. Zmienne $_POST['imie'] i $_POST['rok'] są automatycznie ustawiane po przesłaniu formularza przez użytkownika. Wcześniej użyliśmy zmiennej superglobalnej $_SERVER; teraz poznaliśmy zmienną $_POST (również superglobalną), która przechowuje wszystkie dane wysłane w formularzu. Zauważ, że nasz formularz przekazywany jest metodą POST (parametr method). Jeśli wybralibyśmy metodę GET, wszystkie dane znajdowały się w zmiennej superglobalnej $_GET. Ostatecznie możesz również skorzystać ze zmiennej $_REQUEST, jeśli nie interesuje cię to, skąd pochodzą przesłane dane. Zmienna ta zawiera wszystkie informacje niezależnie od tego czy zostały one przekazane metodą GET, POST czy też w ciasteczku (cookie). Przyjrzyj się też funkcji import_request_variables().


Używanie starej składni w nowych wersjach PHP

Odkąd PHP stało się popularnym językiem skryptowym, istnieją duże archiwa darmowych skryptów, które można często bez żadnych ograniczeń wykorzystywać na swoich stronach WWW. Twórcy PHP postarali się, aby uruchamianie starszych skryptów było możliwe we wszystkich nowszych wersjach środowiska. Czasami jednak, aby uruchomić taki program, trzeba będzie dokonać w nim pewnych zmian.

Dwie najistotniejsze zmiany w stosunku do starszych wersji PHP to:

  • Zastąpienie zmiennych $HTTP_*_VARS (które wewnątrz funkcji muszą być importowane tak jak zmienne globalne) tablicami superglobalnymi w wersji 4.1.0 środowiska PHP. Oto one: $_GET, $_POST, $_COOKIE, $_SERVER, $_FILES, $_ENV, $_REQUEST i $_SESSION. Wykorzystywane wcześniej tablice $HTTP_*_VARS, takie jak np. $HTTP_POST_VARS, nadal są dostępne dla skryptów. Od PHP w wersji 5.0.0, długie tablice zmiennych predefiniowanych mogą być wyłączone dyrektywą konfiguracji register_long_arrays.

  • Zmienne pochodzące "z zewnątrz" nie są już domyślnie rejestrowane jako zwyczajne zmienne skryptu. Inaczej mówiąc, od wersji 4.2.0 dyrektywa konfiguracyjna register_globals w pliku php.ini domyślnie przyjmuje wartość off. Zalecana metoda odwoływania się do zmiennych "z zewnątrz" polega na zastosowaniu opisanych wyżej tablic superglobalnych. W starszych skryptach, książkach i kursach możesz się spotkać ze starą składnią, która jest niestety mniej bezpieczna. Korzystając ze zmiennych superglobalnych masz pewność, że dane przesłane metodą GET znajdą się w tablicy $_GET, metodą POST w $_POST itd.

Więcej informacji na ten temat znajdziesz w sekcji Zmienne predefiniowane i na stronach pokrewnych.


Co dalej?

Z już nabytą wiedzą nie powinieneś mieć problemów ze zrozumieniem kolejnych rozdziałów podręcznika i zawartych w nich przykładowych skryptów. Przykłady możesz znaleźć również na innych stronach poświęconych PHP: http://www.php.net/links.php.

Jeśli chcesz obejrzeć rozmaite prezentacje na temat PHP i jego zastosowań, zajrzyj na strony: http://conf.php.net/ i http://talks.php.net/


Rozdział 3. General Installation Considerations

Before starting the installation, first you need to know what do you want to use PHP for. There are three main fields you can use PHP, as described in the What can PHP do? section:

  • Websites and web applications (server-side scripting)

  • Command line scripting

  • Desktop (GUI) applications

For the first and most common form, you need three things: PHP itself, a web server and a web browser. You probably already have a web browser, and depending on your operating system setup, you may also have a web server (e.g. Apache on Linux and MacOS X; IIS on Windows). You may also rent webspace at a company. This way, you don't need to set up anything on your own, only write your PHP scripts, upload it to the server you rent, and see the results in your browser.

In case of setting up the server and PHP on your own, you have two choices for the method of connecting PHP to the server. For many servers PHP has a direct module interface (also called SAPI). These servers include Apache, Microsoft Internet Information Server, Netscape and iPlanet servers. Many other servers have support for ISAPI, the Microsoft module interface (OmniHTTPd for example). If PHP has no module support for your web server, you can always use it as a CGI or FastCGI processor. This means you set up your server to use the CGI executable of PHP to process all PHP file requests on the server.

If you are also interested to use PHP for command line scripting (e.g. write scripts autogenerating some images for you offline, or processing text files depending on some arguments you pass to them), you always need the command line executable. For more information, read the section about writing command line PHP applications. In this case, you need no server and no browser.

With PHP you can also write desktop GUI applications using the PHP-GTK extension. This is a completely different approach than writing web pages, as you do not output any HTML, but manage windows and objects within them. For more information about PHP-GTK, please visit the site dedicated to this extension. PHP-GTK is not included in the official PHP distribution.

From now on, this section deals with setting up PHP for web servers on Unix and Windows with server module interfaces and CGI executables. You will also find information on the command line executable in the following sections.

PHP source code and binary distributions for Windows can be found at http://www.php.net/downloads.php. We recommend you to choose a mirror nearest to you for downloading the distributions.


Rozdział 4. Installation on Unix systems

This section will guide you through the general configuration and installation of PHP on Unix systems. Be sure to investigate any sections specific to your platform or web server before you begin the process.

As our manual outlines in the General Installation Considerations section, we are mainly dealing with web centric setups of PHP in this section, although we will cover setting up PHP for command line usage as well.

There are several ways to install PHP for the Unix platform, either with a compile and configure process, or through various pre-packaged methods. This documentation is mainly focused around the process of compiling and configuring PHP. Many Unix like systems have some sort of package installation system. This can assist in setting up a standard configuration, but if you need to have a different set of features (such as a secure server, or a different database driver), you may need to build PHP and/or your webserver. If you are unfamiliar with building and compiling your own software, it is worth checking to see whether somebody has already built a packaged version of PHP with the features you need.

Prerequisite knowledge and software for compiling:

  • Basic Unix skills (being able to operate "make" and a C compiler)

  • An ANSI C compiler

  • flex: Version 2.5.4

  • bison: Version 1.28 (preferred), 1.35, or 1.75

  • A web server

  • Any module specific components (such as gd, pdf libs, etc.)

The initial PHP setup and configuration process is controlled by the use of the commandline options of the configure script. You could get a list of all available options along with short explanations running ./configure --help. Our manual documents the different options separately. You will find the core options in the appendix, while the different extension specific options are descibed on the reference pages.

When PHP is configured, you are ready to build the module and/or executables. The command make should take care of this. If it fails and you can't figure out why, see the Problems section.


Apache 1.3.x on Unix systems

This section contains notes and hints specific to Apache installs of PHP on Unix platforms. We also have instructions and notes for Apache 2 on a separate page.

You can select arguments to add to the configure on line 10 below from the list of core configure options and from extension specific options described at the respective places in the manual. The version numbers have been omitted here, to ensure the instructions are not incorrect. You will need to replace the 'xxx' here with the correct values from your files.

Przykład 4-1. Installation Instructions (Apache Shared Module Version) for PHP

1.  gunzip apache_xxx.tar.gz
2.  tar -xvf apache_xxx.tar
3.  gunzip php-xxx.tar.gz
4.  tar -xvf php-xxx.tar
5.  cd apache_xxx
6.  ./configure --prefix=/www --enable-module=so
7.  make
8.  make install
9.  cd ../php-xxx

10. Now, configure your PHP.  This is where you customize your PHP
    with various options, like which extensions will be enabled.  Do a
    ./configure --help for a list of available options.  In our example
    we'll do a simple configure with Apache 1 and MySQL support.  Your
    path to apxs may differ from our example.

      ./configure --with-mysql --with-apxs=/www/bin/apxs

11. make
12. make install

    If you decide to change your configure options after installation,
    you only need to repeat the last three steps. You only need to 
    restart apache for the new module to take effect. A recompile of
    Apache is not needed.
  
    Note that unless told otherwise, 'make install' will also install PEAR,
    various PHP tools such as phpize, install the PHP CLI, and more.

13. Setup your php.ini file:

      cp php.ini-dist /usr/local/lib/php.ini

    You may edit your .ini file to set PHP options.  If you prefer your
    php.ini in another location, use --with-config-file-path=/some/path in
    step 10. 
    
    If you instead choose php.ini-recommended, be certain to read the list
    of changes within, as they affect how PHP behaves.

14. Edit your httpd.conf to load the PHP module.  The path on the right hand
    side of the LoadModule statement must point to the path of the PHP
    module on your system.  The make install from above may have already
    added this for you, but be sure to check.
        
    For PHP 4:
            
      LoadModule php4_module libexec/libphp4.so

    For PHP 5:
                      
      LoadModule php5_module libexec/libphp5.so
      
15. And in the AddModule section of httpd.conf, somewhere under the
    ClearModuleList, add this:
    
    For PHP 4:
    
      AddModule mod_php4.c
      
    For PHP 5:
    
      AddModule mod_php5.c

16. Tell Apache to parse certain extensions as PHP.  For example,
    let's have Apache parse the .php extension as PHP.  You could
    have any extension(s) parse as PHP by simply adding more, with
    each separated by a space.  We'll add .phtml to demonstrate.

      AddType application/x-httpd-php .php .phtml

    It's also common to setup the .phps extension to show highlighted PHP
    source, this can be done with:
    
      AddType application/x-httpd-php-source .phps

17. Use your normal procedure for starting the Apache server. (You must
    stop and restart the server, not just cause the server to reload by
    using a HUP or USR1 signal.)

Alternatively, to install PHP as a static object:

Przykład 4-2. Installation Instructions (Static Module Installation for Apache) for PHP

1.  gunzip -c apache_1.3.x.tar.gz | tar xf -
2.  cd apache_1.3.x
3.  ./configure
4.  cd ..

5.  gunzip -c php-5.x.y.tar.gz | tar xf -
6.  cd php-5.x.y
7.  ./configure --with-mysql --with-apache=../apache_1.3.x
8.  make
9.  make install

10. cd ../apache_1.3.x

11. ./configure --prefix=/www --activate-module=src/modules/php5/libphp5.a
    (The above line is correct! Yes, we know libphp5.a does not exist at this
    stage. It isn't supposed to. It will be created.)

12. make
    (you should now have an httpd binary which you can copy to your Apache bin dir if
    it is your first install then you need to "make install" as well)

13. cd ../php-5.x.y
14. cp php.ini-dist /usr/local/lib/php.ini

15. You can edit /usr/local/lib/php.ini file to set PHP options.
    Edit your httpd.conf or srm.conf file and add:
    AddType application/x-httpd-php .php

Notatka: Replace php-5 by php-4 and php5 by php4 in PHP 4.

Depending on your Apache install and Unix variant, there are many possible ways to stop and restart the server. Below are some typical lines used in restarting the server, for different apache/unix installations. You should replace /path/to/ with the path to these applications on your systems.

Przykład 4-3. Example commands for restarting Apache

1. Several Linux and SysV variants:
/etc/rc.d/init.d/httpd restart

2. Using apachectl scripts:
/path/to/apachectl stop
/path/to/apachectl start

3. httpdctl and httpsdctl (Using OpenSSL), similar to apachectl:
/path/to/httpsdctl stop
/path/to/httpsdctl start

4. Using mod_ssl, or another SSL server, you may want to manually
stop and start:
/path/to/apachectl stop
/path/to/apachectl startssl

The locations of the apachectl and http(s)dctl binaries often vary. If your system has locate or whereis or which commands, these can assist you in finding your server control programs.

Different examples of compiling PHP for apache are as follows:

./configure --with-apxs --with-pgsql

This will create a libphp5.so (or libphp4.so in PHP 4) shared library that is loaded into Apache using a LoadModule line in Apache's httpd.conf file. The PostgreSQL support is embedded into this library.

./configure --with-apxs --with-pgsql=shared

This will create a libphp4.so shared library for Apache, but it will also create a pgsql.so shared library that is loaded into PHP either by using the extension directive in php.ini file or by loading it explicitly in a script using the dl() function.

./configure --with-apache=/path/to/apache_source --with-pgsql

This will create a libmodphp5.a library, a mod_php5.c and some accompanying files and copy this into the src/modules/php5 directory in the Apache source tree. Then you compile Apache using --activate-module=src/modules/php5/libphp5.a and the Apache build system will create libphp5.a and link it statically into the httpd binary (replace php5 by php4 in PHP 4). The PostgreSQL support is included directly into this httpd binary, so the final result here is a single httpd binary that includes all of Apache and all of PHP.

./configure --with-apache=/path/to/apache_source --with-pgsql=shared

Same as before, except instead of including PostgreSQL support directly into the final httpd you will get a pgsql.so shared library that you can load into PHP from either the php.ini file or directly using dl().

When choosing to build PHP in different ways, you should consider the advantages and drawbacks of each method. Building as a shared object will mean that you can compile apache separately, and don't have to recompile everything as you add to, or change, PHP. Building PHP into apache (static method) means that PHP will load and run faster. For more information, see the Apache webpage on DSO support.

Notatka: Apache's default httpd.conf currently ships with a section that looks like this:

User nobody
Group "#-1"

Unless you change that to "Group nogroup" or something like that ("Group daemon" is also very common) PHP will not be able to open files.

Notatka: Make sure you specify the installed version of apxs when using --with-apxs=/path/to/apxs. You must NOT use the apxs version that is in the apache sources but the one that is actually installed on your system.


Apache 2.0 on Unix systems

This section contains notes and hints specific to Apache 2.0 installs of PHP on Unix systems.

Ostrzeżenie

Nie zalecamy korzystania z wątkowanego MPM na produkcyjnych serwerach Apache2. Zamiast niego wskazane jest używanie preforkowanego MPM, lub używanie Apache1. Wyjaśnienie powodów można znaleźć w odpowiednim punkcie FAQ, dotyczącym używania Apache2 z wątkowanym MPM

You are highly encouraged to take a look at the Apache Documentation to get a basic understanding of the Apache 2.0 Server.

PHP and Apache 2.0.x compatibility notes: The following versions of PHP are known to work with the most recent version of Apache 2.0.x:

These versions of PHP are compatible to Apache 2.0.40 and later.

Apache 2.0 SAPI-support started with PHP 4.2.0. PHP 4.2.3 works with Apache 2.0.39, don't use any other version of Apache with PHP 4.2.3. However, the recommended setup is to use PHP 4.3.0 or later with the most recent version of Apache2.

All mentioned versions of PHP will work still with Apache 1.3.x.

Download the most recent version of Apache 2.0 and a fitting PHP version from the above mentioned places. This quick guide covers only the basics to get started with Apache 2.0 and PHP. For more information read the Apache Documentation. The version numbers have been omitted here, to ensure the instructions are not incorrect. You will need to replace the 'NN' here with the correct values from your files.

Przykład 4-4. Installation Instructions (Apache 2 Shared Module Version)

1.  gzip -d httpd-2_0_NN.tar.gz
2.  tar xvf httpd-2_0_NN.tar
3.  gunzip php-NN.tar.gz
4.  tar -xvf php-NN.tar
5.  cd httpd-2_0_NN
6.  ./configure --enable-so
7.  make
8.  make install

    Now you have Apache 2.0.NN available under /usr/local/apache2,
    configured with loadable module support and the standard MPM prefork.
    To test the installation use your normal procedure for starting
    the Apache server, e.g.:
    /usr/local/apache2/bin/apachectl start
    and stop the server to go on with the configuration for PHP:
    /usr/local/apache2/bin/apachectl stop.

9.  cd ../php-NN

10. Now, configure your PHP.  This is where you customize your PHP
    with various options, like which extensions will be enabled.  Do a
    ./configure --help for a list of available options.  In our example
    we'll do a simple configure with Apache 2 and MySQL support.  Your
    path to apxs may differ, in fact, the binary may even be named apxs2 on
    your system. 
    
      ./configure --with-apxs2=/usr/local/apache2/bin/apxs --with-mysql

11. make
12. make install

    If you decide to change your configure options after installation,
    you only need to repeat the last three steps. You only need to
    restart apache for the new module to take effect. A recompile of
    Apache is not needed.
                
    Note that unless told otherwise, 'make install' will also install PEAR,
    various PHP tools such as phpize, install the PHP CLI, and more.
    
13. Setup your php.ini 
    
    cp php.ini-dist /usr/local/lib/php.ini
          
    You may edit your .ini file to set PHP options.  If you prefer having
    php.ini in another location, use --with-config-file-path=/some/path in
    step 10.
    
    If you instead choose php.ini-recommended, be certain to read the list
    of changes within, as they affect how PHP behaves.

14. Edit your httpd.conf to load the PHP module.  The path on the right hand
    side of the LoadModule statement must point to the path of the PHP
    module on your system.  The make install from above may have already
    added this for you, but be sure to check.

    For PHP 4:
  
      LoadModule php4_module modules/libphp4.so
      
    For PHP 5:
    
      LoadModule php5_module modules/libphp5.so
 
15. Tell Apache to parse certain extensions as PHP.  For example,
    let's have Apache parse the .php extension as PHP.  You could
    have any extension(s) parse as PHP by simply adding more, with
    each separated by a space.  We'll add .phtml to demonstrate.
            
      AddType application/x-httpd-php .php .phtml
                  
    It's also common to setup the .phps extension to show highlighted PHP
    source, this can be done with:
    
      AddType application/x-httpd-php-source .phps
 
16. Use your normal procedure for starting the Apache server, e.g.:
   
      /usr/local/apache2/bin/apachectl start

Following the steps above you will have a running Apache 2.0 with support for PHP as SAPI module. Of course there are many more configuration options available for both, Apache and PHP. For more information use ./configure --help in the corresponding source tree. In case you wish to build a multithreaded version of Apache 2.0 you must overwrite the standard MPM-Module prefork either with worker or perchild. To do so append to your configure line in step 6 above either the option --with-mpm=worker or --with-mpm=perchild. Take care about the consequences and understand what you are doing. For more information read the Apache documentation about the MPM-Modules.

Notatka: If you want to use content negotiation, read the Apache MultiViews FAQ.

Notatka: To build a multithreaded version of Apache your system must support threads. This also implies to build PHP with experimental Zend Thread Safety (ZTS). Therefore not all extensions might be available. The recommended setup is to build Apache with the standard prefork MPM-Module.


Caudium

PHP 4 can be built as a Pike module for the Caudium webserver. Note that this is not supported with PHP 3. Follow the simple instructions below to install PHP 4 for Caudium.

Przykład 4-5. Caudium Installation Instructions

1.  Make sure you have Caudium installed prior to attempting to
    install PHP 4. For PHP 4 to work correctly, you will need Pike
    7.0.268 or newer. For the sake of this example we assume that
    Caudium is installed in /opt/caudium/server/.
2.  Change directory to php-x.y.z (where x.y.z is the version number).
3.  ./configure --with-caudium=/opt/caudium/server
4.  make
5.  make install
6.  Restart Caudium if it's currently running.
7.  Log into the graphical configuration interface and go to the
    virtual server where you want to add PHP 4 support.
8.  Click Add Module and locate and then add the PHP 4 Script Support module.
9.  If the documentation says that the 'PHP 4 interpreter isn't
    available', make sure that you restarted the server. If you did
    check /opt/caudium/logs/debug/default.1 for any errors related to
    <filename>PHP4.so</filename>. Also make sure that 
    <filename>caudium/server/lib/[pike-version]/PHP4.so</filename>
    is present.
10. Configure the PHP Script Support module if needed.

You can of course compile your Caudium module with support for the various extensions available in PHP 4. See the reference pages for extension specific configure options.

Notatka: When compiling PHP 4 with MySQL support you must make sure that the normal MySQL client code is used. Otherwise there might be conflicts if your Pike already has MySQL support. You do this by specifying a MySQL install directory the --with-mysql option.


fhttpd related notes

To build PHP as an fhttpd module, answer "yes" to "Build as an fhttpd module?" (the --with-fhttpd=DIR option to configure) and specify the fhttpd source base directory. The default directory is /usr/local/src/fhttpd. If you are running fhttpd, building PHP as a module will give better performance, more control and remote execution capability.

Notatka: Support for fhttpd is no longer available as of PHP 4.3.0.


Sun, iPlanet and Netscape servers on Sun Solaris

This section contains notes and hints specific to Sun Java System Web Server, Sun ONE Web Server, iPlanet and Netscape server installs of PHP on Sun Solaris.

From PHP 4.3.3 on you can use PHP scripts with the NSAPI module to generate custom directory listings and error pages. Additional functions for Apache compatibility are also available. For support in current webservers read the note about subrequests.

You can find more information about setting up PHP for the Netscape Enterprise Server (NES) here: http://benoit.noss.free.fr/php/install-php4.html

To build PHP with Sun JSWS/Sun ONE WS/iPlanet/Netscape webservers, enter the proper install directory for the --with-nsapi=[DIR] option. The default directory is usually /opt/netscape/suitespot/. Please also read /php-xxx-version/sapi/nsapi/nsapi-readme.txt.

  1. Install the following packages from http://www.sunfreeware.com/ or another download site:

    autoconf-2.13
    automake-1.4
    bison-1_25-sol26-sparc-local
    flex-2_5_4a-sol26-sparc-local
    gcc-2_95_2-sol26-sparc-local
    gzip-1.2.4-sol26-sparc-local
    m4-1_4-sol26-sparc-local
    make-3_76_1-sol26-sparc-local
    mysql-3.23.24-beta (if you want mysql support)
    perl-5_005_03-sol26-sparc-local
    tar-1.13 (GNU tar)

  2. Make sure your path includes the proper directories PATH=.:/usr/local/bin:/usr/sbin:/usr/bin:/usr/ccs/bin and make it available to your system export PATH.

  3. gunzip php-x.x.x.tar.gz (if you have a .gz dist, otherwise go to 4).

  4. tar xvf php-x.x.x.tar

  5. Change to your extracted PHP directory: cd ../php-x.x.x

  6. For the following step, make sure /opt/netscape/suitespot/ is where your netscape server is installed. Otherwise, change to the correct path and run:
    ./configure --with-mysql=/usr/local/mysql \
    --with-nsapi=/opt/netscape/suitespot/ \
    --enable-libgcc

  7. Run make followed by make install.

After performing the base install and reading the appropriate readme file, you may need to perform some additional configuration steps.

Configuration Instructions for Sun/iPlanet/Netscape. Firstly you may need to add some paths to the LD_LIBRARY_PATH environment for the server to find all the shared libs. This can best done in the start script for your webserver. The start script is often located in: /path/to/server/https-servername/start. You may also need to edit the configuration files that are located in: /path/to/server/https-servername/config/.

  1. Add the following line to mime.types (you can do that by the administration server):
    type=magnus-internal/x-httpd-php exts=php

  2. Edit magnus.conf (for servers >= 6) or obj.conf (for servers < 6) and add the following, shlib will vary depending on your system, it will be something like /opt/netscape/suitespot/bin/libphp4.so. You should place the following lines after mime types init.
    Init fn="load-modules" funcs="php4_init,php4_execute,php4_auth_trans" shlib="/opt/netscape/suitespot/bin/libphp4.so"
    Init fn="php4_init" LateInit="yes" errorString="Failed to initialize PHP!" [php_ini="/path/to/php.ini"]
    (PHP >= 4.3.3) The php_ini parameter is optional but with it you can place your php.ini in your webserver config directory.

  3. Configure the default object in obj.conf (for virtual server classes [version 6.0+] in their vserver.obj.conf):
    <Object name="default">
    .
    .
    .
    .#NOTE this next line should happen after all 'ObjectType' and before all 'AddLog' lines
    Service fn="php4_execute" type="magnus-internal/x-httpd-php" [inikey=value inikey=value ...]
    .
    .
    </Object>
    (PHP >= 4.3.3) As additional parameters you can add some special php.ini-values, for example you can set a docroot="/path/to/docroot" specific to the context php4_execute is called. For boolean ini-keys please use 0/1 as value, not "On","Off",... (this will not work correctly), e.g. zlib.output_compression=1 instead of zlib.output_compression="On"

  4. This is only needed if you want to configure a directory that only consists of PHP scripts (same like a cgi-bin directory):
    <Object name="x-httpd-php">
    ObjectType fn="force-type" type="magnus-internal/x-httpd-php"
    Service fn=php4_execute [inikey=value inikey=value ...]
    </Object>
    After that you can configure a directory in the Administration server and assign it the style x-httpd-php. All files in it will get executed as PHP. This is nice to hide PHP usage by renaming files to .html.

  5. Setup of authentication: PHP authentication cannot be used with any other authentication. ALL AUTHENTICATION IS PASSED TO YOUR PHP SCRIPT. To configure PHP Authentication for the entire server, add the following line to your default object:
    <Object name="default">
    AuthTrans fn=php4_auth_trans
    .
    .
    .
    </Object>

  6. To use PHP Authentication on a single directory, add the following:
    <Object ppath="d:\path\to\authenticated\dir\*">
    AuthTrans fn=php4_auth_trans
    </Object>

Notatka: The stacksize that PHP uses depends on the configuration of the webserver. If you get crashes with very large PHP scripts, it is recommended to raise it with the Admin Server (in the section "MAGNUS EDITOR").


CGI environment and recommended modifications in php.ini

Important when writing PHP scripts is the fact that Sun JSWS/Sun ONE WS/iPlanet/Netscape is a multithreaded web server. Because of that all requests are running in the same process space (the space of the webserver itself) and this space has only one environment. If you want to get CGI variables like PATH_INFO, HTTP_HOST etc. it is not the correct way to try this in the old PHP 3.x way with getenv() or a similar way (register globals to environment, $_ENV). You would only get the environment of the running webserver without any valid CGI variables!

Notatka: Why are there (invalid) CGI variables in the environment?

Answer: This is because you started the webserver process from the admin server which runs the startup script of the webserver, you wanted to start, as a CGI script (a CGI script inside of the admin server!). This is why the environment of the started webserver has some CGI environment variables in it. You can test this by starting the webserver not from the administration server. Use the command line as root user and start it manually - you will see there are no CGI-like environment variables.

Simply change your scripts to get CGI variables in the correct way for PHP 4.x by using the superglobal $_SERVER. If you have older scripts which use $HTTP_HOST, etc., you should turn on register_globals in php.ini and change the variable order too (important: remove "E" from it, because you do not need the environment here):
variables_order = "GPCS"
register_globals = On


Special use for error pages or self-made directory listings (PHP >= 4.3.3)

You can use PHP to generate the error pages for "404 Not Found" or similar. Add the following line to the object in obj.conf for every error page you want to overwrite:
Error fn="php4_execute" code=XXX script="/path/to/script.php" [inikey=value inikey=value...]
where XXX is the HTTP error code. Please delete any other Error directives which could interfere with yours. If you want to place a page for all errors that could exist, leave the code parameter out. Your script can get the HTTP status code with $_SERVER['ERROR_TYPE'].

Another possibility is to generate self-made directory listings. Just create a PHP script which displays a directory listing and replace the corresponding default Service line for type="magnus-internal/directory" in obj.conf with the following:
Service fn="php4_execute" type="magnus-internal/directory" script="/path/to/script.php" [inikey=value inikey=value...]
For both error and directory listing pages the original URI and translated URI are in the variables $_SERVER['PATH_INFO'] and $_SERVER['PATH_TRANSLATED'].


Note about nsapi_virtual() and subrequests (PHP >= 4.3.3)

The NSAPI module now supports the nsapi_virtual() function (alias: virtual()) to make subrequests on the webserver and insert the result in the webpage. This function uses some undocumented features from the NSAPI library. On Unix the module automatically looks for the needed functions and uses them if available. If not, nsapi_virtual() is disabled.

Notatka: But be warned: Support for nsapi_virtual() is EXPERIMENTAL!!!


CGI and commandline setups

The default is to build PHP as a CGI program. This creates a commandline interpreter, which can be used for CGI processing, or for non-web-related PHP scripting. If you are running a web server PHP has module support for, you should generally go for that solution for performance reasons. However, the CGI version enables users to run different PHP-enabled pages under different user-ids.

Ostrzeżenie

Używając instalacji CGI, serwer jest podatny na wiele potencjalnych ataków. Sposoby obrony przed nimi zostały opisane w rozdziale o bezpieczeństwie instalacji CGI.

As of PHP 4.3.0, some important additions have happened to PHP. A new SAPI named CLI also exists and it has the same name as the CGI binary. What is installed at {PREFIX}/bin/php depends on your configure line and this is described in detail in the manual section named Using PHP from the command line. For further details please read that section of the manual.


Testing

If you have built PHP as a CGI program, you may test your build by typing make test. It is always a good idea to test your build. This way you may catch a problem with PHP on your platform early instead of having to struggle with it later.


Benchmarking

If you have built PHP 3 as a CGI program, you may benchmark your build by typing make bench. Note that if tryb bezpieczny is on by default, the benchmark may not be able to finish if it takes longer then the 30 seconds allowed. This is because the set_time_limit() can not be used in tryb bezpieczny. Use the max_execution_time configuration setting to control this time for your own scripts. make bench ignores the configuration file.

Notatka: make bench is only available for PHP 3.


Using Variables

Some server supplied environment variables are not defined in the current CGI/1.1 specification. Only the following variables are defined there: AUTH_TYPE, CONTENT_LENGTH, CONTENT_TYPE, GATEWAY_INTERFACE, PATH_INFO, PATH_TRANSLATED, QUERY_STRING, REMOTE_ADDR, REMOTE_HOST, REMOTE_IDENT, REMOTE_USER, REQUEST_METHOD, SCRIPT_NAME, SERVER_NAME, SERVER_PORT, SERVER_PROTOCOL, and SERVER_SOFTWARE. Everything else should be treated as 'vendor extensions'.


HP-UX specific installation notes

This section contains notes and hints specific to installing PHP on HP-UX systems. (Contributed by paul_mckay at clearwater-it dot co dot uk).

Notatka: These tips were written for PHP 4.0.4 and Apache 1.3.9.

  1. You need gzip, download a binary distribution from http://hpux.connect.org.uk/ftp/hpux/Gnu/gzip-1.2.4a/gzip-1.2.4a-sd-10.20.depot.Z uncompress the file and install using swinstall.

  2. You need gcc, download a binary distribution from http://gatekeep.cs.utah.edu/ftp/hpux/Gnu/gcc-2.95.2/gcc-2.95.2-sd-10.20.depot.gz. uncompress this file and install gcc using swinstall.

  3. You need the GNU binutils, you can download a binary distribution from http://hpux.connect.org.uk/ftp/hpux/Gnu/binutils-2.9.1/binutils-2.9.1-sd-10.20.depot.gz. uncompress this file and install binutils using swinstall.

  4. You now need bison, you can download a binary distribution from http://hpux.connect.org.uk/ftp/hpux/Gnu/bison-1.28/bison-1.28-sd-10.20.depot.gz, install as above.

  5. You now need flex, you need to download the source from one of the http://www.gnu.org mirrors. It is in the non-gnu directory of the ftp site. Download the file, gunzip, then tar -xvf it. Go into the newly created flex directory and run ./configure, followed by make, and then make install.

    If you have errors here, it's probably because gcc etc. are not in your PATH so add them to your PATH.

  6. Download the PHP and apache sources.

  7. gunzip and tar -xvf them. We need to hack a couple of files so that they can compile OK.

  8. Firstly the configure file needs to be hacked because it seems to lose track of the fact that you are a hpux machine, there will be a better way of doing this but a cheap and cheerful hack is to put lt_target=hpux10.20 on line 47286 of the configure script.

  9. Next, the Apache GuessOS file needs to be hacked. Under apache_1.3.9/src/helpers change line 89 from echo "hp${HPUXMACH}-hpux${HPUXVER}"; exit 0 to: echo "hp${HPUXMACH}-hp-hpux${HPUXVER}"; exit 0

  10. You cannot install PHP as a shared object under HP-UX so you must compile it as a static, just follow the instructions at the Apache page.

  11. PHP and Apache should have compiled OK, but Apache won't start. you need to create a new user for Apache, e.g. www, or apache. You then change lines 252 and 253 of the conf/httpd.conf in Apache so that instead of

    User nobody 
    Group nogroup

    you have something like

    User www 
    Group sys

    This is because you can't run Apache as nobody under hp-ux. Apache and PHP should then work.


OpenBSD installation notes

This section contains notes and hints specific to installing PHP on OpenBSD 3.6.


Using Binary Packages

Using binary packages to install PHP on OpenBSD is the recommended and simplest method. The core package has been separated from the various modules, and each can be installed and removed independently from the others. The files you need can be found on your OpenBSD CD or on the FTP site.

The main package you need to install is php4-core-4.3.8.tgz, which contains the basic engine (plus gettext and iconv). Next, take a look at the module packages, such as php4-mysql-4.3.8.tgz or php4-imap-4.3.8.tgz. You need to use the phpxs command to activate and deactivate these modules in your php.ini.

Przykład 4-6. OpenBSD Package Install Example

# pkg_add php4-core-4.3.8.tgz
# /usr/local/sbin/phpxs -s
# cp /usr/local/share/doc/php4/php.ini-recommended /var/www/conf/php.ini
  (add in mysql)
# pkg_add php4-mysql-4.3.8.tgz
# /usr/local/sbin/phpxs -a mysql
  (add in imap)
# pkg_add php4-imap-4.3.8.tgz
# /usr/local/sbin/phpxs -a imap
  (remove mysql as a test)
# pkg_delete php4-mysql-4.3.8
# /usr/local/sbin/phpxs -r mysql
  (install the PEAR libraries)
# pkg_add php4-pear-4.3.8.tgz

Read the packages(7) manual page for more information about binary packages on OpenBSD.


Using Ports

You can also compile up PHP from source using the ports tree. However, this is only recommended for users familiar with OpenBSD. The PHP 4 port is split into two sub-directories: core and extensions. The extensions directory generates sub-packages for all of the supported PHP modules. If you find you do not want to create some of these modules, use the no_* FLAVOR. For example, to skip building the imap module, set the FLAVOR to no_imap.


Common Problems

  • The default install of Apache runs inside a chroot(2) jail, which will restrict PHP scripts to accessing files under /var/www. You will therefore need to create a /var/www/tmp directory for PHP session files to be stored, or use an alternative session backend. In addition, database sockets need to be placed inside the jail or listen on the localhost interface. If you use network functions, some files from /etc such as /etc/resolv.conf and /etc/services will need to be moved into /var/www/etc. The OpenBSD PEAR package automatically installs into the correct chroot directories, so no special modification is needed there. More information on the OpenBSD Apache is available in the OpenBSD FAQ.

  • The OpenBSD 3.6 package for the gd extension requires XFree86 to be installed. If you do not wish to use some of the font features that require X11, install the php4-gd-4.3.8-no_x11.tgz package instead.


Older Releases

Older releases of OpenBSD used the FLAVORS system to compile up a statically linked PHP. Since it is hard to generate binary packages using this method, it is now deprecated. You can still use the old stable ports trees if you wish, but they are unsupported by the OpenBSD team. If you have any comments about this, the current maintainer for the port is Anil Madhavapeddy (avsm at openbsd dot org).


Solaris specific installation tips

This section contains notes and hints specific to installing PHP on Solaris systems.


Required software

Solaris installs often lack C compilers and their related tools. Read this FAQ for information on why using GNU versions for some of these tools is necessary. The required software is as follows:

  • gcc (recommended, other C compilers may work)

  • make

  • flex

  • bison

  • m4

  • autoconf

  • automake

  • perl

  • gzip

  • tar

  • GNU sed

In addition, you will need to install (and possibly compile) any additional software specific to your configuration, such as Oracle or MySQL.


Using Packages

You can simplify the Solaris install process by using pkgadd to install most of your needed components.


Debian GNU/Linux installation notes

This section contains notes and hints specific to installing PHP on Debian GNU/Linux.


Using APT

While you can just download the PHP source and compile it yourself, using Debian's packaging system is the simplest and cleanest method of installing PHP. If you are not familiar with building software on Linux, this is the way to go.

The first decision you need to make is whether you want to install Apache 1.3.x or Apache 2.x. The corresponding PHP packages are respectively named libapache-mod-php* and libapache2-mod-php*. The steps given below will use Apache 1.3.x. Please note that, as of this writing, there is no official Debian packages of PHP 5. Then the steps given below will install PHP 4.

PHP is available in Debian as CGI or CLI flavour too, named respectively php4-cgi and php4-cli. If you need them, you'll just have to reproduce the following steps with the good package names. Another special package you'd want to install is php4-pear. It contains a minimal PEAR installation and the pear commandline utility.

If you need more recent packages of PHP than the Debian's stable ones or if some PHP modules lacks the Debian official repository, perhaps you should take a look at http://www.apt-get.org/. One of the results found should be Dotdeb. This unofficial repository is maintained by Guillaume Plessis and contains Debian packages of the most recent versions of PHP 4 and PHP 5. To use it, just add the to following two lines to your /etc/apt/sources.lists and run apt-get update :

Przykład 4-7. The two Dotdeb related lines

deb http://packages.dotdeb.org stable all
deb-src http://packages.dotdeb.org stable all

The last thing to consider is whether your list of packages is up to date. If you have not updated it recently, you need to run apt-get update before anything else. This way, you will be using the most recent stable version of the Apache and PHP packages.

Now that everything is in place, you can use the following example to install Apache and PHP:

Przykład 4-8. Debian Install Example with Apache 1.3

# apt-get install libapache-mod-php4

APT will automatically install the PHP 4 module for Apache 1.3, and all its dependencies and then activate it. If you're not asked to restart Apache during the install process, you'll have to do it manually :

Przykład 4-9. Stopping and starting Apache once PHP 4 is installed

# /etc/init.d/apache stop
# /etc/init.d/apache start

Better control on configuration

In the last section, PHP was installed with only core modules. This may not be what you want and you will soon discover that you need more activated modules, like MySQL, cURL, GD, etc.

When you compile PHP from source yourself, you need to activate modules via the configure command. With APT, you just have to install additional packages. They're all named 'php4-*' (or 'php5-*' if you installed PHP 5 from a third party repository).

Przykład 4-10. Getting the list of PHP additional packages

# dpkg -l 'php4-*'

As you can see from the last output, there's a lot of PHP modules that you can install (excluding the php4-cgi, php4-cli or php4-pear special packages). Look at them closely and choose what you need. If you choose a module and you do not have the proper libraries, APT will automatically install all the dependencies for you.

If you choose to add the MySQL, cURL and GD support to PHP the command will look something like this:

Przykład 4-11. Install PHP with MySQL, cURL and GD

# apt-get install php4-mysql php4-curl php4-gd

APT will automatically add the appropriate lines to your different php.ini (/etc/php4/apache/php.ini, /etc/php4/cgi/php.ini, etc).

Przykład 4-12. These lines activate MySQL, cURL and GD into PHP

extension=mysql.so
extension=curl.so
extension=gd.so

You'll only have to stop/start Apache as previously to activate the modules.


Common Problems

  • If you see the PHP source instead of the result the script should produce, APT has probably not included /etc/apache/conf.d/php4 in your Apache 1.3 configuration. Please ensure that the following line is present in your /etc/apache/httpd.conf file then stop/start Apache:

    Przykład 4-13. This line activates PHP 4 into Apache

    # Include /etc/apache/conf.d/
  • If you installed an additional module and if its functions are not available in your scripts, please ensure that the appropriate line is present in your php.ini, as seen before. APT may fail during the installation of the additional module, due to a confusing debconf configuration.


Rozdział 5. Installation on Mac OS X

This section contains notes and hints specific to installing PHP on Mac OS X. There are two slightly different versions of Mac OS X, Client and Server, our manual deals with installing PHP on both systems. Note that PHP is not available for MacOS 9 and earlier versions.


Using Packages

There are a few pre-packaged and pre-compiled versions of PHP for Mac OS X. This can help in setting up a standard configuration, but if you need to have a different set of features (such as a secure server, or a different database driver), you may need to build PHP and/or your web server yourself. If you are unfamiliar with building and compiling your own software, it's worth checking whether somebody has already built a packaged version of PHP with the features you need.


Compiling for OS X Server

Mac OS X Server install.

  1. Get the latest distributions of Apache and PHP.

  2. Untar them, and run the configure program on Apache like so.
    ./configure --exec-prefix=/usr \
    --localstatedir=/var \
    --mandir=/usr/share/man \
    --libexecdir=/System/Library/Apache/Modules \
    --iconsdir=/System/Library/Apache/Icons \
    --includedir=/System/Library/Frameworks/Apache.framework/Versions/1.3/Headers \
    --enable-shared=max \
    --enable-module=most \
    --target=apache

  3. If you want the compiler to do some optimization, you may also want to add this line:
    setenv OPTIM=-O2

  4. Next, go to the PHP 4 source directory and configure it.
    ./configure --prefix=/usr \
        --sysconfdir=/etc \
        --localstatedir=/var \
        --mandir=/usr/share/man \
        --with-xml \
        --with-apache=/src/apache_1.3.12
    If you have any other additions (MySQL, GD, etc.), be sure to add them here. For the --with-apache string, put in the path to your apache source directory, for example /src/apache_1.3.12.

  5. Type make and make install. This will add a directory to your Apache source directory under src/modules/php4.

  6. Now, reconfigure Apache to build in PHP 4.
    ./configure --exec-prefix=/usr \
    --localstatedir=/var \
    --mandir=/usr/share/man \
    --libexecdir=/System/Library/Apache/Modules \
    --iconsdir=/System/Library/Apache/Icons \
    --includedir=/System/Library/Frameworks/Apache.framework/Versions/1.3/Headers \
    --enable-shared=max \
    --enable-module=most \
    --target=apache \
    --activate-module=src/modules/php4/libphp4.a
    You may get a message telling you that libmodphp4.a is out of date. If so, go to the src/modules/php4 directory inside your Apache source directory and run this command: ranlib libmodphp4.a. Then go back to the root of the Apache source directory and run the above configure command again. That'll bring the link table up to date. Run make and make install again.

  7. Copy and rename the php.ini-dist file to your bin directory from your PHP 4 source directory: cp php.ini-dist /usr/local/bin/php.ini or (if your don't have a local directory) cp php.ini-dist /usr/bin/php.ini.


Compiling for MacOS X Client

The following instructions will help you install a PHP module for the Apache web server included in MacOS X. This version includes support for the MySQL and PostgreSQL databases. These instructions are graciously provided by Marc Liyanage.

Ostrzeżenie

Be careful when you do this, you could screw up your Apache web server!

Do this to install:

  1. Open a terminal window.

  2. Type wget http://www.diax.ch/users/liyanage/software/macosx/libphp4.so.gz, wait for the download to finish.

  3. Type gunzip libphp4.so.gz.

  4. Type sudo apxs -i -a -n php4 libphp4.so

  5. Now type sudo open -a TextEdit /etc/httpd/httpd.conf. TextEdit will open with the web server configuration file. Locate these two lines towards the end of the file: (Use the Find command)
    #AddType application/x-httpd-php .php 
    #AddType application/x-httpd-php-source .phps
    Remove the two hash marks (#), then save the file and quit TextEdit.

  6. Finally, type sudo apachectl graceful to restart the web server.

PHP should now be up and running. You can test it by dropping a file into your Sites folder which is called test.php. Into that file, write this line: <?php phpinfo() ?>.

Now open up 127.0.0.1/~your_username/test.php in your web browser. You should see a status table with information about the PHP module.


Rozdział 6. Installation on Windows systems

This section applies to Windows 98/Me and Windows NT/2000/XP/2003. PHP will not work on 16 bit platforms such as Windows 3.1 and sometimes we refer to the supported Windows platforms as Win32. Windows 95 is no longer supported as of PHP 4.3.0.

There are two main ways to install PHP for Windows: either manually or by using the installer.

If you have Microsoft Visual Studio, you can also build PHP from the original source code.

Once you have PHP installed on your Windows system, you may also want to load various extensions for added functionality.

Ostrzeżenie

There are several all-in-one installers over the Internet, but none of those are endorsed by PHP.net, as we believe that the manual installation is the best choice to have your system secure and optimised.


Windows Installer

The Windows PHP installer is available from the downloads page at http://www.php.net/downloads.php. This installs the CGI version of PHP and for IIS, PWS, and Xitami, it configures the web server as well. The installer does not include any extra external PHP extensions (php_*.dll) as you'll only find those in the Windows Zip Package and PECL downloads.

Notatka: While the Windows installer is an easy way to make PHP work, it is restricted in many aspects as, for example, the automatic setup of extensions is not supported. Use of the installer isn't the preferred method for installing PHP.

First, install your selected HTTP (web) server on your system, and make sure that it works.

Run the executable installer and follow the instructions provided by the installation wizard. Two types of installation are supported - standard, which provides sensible defaults for all the settings it can, and advanced, which asks questions as it goes along.

The installation wizard gathers enough information to set up the php.ini file, and configure certain web servers to use PHP. One of the web servers the PHP installer does not configure for is Apache, so you'll need to configure it manually.

Once the installation has completed, the installer will inform you if you need to restart your system, restart the server, or just start using PHP.

Ostrzeżenie

Be aware, that this setup of PHP is not secure. If you would like to have a secure PHP setup, you'd better go on the manual way, and set every option carefully. This automatically working setup gives you an instantly working PHP installation, but it is not meant to be used on online servers.


Manual Installation Steps

This install guide will help you manually install and configure PHP with a web server on Microsoft Windows. To get started you'll need to download the zip binary distribution from the downloads page at http://www.php.net/downloads.php.

Although there are many all-in-one installation kits, and we also distribute a PHP installer for Microsoft Windows, we recommend you take the time to setup PHP yourself as this will provide you with a better understanding of the system, and enables you to install PHP extensions easily when needed.

Upgrading from a previous PHP version: Previous editions of the manual suggest moving various ini and DLL files into your SYSTEM (i.e. C:\WINDOWS) folder and while this simplifies the installation procedure it makes upgrading difficult. We advise you remove all of these files (like php.ini and PHP related DLLs from the Windows SYSTEM folder) before moving on with a new PHP installation. Be sure to backup these files as you might break the entire system. The old php.ini might be useful in setting up the new PHP as well. And as you'll soon learn, the preferred method for installing PHP is to keep all PHP related files in one directory and have this directory available to your systems PATH.

MDAC requirements: If you use Microsoft Windows 98/NT4 download the latest version of the Microsoft Data Access Components (MDAC) for your platform. MDAC is available at http://msdn.microsoft.com/data/. This requirement exists because ODBC is built into the distributed Windows binaries.

The following steps should be completed on all installations before any server specific instructions are performed:

Extract the distribution file into a directory of your choice. If you are installing PHP 4, extract to C:\, as the zip file expands to a foldername like php-4.3.7-Win32. If you are installing PHP 5, extract to C:\php as the zip file doesn't expand as in PHP 4. You may choose a different location but do not have spaces in the path (like C:\Program Files\PHP) as some web servers will crash if you do.

The directory structure extracted from the zip is different for PHP versions 4 and 5 and look like as follows:

Przykład 6-1. PHP 4 package structure

c:\php
   |
   +--cli
   |  |
   |  |-php.exe           -- CLI executable - ONLY for commandline scripting
   |
   +--dlls                -- support DLLs required by some extensions
   |  |
   |  |-expat.dll
   |  |
   |  |-fdftk.dll
   |  |
   |  |-...
   |
   +--extensions          -- extension DLLs for PHP
   |  |
   |  |-php_bz2.dll
   |  |
   |  |-php_cpdf.dll
   |  |
   |  |-..
   |
   +--mibs                -- support files for SNMP
   |
   +--openssl             -- support files for Openssl
   |
   +--pdf-related         -- support files for PDF
   |
   +--sapi                -- SAPI (server module support) DLLs
   |  |
   |  |-php4apache.dll
   |  |
   |  |-php4apache2.dll
   |  |
   |  |-..
   |
   +--PEAR                -- initial copy of PEAR
   |
   |
   |-go-pear.bat          -- PEAR setup script
   |
   |-..
   |
   |-php.exe              -- CGI executable
   |
   |-..
   |
   |-php.ini-dist         -- default php.ini settings
   |
   |-php.ini-recommended  -- recommended php.ini settings
   | 
   |-php4ts.dll           -- core PHP DLL
   | 
   |-...

Or:

Przykład 6-2. PHP 5 package structure

c:\php
   |
   +--dev
   |  |
   |  |-php5ts.lib
   |
   +--ext                 -- extension DLLs for PHP
   |  |
   |  |-php_bz2.dll
   |  |
   |  |-php_cpdf.dll
   |  |
   |  |-..
   |
   +--extras
   |  |
   |  +--mibs             -- support files for SNMP
   |  |
   |  +--openssl          -- support files for Openssl
   |  |
   |  +--pdf-related      -- support files for PDF
   |  |
   |  |-mime.magic
   |
   +--pear                -- initial copy of PEAR
   |
   |
   |-go-pear.bat          -- PEAR setup script
   |
   |-fdftk.dll
   |
   |-..
   |
   |-php-cgi.exe          -- CGI executable
   |
   |-php-win.exe          -- executes scripts without an opened command prompt
   |
   |-php.exe              -- CLI executable - ONLY for command line scripting
   |
   |-..
   |
   |-php.ini-dist         -- default php.ini settings
   |
   |-php.ini-recommended  -- recommended php.ini settings
   | 
   |-php5activescript.dll
   |
   |-php5apache.dll
   |
   |-php5apache2.dll
   |
   |-..
   |
   |-php5ts.dll           -- core PHP DLL
   | 
   |-...

Notice the differences and similarities. Both PHP 4 and PHP 5 have a CGI executable, a CLI executable, and server modules, but they are located in different folders and/or have different names. While PHP 4 packages have the server modules in the sapi folder, PHP 5 distributions have no such directory and instead they're in the PHP folder root. The supporting DLLs for the PHP 5 extensions are also not in a seperate directory.

Notatka: In PHP 4, you should move all files located in the dll and sapi folders to the main folder (e.g. C:\php).

Here is a list of server modules shipped with PHP 4 and PHP 5:

  • sapi/php4activescript.dll (php5activescript.dll) - ActiveScript engine, allowing you to embed PHP in your Windows applications.

  • sapi/php4apache.dll (php5apache.dll) - Apache 1.3.x module.

  • sapi/php4apache2.dll (php5apache2.dll) - Apache 2.0.x module.

  • sapi/php4isapi.dll (php5isapi.dll) - ISAPI Module for ISAPI compliant web servers like IIS 4.0/PWS 4.0 or newer.

  • sapi/php4nsapi.dll (php5nsapi.dll) - Sun/iPlanet/Netscape server module.

  • sapi/php4pi3web.dll (no equivalent in PHP 5) - Pi3Web server module.

Server modules provide significantly better performance and additional functionality compared to the CGI binary. The CLI version is designed to let you use PHP for command line scripting. More information about CLI is available in the chapter about using PHP from the command line.

Ostrzeżenie

The SAPI modules have been significantly improved as of the 4.1 release, however, in older systems you may encounter server errors or other server modules failing, such as ASP.

The CGI and CLI binaries, and the web server modules all require the php4ts.dll (php5ts.dll) file to be available to them. You have to make sure that this file can be found by your PHP installation. The search order for this DLL is as follows:

  • The same directory from where php.exe is called, or in case you use a SAPI module, the web server's directory (e.g. C:\Program Files\Apache Group\Apache2\bin).

  • Any directory in your Windows PATH environment variable.

To make php4ts.dll / php5ts.dll available you have three options: copy the file to the Windows system directory, copy the file to the web server's directory, or add your PHP directory, C:\php to the PATH. For better maintenance, we advise you to follow the last option, add C:\php to the PATH, because it will be simpler to upgrade PHP in the future. Read more about how to add your PHP directory to PATH in the corresponding FAQ entry (and then don't forget to restart the computer - logoff isn't enough).

The next step is to set up a valid configuration file for PHP, php.ini. There are two ini files distributed in the zip file, php.ini-dist and php.ini-recommended. We advise you to use php.ini-recommended, because we optimized the default settings in this file for performance, and security. Read this well documented file carefully because it has changes from php.ini-dist that will drastically affect your setup. Some examples are display_errors being off and magic_quotes_gpc being off. In addition to reading these, study the ini settings and set every element manually yourself. If you would like to achieve the best security, then this is the way for you, although PHP works fine with these default ini files. Copy your chosen ini-file to a directory that PHP is able to find and rename it to php.ini. PHP searches for php.ini in the locations described in sekcja The configuration file w Rozdział 9 section.

If you are running Apache 2, the simpler option is to use the PHPIniDir directive (read the installation on Apache 2 page), otherwise your best option is to set the PHPRC environment variable. This process is explained in the following FAQ entry.

Notatka: If you're using NTFS on Windows NT, 2000, XP or 2003, make sure that the user running the web server has read permissions to your php.ini (e.g. make it readable by Everyone).

The following steps are optional:

  • Edit your new php.ini file. If you plan to use OmniHTTPd, do not follow the next step. Set the doc_root to point to your web servers document_root. For example:

    doc_root = c:\inetpub\wwwroot // for IIS/PWS
    
    doc_root = c:\apache\htdocs // for Apache

  • Choose the extensions you would like to load when PHP starts. See the section about Windows extensions, about how to set up one, and what is already built in. Note that on a new installation it is advisable to first get PHP working and tested without any extensions before enabling them in php.ini.

  • On PWS and IIS, you can set the browscap configuration setting to point to: c:\windows\system\inetsrv\browscap.ini on Windows 9x/Me, c:\winnt\system32\inetsrv\browscap.ini on NT/2000, and c:\windows\system32\inetsrv\browscap.ini on XP. For an up-to-date browscap.ini, read the following FAQ.

PHP is now setup on your system. The next step is to choose a web server, and enable it to run PHP. Choose a webserver from the table of contents.


ActiveScript

This section contains notes specific to the ActiveScript installation.

ActiveScript is a windows only SAPI that enables you to use PHP script in any ActiveScript compliant host, like Windows Script Host, ASP/ASP.NET, Windows Script Components or Microsoft Scriptlet control.

As of PHP 5.0.1, ActiveScript has been moved to the PECL repository. DLL z tym rozszerzeniem PECL można pobrać ze strony PHP Downloads lub http://snaps.php.net/.

Notatka: You should read the manual installation steps first!

After installing PHP, you should download the ActiveScript DLL (php5activescript.dll) and place it in the main PHP folder (e.g. C:\php).

After having all the files needed, you must register the DLL on your system. To achieve this, open a Command Prompt window (located in the Start Menu). Then go to your PHP directory by typing something like cd C:\php. To register the DLL just type regsvr32 php5activescript.dll.

To test if ActiveScript is working, create a new file, named test.wsf (the extension is very important) and type:
<job id="test">
 
 <script language="PHPScript">
  $WScript->Echo("Hello World!");
 </script>
 
</job>
Save and double-click on the file. If you receive a little window saying "Hello World!" you're done.

Notatka: In PHP 4, the engine was named 'ActivePHP', so if you are using PHP 4, you should replace 'PHPScript' with 'ActivePHP' in the above example.

Notatka: ActiveScript doesn't use the default php.ini file. Instead, it will look only in the same directory as the .exe that caused it to load. You should create php-activescript.ini and place it in that folder, if you wish to load extensions, etc.


Microsoft IIS / PWS

This section contains notes and hints specific to IIS (Microsoft Internet Information Server).

Ostrzeżenie

Używając instalacji CGI, serwer jest podatny na wiele potencjalnych ataków. Sposoby obrony przed nimi zostały opisane w rozdziale o bezpieczeństwie instalacji CGI.


General considerations for all installations of PHP with IIS or PWS

  • First, read the Manual Installation Instructions. Do not skip this step as it provides crucial information for installing PHP on Windows.

  • CGI users must set the cgi.force_redirect PHP directive to 0 inside php.ini. Read the faq on cgi.force_redirect for important details. Also, CGI users may want to set the cgi.redirect_status_env directive. When using directives, be sure these directives aren't commented out inside php.ini.

  • The PHP 4 CGI is named php.exe while in PHP 5 it's php-cgi.exe. In PHP 5, php.exe is the CLI, and not the CGI.

  • Modify the Windows PATH environment variable to include the PHP directory. This way the PHP DLL files, PHP executables, and php.ini can all remain in the PHP directory without cluttering up the Windows system directory. For more details, see the FAQ on Setting the PATH.

  • The IIS user (usually IUSR_MACHINENAME) needs permission to read various files and directories, such as php.ini, docroot, and the session tmp directory.

  • Be sure the extension_dir and doc_root PHP directives are appropriately set in php.ini. These directives depend on the system that PHP is being installed on. In PHP 4, the extension_dir is extensions while with PHP 5 it's ext. So, an example PHP 5 extensions_dir value is "c:\php\ext" and an example IIS doc_root value is "c:\Inetpub\wwwroot".

  • PHP extension DLL files, such as php_mysql.dll and php_curl.dll, are found in the zip package of the PHP download (not the PHP installer). In PHP 5, many extensions are part of PECL and can be downloaded in the "Collection of PECL modules" package. Files such as php_zip.dll and php_ssh2.dll. Download PHP files here.

  • When defining the executable, the 'check that file exists' box may also be checked. For a small performance penalty, the IIS (or PWS) will check that the script file exists and sort out authentication before firing up PHP. This means that the web server will provide sensible 404 style error messages instead of CGI errors complaining that PHP did not output any data.


Windows NT/200x/XP and IIS 4 or newer

PHP may be installed as a CGI binary, or with the ISAPI module. In either case, you need to start the Microsoft Management Console (may appear as 'Internet Services Manager', either in your Windows NT 4.0 Option Pack branch or the Control Panel=>Administrative Tools under Windows 2000/XP). Then right click on your Web server node (this will most probably appear as 'Default Web Server'), and select 'Properties'.

If you want to use the CGI binary, do the following:

  • Under 'Home Directory', 'Virtual Directory', or 'Directory', do the following:

  • Change the Execute Permissions to 'Scripts only'

  • Click on the 'Configuration' button, and choose the Application Mappings tab. Click Add and set the Executable path to the appropriate CGI file. An example PHP 5 value is: C:\php\php-cgi.exe Supply .php as the extension. Leave 'Method exclusions' blank, and check the 'Script engine' checkbox. Now, click OK a few times.

  • Set up the appropriate security. (This is done in Internet Service Manager), and if your NT Server uses NTFS file system, add execute rights for I_USR_ to the directory that contains php.exe / php-cgi.exe.

To use the ISAPI module, do the following:

  • If you don't want to perform HTTP Authentication using PHP, you can (and should) skip this step. Under ISAPI Filters, add a new ISAPI filter. Use PHP as the filter name, and supply a path to the php4isapi.dll / php5isapi.dll.

  • Under 'Home Directory', 'Virtual Directory', or 'Directory', do the following:

  • Change the Execute Permissions to 'Scripts only'

  • Click on the 'Configuration' button, and choose the Application Mappings tab. Click Add and set the Executable path to the appropriate ISAPI DLL. An example PHP 5 value is: C:\php\php5isapi.dll Supply .php as the extension. Leave 'Method exclusions' blank, and check the 'Script engine' checkbox. Now, click OK a few times.

  • Stop IIS completely (NET STOP iisadmin)

  • Start IIS again (NET START w3svc)

With IIS 6 (2003 Server), open up the IIS Manager, go to Web Service Extensions, choose "Add a new Web service extension", enter in a name such as PHP, choose the Add button and for the value browse to either the ISAPI file (php4isapi.dll or php5isapi.dll) or CGI (php.exe or php-cgi.exe) then check "Set extension status to Allowed" and click OK.

In order to use index.php as a default content page, do the following: From within the Documents tab, choose Add. Type in index.php and click OK. Adjust the order by choosing Move Up or Move Down. This is similar to setting DirectoryIndex with Apache.

The steps above must be repeated for each extension that is to be associated with PHP scripts. .php is the most common although .php3 may be required for legacy applications.

If you experience 100% CPU usage after some time, turn off the IIS setting Cache ISAPI Application.


Windows and PWS 4

PWS 4 does not support ISAPI, only PHP CGI should be used.

  • Edit the enclosed pws-php4cgi.reg / pws-php5cgi.reg file (look into the SAPI folder for PHP 4, or in the main folder for PHP 5) to reflect the location of your php.exe / php-cgi.exe. Backslashes should be escaped, for example: [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\w3svc\parameters\Script Map] ".php"="C:\\php\\php.exe" (change to C:\\php\\php-cgi.exe if you are using PHP 5) Now merge this registery file into your system; you may do this by double-clicking it.

  • In the PWS Manager, right click on a given directory you want to add PHP support to, and select Properties. Check the 'Execute' checkbox, and confirm.


Windows and PWS/IIS 3

The recommended method for configuring these servers is to use the REG file included with the distribution (pws-php4cgi.reg in the SAPI folder for PHP 4, or pws-php5cgi.reg in the main folder for PHP 5). You may want to edit this file and make sure the extensions and PHP install directories match your configuration. Or you can follow the steps below to do it manually.

Ostrzeżenie

These steps involve working directly with the Windows registry. One error here can leave your system in an unstable state. We highly recommend that you back up your registry first. The PHP Development team will not be held responsible if you damage your registry.

  • Run Regedit.

  • Navigate to: HKEY_LOCAL_MACHINE /System /CurrentControlSet /Services /W3Svc /Parameters /ScriptMap.

  • On the edit menu select: New->String Value.

  • Type in the extension you wish to use for your php scripts. For example .php

  • Double click on the new string value and enter the path to php.exe in the value data field. ex: C:\php\php.exe "%s" %s for PHP 4, or C:\php\php-cgi.exe "%s" %s for PHP 5.

  • Repeat these steps for each extension you wish to associate with PHP scripts.

The following steps do not affect the web server installation and only apply if you want your PHP scripts to be executed when they are run from the command line (ex. run C:\myscripts\test.php) or by double clicking on them in a directory viewer window. You may wish to skip these steps as you might prefer the PHP files to load into a text editor when you double click on them.

  • Navigate to: HKEY_CLASSES_ROOT

  • On the edit menu select: New->Key.

  • Name the key to the extension you setup in the previous section. ex: .php

  • Highlight the new key and in the right side pane, double click the "default value" and enter phpfile.

  • Repeat the last step for each extension you set up in the previous section.

  • Now create another New->Key under HKEY_CLASSES_ROOT and name it phpfile.

  • Highlight the new key phpfile and in the right side pane, double click the "default value" and enter PHP Script.

  • Right click on the phpfile key and select New->Key, name it Shell.

  • Right click on the Shell key and select New->Key, name it open.

  • Right click on the open key and select New->Key, name it command.

  • Highlight the new key command and in the right side pane, double click the "default value" and enter the path to php.exe. ex: c:\php\php.exe -q %1. (don't forget the %1).

  • Exit Regedit.

  • If using PWS on Windows, reboot to reload the registry.

PWS and IIS 3 users now have a fully operational system. IIS 3 users can use a nifty tool from Steven Genusa to configure their script maps.


Apache 1.3.x on Microsoft Windows

This section contains notes and hints specific to Apache 1.3.x installs of PHP on Microsoft Windows systems. There are also instructions and notes for Apache 2 on a separate page.

Notatka: Please read the manual installation steps first!

There are two ways to set up PHP to work with Apache 1.3.x on Windows. One is to use the CGI binary (php.exe for PHP 4 and php-cgi.exe for PHP 5), the other is to use the Apache Module DLL. In either case you need to edit your httpd.conf to configure Apache to work with PHP, and then restart the server.

It is worth noting here that now the SAPI module has been made more stable under Windows, we recommend it's use above the CGI binary, since it is more transparent and secure.

Although there can be a few variations of configuring PHP under Apache, these are simple enough to be used by the newcomer. Please consult the Apache Documentation for further configuration directives.

After changing the configuration file, remember to restart the server, for example, NET STOP APACHE followed by NET START APACHE, if you run Apache as a Windows Service, or use your regular shortcuts.

Notatka: Nalezy pamiętać, że podając ścieżki w plikach konfiguracyjnych Apache w systemie Windows, wszystkie znaki backslash takie jak na przykład w ścieżce c:\directory\file.ext muszą być zamienione na znaki slash, na przykład c:/directory/file.ext.


Installing as an Apache module

You should add the following lines to your Apache httpd.conf file:

Przykład 6-3. PHP as an Apache 1.3.x module

This assumes PHP is installed to c:\php. Adjust the path if this is not the case.

For PHP 4:

# Add to the end of the LoadModule section
# Don't forget to copy this file from the sapi directory!
LoadModule php4_module "C:/php/php4apache.dll"

# Add to the end of the AddModule section
AddModule mod_php4.c

For PHP 5:

# Add to the end of the LoadModule section
LoadModule php5_module "C:/php/php5apache.dll"

# Add to the end of the AddModule section
AddModule mod_php5.c

For both:

# Add this line inside the <IfModule mod_mime.c> conditional brace
AddType application/x-httpd-php .php

# For syntax highlighted .phps files, also add
AddType application/x-httpd-php-source .phps


Installing as a CGI binary

If you unzipped the PHP package to C:\php\ as described in the Manual Installation Steps section, you need to insert these lines to your Apache configuration file to set up the CGI binary:

Przykład 6-4. PHP and Apache 1.3.x as CGI

ScriptAlias /php/ "c:/php/"
AddType application/x-httpd-php .php

# For PHP 4
Action application/x-httpd-php "/php/php.exe"

# For PHP 5
Action application/x-httpd-php "/php/php-cgi.exe"

# specify the directory where php.ini is
SetEnv PHPRC C:/php
Note that the second line in the list above can be found in the actual versions of httpd.conf, but it is commented out. Remember also to substitute the c:/php/ for your actual path to PHP.

Ostrzeżenie

Używając instalacji CGI, serwer jest podatny na wiele potencjalnych ataków. Sposoby obrony przed nimi zostały opisane w rozdziale o bezpieczeństwie instalacji CGI.

If you would like to present PHP source files syntax highlighted, there is no such convenient option as with the module version of PHP. If you chose to configure Apache to use PHP as a CGI binary, you will need to use the highlight_file() function. To do this simply create a PHP script file and add this code: <?php highlight_file('some_php_script.php'); ?>.


Apache 2.0.x on Microsoft Windows

This section contains notes and hints specific to Apache 2.0.x installs of PHP on Microsoft Windows systems. We also have instructions and notes for Apache 1.3.x users on a separate page.

Notatka: You should read the manual installation steps first!

Notatka: Users of Apache 2.2.x may use the documentation below except the appropriate DLL files are instead named php4apache2_2.dll and php5apache2_2.dll. These exist in the PHP distribution as of PHP 5.2.0. See also http://snaps.php.net/

Ostrzeżenie

Nie zalecamy korzystania z wątkowanego MPM na produkcyjnych serwerach Apache2. Zamiast niego wskazane jest używanie preforkowanego MPM, lub używanie Apache1. Wyjaśnienie powodów można znaleźć w odpowiednim punkcie FAQ, dotyczącym używania Apache2 z wątkowanym MPM

You are highly encouraged to take a look at the Apache Documentation to get a basic understanding of the Apache 2.0.x Server. Also consider to read the Windows specific notes for Apache 2.0.x before reading on here.

PHP and Apache 2.0.x compatibility notes: The following versions of PHP are known to work with the most recent version of Apache 2.0.x:

These versions of PHP are compatible to Apache 2.0.40 and later.

Apache 2.0 SAPI-support started with PHP 4.2.0. PHP 4.2.3 works with Apache 2.0.39, don't use any other version of Apache with PHP 4.2.3. However, the recommended setup is to use PHP 4.3.0 or later with the most recent version of Apache2.

All mentioned versions of PHP will work still with Apache 1.3.x.

Ostrzeżenie

Apache 2.0.x is designed to run on Windows NT 4.0, Windows 2000 or Windows XP. At this time, support for Windows 9x is incomplete. Apache 2.0.x is not expected to work on those platforms at this time.

Download the most recent version of Apache 2.0.x and a fitting PHP version. Follow the Manual Installation Steps and come back to go on with the integration of PHP and Apache.

There are two ways to set up PHP to work with Apache 2.0.x on Windows. One is to use the CGI binary the other is to use the Apache module DLL. In either case you need to edit your httpd.conf to configure Apache to work with PHP and then restart the server.

Notatka: Nalezy pamiętać, że podając ścieżki w plikach konfiguracyjnych Apache w systemie Windows, wszystkie znaki backslash takie jak na przykład w ścieżce c:\directory\file.ext muszą być zamienione na znaki slash, na przykład c:/directory/file.ext.


Installing as a CGI binary

You need to insert these three lines to your Apache httpd.conf configuration file to set up the CGI binary:

Przykład 6-5. PHP and Apache 2.0 as CGI

ScriptAlias /php/ "c:/php/"
AddType application/x-httpd-php .php

# For PHP 4
Action application/x-httpd-php "/php/php.exe"

# For PHP 5
Action application/x-httpd-php "/php/php-cgi.exe"

Ostrzeżenie

Używając instalacji CGI, serwer jest podatny na wiele potencjalnych ataków. Sposoby obrony przed nimi zostały opisane w rozdziale o bezpieczeństwie instalacji CGI.


Installing as an Apache module

You need to insert these two lines to your Apache httpd.conf configuration file to set up the PHP module for Apache 2.0:

Przykład 6-6. PHP and Apache 2.0 as Module

# For PHP 4 do something like this:
LoadModule php4_module "c:/php/php4apache2.dll"
# Don't forget to copy the php4apache2.dll file from the sapi directory!
AddType application/x-httpd-php .php

# For PHP 5 do something like this:
LoadModule php5_module "c:/php/php5apache2.dll"
AddType application/x-httpd-php .php

# configure the path to php.ini
PHPIniDir "C:/php"

Notatka: Remember to substitute your actual path to PHP for the c:/php/ in the above examples. Take care to use either php4apache2.dll or php5apache2.dll in your LoadModule directive and not php4apache.dll or php5apache.dll as the latter ones are designed to run with Apache 1.3.x.

Notatka: If you want to use content negotiation, read related FAQ.

Ostrzeżenie

Don't mix up your installation with DLL files from different PHP versions. You have the only choice to use the DLL's and extensions that ship with your downloaded PHP version.


Sun, iPlanet and Netscape servers on Microsoft Windows

This section contains notes and hints specific to Sun Java System Web Server, Sun ONE Web Server, iPlanet and Netscape server installs of PHP on Windows.

From PHP 4.3.3 on you can use PHP scripts with the NSAPI module to generate custom directory listings and error pages. Additional functions for Apache compatibility are also available. For support in current webservers read the note about subrequests.


CGI setup on Sun, iPlanet and Netscape servers

To install PHP as a CGI handler, do the following:

  • Copy php4ts.dll to your systemroot (the directory where you installed Windows)

  • Make a file association from the command line. Type the following two lines:
    assoc .php=PHPScript
    ftype PHPScript=c:\php\php.exe %1 %*

  • In the Netscape Enterprise Administration Server create a dummy shellcgi directory and remove it just after (this step creates 5 important lines in obj.conf and allow the web server to handle shellcgi scripts).

  • In the Netscape Enterprise Administration Server create a new mime type (Category: type, Content-Type: magnus-internal/shellcgi, File Suffix:php).

  • Do it for each web server instance you want PHP to run

More details about setting up PHP as a CGI executable can be found here: http://benoit.noss.free.fr/php/install-php.html


NSAPI setup on Sun, iPlanet and Netscape servers

To install PHP with NSAPI, do the following:

  • Copy php4ts.dll to your systemroot (the directory where you installed Windows)

  • Make a file association from the command line. Type the following two lines:
    assoc .php=PHPScript
    ftype PHPScript=c:\php\php.exe %1 %*

  • In the Netscape Enterprise Administration Server create a new mime type (Category: type, Content-Type: magnus-internal/x-httpd-php, File Suffix: php).

  • Edit magnus.conf (for servers >= 6) or obj.conf (for servers < 6) and add the following: You should place the lines after mime types init.
    Init fn="load-modules" funcs="php4_init,php4_execute,php4_auth_trans" shlib="c:/php/sapi/php4nsapi.dll"
    Init fn="php4_init" LateInit="yes" errorString="Failed to initialise PHP!" [php_ini="c:/path/to/php.ini"]
    (PHP >= 4.3.3) The php_ini parameter is optional but with it you can place your php.ini in your webserver config directory.

  • Configure the default object in obj.conf (for virtual server classes [Sun Web Server 6.0+] in their vserver.obj.conf): In the <Object name="default"> section, place this line necessarily after all 'ObjectType' and before all 'AddLog' lines:
    Service fn="php4_execute" type="magnus-internal/x-httpd-php" [inikey=value inikey=value ...]
    (PHP >= 4.3.3) As additional parameters you can add some special php.ini-values, for example you can set a docroot="/path/to/docroot" specific to the context php4_execute is called. For boolean ini-keys please use 0/1 as value, not "On","Off",... (this will not work correctly), e.g. zlib.output_compression=1 instead of zlib.output_compression="On"

  • This is only needed if you want to configure a directory that only consists of PHP scripts (same like a cgi-bin directory):
    <Object name="x-httpd-php">
    ObjectType fn="force-type" type="magnus-internal/x-httpd-php"
    Service fn=php4_execute [inikey=value inikey=value ...]
    </Object>
    After that you can configure a directory in the Administration server and assign it the style x-httpd-php. All files in it will get executed as PHP. This is nice to hide PHP usage by renaming files to .html.

  • Restart your web service and apply changes

  • Do it for each web server instance you want PHP to run

Notatka: More details about setting up PHP as an NSAPI filter can be found here: http://benoit.noss.free.fr/php/install-php4.html

Notatka: The stacksize that PHP uses depends on the configuration of the webserver. If you get crashes with very large PHP scripts, it is recommended to raise it with the Admin Server (in the section "MAGNUS EDITOR").


CGI environment and recommended modifications in php.ini

Important when writing PHP scripts is the fact that Sun JSWS/Sun ONE WS/iPlanet/Netscape is a multithreaded web server. Because of that all requests are running in the same process space (the space of the webserver itself) and this space has only one environment. If you want to get CGI variables like PATH_INFO, HTTP_HOST etc. it is not the correct way to try this in the old PHP 3.x way with getenv() or a similar way (register globals to environment, $_ENV). You would only get the environment of the running webserver without any valid CGI variables!

Notatka: Why are there (invalid) CGI variables in the environment?

Answer: This is because you started the webserver process from the admin server which runs the startup script of the webserver, you wanted to start, as a CGI script (a CGI script inside of the admin server!). This is why the environment of the started webserver has some CGI environment variables in it. You can test this by starting the webserver not from the administration server. Use the command line as root user and start it manually - you will see there are no CGI-like environment variables.

Simply change your scripts to get CGI variables in the correct way for PHP 4.x by using the superglobal $_SERVER. If you have older scripts which use $HTTP_HOST, etc., you should turn on register_globals in php.ini and change the variable order too (important: remove "E" from it, because you do not need the environment here):
variables_order = "GPCS"
register_globals = On


Special use for error pages or self-made directory listings (PHP >= 4.3.3)

You can use PHP to generate the error pages for "404 Not Found" or similar. Add the following line to the object in obj.conf for every error page you want to overwrite:
Error fn="php4_execute" code=XXX script="/path/to/script.php" [inikey=value inikey=value...]
where XXX is the HTTP error code. Please delete any other Error directives which could interfere with yours. If you want to place a page for all errors that could exist, leave the code parameter out. Your script can get the HTTP status code with $_SERVER['ERROR_TYPE'].

Another possibility is to generate self-made directory listings. Just create a PHP script which displays a directory listing and replace the corresponding default Service line for type="magnus-internal/directory" in obj.conf with the following:
Service fn="php4_execute" type="magnus-internal/directory" script="/path/to/script.php" [inikey=value inikey=value...]
For both error and directory listing pages the original URI and translated URI are in the variables $_SERVER['PATH_INFO'] and $_SERVER['PATH_TRANSLATED'].


Note about nsapi_virtual() and subrequests (PHP >= 4.3.3)

The NSAPI module now supports the nsapi_virtual() function (alias: virtual()) to make subrequests on the webserver and insert the result in the webpage. The problem is, that this function uses some undocumented features from the NSAPI library.

Under Unix this is not a problem, because the module automatically looks for the needed functions and uses them if available. If not, nsapi_virtual() is disabled.

Under Windows limitations in the DLL handling need the use of a automatic detection of the most recent ns-httpdXX.dll file. This is tested for servers till version 6.1. If a newer version of the Sun server is used, the detection fails and nsapi_virtual() is disabled.

If this is the case, try the following: Add the following parameter to php4_init in magnus.conf/obj.conf:
Init fn=php4_init ... server_lib="ns-httpdXX.dll"
where XX is the correct DLL version number. To get it, look in the server-root for the correct DLL name. The DLL with the biggest filesize is the right one.

You can check the status by using the phpinfo() function.

Notatka: But be warned: Support for nsapi_virtual() is EXPERIMENTAL!!!


OmniHTTPd Server

This section contains notes and hints specific to OmniHTTPd on Windows.

Notatka: You should read the manual installation steps first!

Ostrzeżenie

Używając instalacji CGI, serwer jest podatny na wiele potencjalnych ataków. Sposoby obrony przed nimi zostały opisane w rozdziale o bezpieczeństwie instalacji CGI.

You need to complete the following steps to make PHP work with OmniHTTPd. This is a CGI executable setup. SAPI is supported by OmniHTTPd, but some tests have shown that it is not so stable to use PHP as an ISAPI module.

Important for CGI users: Read the faq on cgi.force_redirect for important details. This directive needs to be set to 0.

  1. Install OmniHTTPd server.

  2. Right click on the blue OmniHTTPd icon in the system tray and select Properties

  3. Click on Web Server Global Settings

  4. On the 'External' tab, enter: virtual = .php | actual = c:\php\php.exe (use php-cgi.exe if installing PHP 5), and use the Add button.

  5. On the Mime tab, enter: virtual = wwwserver/stdcgi | actual = .php, and use the Add button.

  6. Click OK

Repeat steps 2 - 6 for each extension you want to associate with PHP.

Notatka: Some OmniHTTPd packages come with built in PHP support. You can choose at setup time to do a custom setup, and uncheck the PHP component. We recommend you to use the latest PHP binaries. Some OmniHTTPd servers come with PHP 4 beta distributions, so you should choose not to set up the built in support, but install your own. If the server is already on your machine, use the Replace button in Step 4 and 5 to set the new, correct information.


Sambar Server on Microsoft Windows

This section contains notes and hints specific to the Sambar Server for Windows.

Notatka: You should read the manual installation steps first!

This list describes how to set up the ISAPI module to work with the Sambar server on Windows.

  • Find the file called mappings.ini (in the config directory) in the Sambar install directory.

  • Open mappings.ini and add the following line under [ISAPI]:

    Przykład 6-7. ISAPI configuration of Sambar

    #for PHP 4
    *.php = c:\php\php4isapi.dll
    
    #for PHP 5
    *.php = c:\php\php5isapi.dll
    (This line assumes that PHP was installed in c:\php.)

  • Now restart the Sambar server for the changes to take effect.


Xitami on Microsoft Windows

This section contains notes and hints specific to Xitami on Windows.

Notatka: You should read the manual installation steps first!

This list describes how to set up the PHP CGI binary to work with Xitami on Windows.

Important for CGI users: Read the faq on cgi.force_redirect for important details. This directive needs to be set to 0. If you want to use $_SERVER['PHP_SELF'] you have to enable the cgi.fix_pathinfo directive.

Ostrzeżenie

Używając instalacji CGI, serwer jest podatny na wiele potencjalnych ataków. Sposoby obrony przed nimi zostały opisane w rozdziale o bezpieczeństwie instalacji CGI.

  • Make sure the webserver is running, and point your browser to xitamis admin console (usually http://127.0.0.1/admin), and click on Configuration.

  • Navigate to the Filters, and put the extension which PHP should parse (i.e. .php) into the field File extensions (.xxx).

  • In Filter command or script put the path and name of your PHP CGI executable i.e. C:\php\php.exe for PHP 4, or C:\php\php-cgi.exe for PHP 5.

  • Press the 'Save' icon.

  • Restart the server to reflect changes.


Building from source

This chapter teaches how to compile PHP from sources on windows, using Microsoft's tools. To compile PHP with cygwin, please refer to Rozdział 4.


Wymagania

To compile and build PHP you need a Microsoft Development Environment. Microsoft Visual C++ 6.0 is recommended, though Visual C++ .NET versions will also work. Since PHP 5 the free Microsoft .NET toolchain is also supported (you need to install Windows Platform SDK, Visual C++ Toolkit and .NET Framework SDK).

To extract the downloaded files you will also need a ZIP extraction utility. Windows XP and newer already include this functionality built-in.

Before you get started, you have to download:

Finally, you are going to need the source to PHP itself. You can get the latest development version using anonymous CVS, a snapshot or the most recent released source tarball.


Putting it all together

After downloading the required packages you have to extract them in a proper place:

  • Create a working directory where all files end up after extracting, e.g: C:\work.

  • Create the directory win32build under your working directory (C:\work) and unzip win32build.zip into it.

  • Create the directory bindlib_w32 under your working directory (C:\work) and unzip bindlib_w32.zip into it.

  • Extract the downloaded PHP source code into your working directory (C:\work).

  • Build the libraries you are going to need (or download the binaries if available) and place the headers and libs in the C:\work\win32build\include and C:\work\win32build\lib directories, respectively.

  • If you don't have cygwin installed with bison and flex, you also need to make the C:\work\win32build\bin directory available in the PATH, so that thoses tools can be found by the configure script.

Following this steps your directory structure looks like this:
+--C:\work
|  |
|  +--bindlib_w32
|  |  |
|  |  +--arpa
|  |  |
|  |  +--conf
|  |  |
|  |  +--...
|  |
|  +--php-5.x.x
|  |  |
|  |  +--build
|  |  |
|  |  +--...
|  |  |
|  |  +--win32
|  |  |
|  |  +--...
|  |
|  +--win32build
|  |  |
|  |  +--bin
|  |  |
|  |  +--include
|  |  |
|  |  +--lib

If you aren't using Cygwin, you must also create the directories C:\usr\local\lib and then copy bison.simple from C:\work\win32build\bin to C:\usr\local\lib.

Notatka: If you want to use PEAR and the comfortable command line installer, the CLI-SAPI is mandatory. For more information about PEAR and the installer read the documentation at the PEAR website.


Build resolv.lib

You must build the resolv.lib library. Decide whether you want to have debug symbols available (bindlib - Win32 Debug) or not (bindlib - Win32 Release), but please remember the choice you made, because the debug build will only link with PHP when it is also built in debug mode. Build the appropriate configuration:

  • For GUI users, launch VC++, by double-clicking in C:\work\bindlib_w32\bindlib.dsw. Then select Build=>Rebuild All.

  • For command line users, make sure that you either have the C++ environment variables registered, or have run vcvars.bat, and then execute one of the following commands:

    • msdev bindlib.dsp /MAKE "bindlib - Win32 Debug"

    • msdev bindlib.dsp /MAKE "bindlib - Win32 Release"

At this point, you should have a usable resolv.lib in either your C:\work\bindlib_w32\Debug or Release subdirectories. Copy this file into your C:\work\win32build\lib directory over the file by the same name found in there.


Building PHP using the new build system [PHP >=5 only]

This chapter explains how to compile PHP >=5 using the new build system, which is CLI-based and very similar with the main PHP's Unix build system.

Notatka: This build system isn't available in PHP 4. Please refer to sekcja Building PHP using DSW files [PHP 4] instead.

Before starting, be sure you have read sekcja Putting it all together and you have built all needed libraries, like Libxml or ICU (needed for PHP >= 6).

First you should open a Visual Studio Command Prompt, which should be available under the Start menu. A regular Command Prompt window shouldn't work, as probably it doesn't have the necessary environment variables set. Then type something like cd C:\work\php-5.x.x to enter in the PHP source dir. Now you are ready to start configuring PHP.

The second step is running the buildconf batch file to make the configure script, by scanning the folder for config.w32 files. By default this command will also search in the following directories: pecl; ..\pecl; pecl\rpc; ..\pecl\rpc. Since PHP 5.1.0, you can change this behaviour by using the --add-modules-dir argument (e.g. cscript /nologo win32/build/buildconf.js --add-modules-dir=../php-gtk2 --add-modules-dir=../pecl).

The third step is configuring. To view the list of the available configuration options type cscript /nologo configure.js --help. After choosing the options that you will enable/disable, type something like: cscript /nologo configure.js --disable-foo --enable-fun-ext. Using --enable-foo=shared will attempt to build the 'foo' extension as a shared, dynamically loadable module.

The last step is compiling. To achieve this just issue the command nmake. The generated files (e.g. .exe and .dll) will be placed in either Release_TS or Debug_TS directories (if built with Thread safety), or in the Release or Debug directories otherwise.

Optionally you may also run PHP's test suite, by typing nmake test. If you want to run just a specific test, you may use the 'TESTS' variable (e.g. nmake /D TESTS=ext/sqlite/tests test - will only run sqlite's tests). To delete the files that were created during the compilation, you can use the nmake clean command.

A very useful configure option to build snapshots is --enable-snapshot-build, which add a new compiling mode (nmake build-snap). This tries to build every extension available (as shared, by default), but it will ignore build errors in individual extensions or SAPI.


Building PHP using DSW files [PHP 4]

Compiling PHP using the DSW files isn't supported as of PHP 5, as a much more flexible system was made available. Anyway, you can still use them, but keep in mind that they are not maintained very often, so you can have compiling problems. To compile PHP 4 for windows, this is the only available way though.


Configure MVC ++

The first step is to configure MVC++ to prepare for compiling. Launch Microsoft Visual C++, and from the menu select Tools => Options. In the dialog, select the directories tab. Sequentially change the dropdown to Executables, Includes, and Library files. Your entries should look like this:

  • Executable files: C:\work\win32build\bin, Cygwin users: C:\cygwin\bin

  • Include files: C:\work\win32build\include

  • Library files: C:\work\win32build\lib


Compiling

The best way to get started is to build the CGI version:

  • For GUI users, launch VC++, and then select File => Open Workspace and select C:\work\php-4.x.x\win32\php4ts.dsw. Then select Build=>Set Active Configuration and select the desired configuration, either php4ts - Win32 Debug_TS or php4ts - Win32 Release_TS. Finally select Build=>Rebuild All.

  • For command line users, make sure that you either have the C++ environment variables registered, or have run vcvars.bat, and then execute one of the following commands from the C:\work\php-4.x.x\win32 directory:

    • msdev php4ts.dsp /MAKE "php4ts - Win32 Debug_TS"

    • msdev php4ts.dsp /MAKE "php4ts - Win32 Release_TS"

    • At this point, you should have a usable php.exe in either your C:\work\php-4.x.x\Debug_TS or Release_TS subdirectories.

It is possible to do minor customization to the build process by editing the main/config.win32.h file. For example you can change the default location of php.ini, the built-in extensions, and the default location for your extensions.

Next you may want to build the CLI version which is designed to use PHP from the command line. The steps are the same as for building the CGI version, except you have to select the php4ts_cli - Win32 Debug_TS or php4ts_cli - Win32 Release_TS project file. After a successful compiling run you will find the php.exe in either the directory Release_TS\cli\ or Debug_TS\cli\.

In order to build the SAPI module (php4isapi.dll) for integrating PHP with Microsoft IIS, set your active configuration to php4isapi-whatever-config and build the desired dll.


Installation of extensions on Windows

After installing PHP and a webserver on Windows, you will probably want to install some extensions for added functionality. You can choose which extensions you would like to load when PHP starts by modifying your php.ini. You can also load a module dynamically in your script using dl().

The DLLs for PHP extensions are prefixed with php_.

Many extensions are built into the Windows version of PHP. This means additional DLL files, and the extension directive, are not used to load these extensions. The Windows PHP Extensions table lists extensions that require, or used to require, additional PHP DLL files. Here's a list of built in extensions:

In PHP 4 (updated PHP 4.3.11): BCMath, Caledar, COM, Ctype, FTP, MySQL, ODBC, Overload, PCRE, Session, Tokenizer, WDDX, XML i Zlib

In PHP 5 (updated PHP 5.0.4), the following changes exist. Built in: DOM, LibXML, Iconv, SimpleXML, SPL i SQLite. And the following are no longer built in: MySQL and Overload.

The default location PHP searches for extensions is C:\php4\extensions in PHP 4 and C:\php5 in PHP 5. To change this setting to reflect your setup of PHP edit your php.ini file:

  • You will need to change the extension_dir setting to point to the directory where your extensions lives, or where you have placed your php_*.dll files. For example:

    extension_dir = C:\php\extensions

  • Enable the extension(s) in php.ini you want to use by uncommenting the extension=php_*.dll lines in php.ini. This is done by deleting the leading ; from the extension you want to load.

    Przykład 6-8. Enable Bzip2 extension for PHP-Windows

    // change the following line from ...
    ;extension=php_bz2.dll
    
    // ... to
    extension=php_bz2.dll

  • Some of the extensions need extra DLLs to work. Couple of them can be found in the distribution package, in the C:\php\dlls\ folder in PHP 4 or in the main folder in PHP 5, but some, for example Oracle (php_oci8.dll) require DLLs which are not bundled with the distribution package. If you are installing PHP 4, copy the bundled DLLs from C:\php\dlls folder to the main C:\php folder. Don't forget to include C:\php in the system PATH (this process is explained in a separate FAQ entry).

  • Some of these DLLs are not bundled with the PHP distribution. See each extensions documentation page for details. Also, read the manual section titled Installation of PECL extensions for details on PECL. An increasingly large number of PHP extensions are found in PECL, and these extensions require a separate download.

Notatka: If you are running a server module version of PHP remember to restart your webserver to reflect your changes to php.ini.

The following table describes some of the extensions available and required additional dlls.

Tabela 6-1. PHP Extensions

ExtensionDescriptionNotes
php_bz2.dllbzip2 compression functionsNone
php_calendar.dllCalendar conversion functionsBuilt in since PHP 4.0.3
php_cpdf.dllClibPDF functionsNone
php_crack.dllCrack functionsNone
php_ctype.dllctype family functionsBuilt in since PHP 4.3.0
php_curl.dllCURL, Client URL library functionsRequires: libeay32.dll, ssleay32.dll (bundled)
php_cybercash.dllCybercash payment functionsPHP <= 4.2.0
php_db.dllDBM functionsDeprecated. Use DBA instead (php_dba.dll)
php_dba.dllDBA: DataBase (dbm-style) Abstraction layer functionsNone
php_dbase.dlldBase functionsNone
php_dbx.dlldbx functions 
php_domxml.dllDOM XML functions PHP <= 4.2.0 requires: libxml2.dll (bundled) PHP >= 4.3.0 requires: iconv.dll (bundled)
php_dotnet.dll.NET functionsPHP <= 4.1.1
php_exif.dllEXIF functions php_mbstring.dll. And, php_exif.dll must be loaded after php_mbstring.dll in php.ini.
php_fbsql.dllFrontBase functionsPHP <= 4.2.0
php_fdf.dllFDF: Forms Data Format functions.Requires: fdftk.dll (bundled)
php_filepro.dllfilePro functionsRead-only access
php_ftp.dllFTP functionsBuilt-in since PHP 4.0.3
php_gd.dllGD library image functions Removed in PHP 4.3.2. Also note that truecolor functions are not available in GD1, instead, use php_gd2.dll.
php_gd2.dllGD library image functionsGD2
php_gettext.dllGettext functions PHP <= 4.2.0 requires gnu_gettext.dll (bundled), PHP >= 4.2.3 requires libintl-1.dll, iconv.dll (bundled).
php_hyperwave.dllHyperWave functionsNone
php_iconv.dllICONV characterset conversionRequires: iconv-1.3.dll (bundled), PHP >=4.2.1 iconv.dll
php_ifx.dllInformix functionsRequires: Informix libraries
php_iisfunc.dllIIS management functionsNone
php_imap.dllIMAP POP3 and NNTP functionsNone
php_ingres.dllIngres II functionsRequires: Ingres II libraries
php_interbase.dllInterBase functionsRequires: gds32.dll (bundled)
php_java.dllJava functionsPHP <= 4.0.6 requires: jvm.dll (bundled)
php_ldap.dllLDAP functions PHP <= 4.2.0 requires libsasl.dll (bundled), PHP >= 4.3.0 requires libeay32.dll, ssleay32.dll (bundled)
php_mbstring.dllMulti-Byte String functionsNone
php_mcrypt.dllMcrypt Encryption functionsRequires: libmcrypt.dll
php_mhash.dllMhash functionsPHP >= 4.3.0 requires: libmhash.dll (bundled)
php_mime_magic.dllMimetype functionsRequires: magic.mime (bundled)
php_ming.dllMing functions for FlashNone
php_msql.dllmSQL functionsRequires: msql.dll (bundled)
php_mssql.dllMSSQL functionsRequires: ntwdblib.dll (bundled)
php_mysql.dllMySQL functionsPHP >= 5.0.0, requires libmysql.dll (bundled)
php_mysqli.dllMySQLi functionsPHP >= 5.0.0, requires libmysql.dll (libmysqli.dll in PHP <= 5.0.2) (bundled)
php_oci8.dllOracle 8 functionsRequires: Oracle 8.1+ client libraries
php_openssl.dllOpenSSL functionsRequires: libeay32.dll (bundled)
php_oracle.dllOracle functionsRequires: Oracle 7 client libraries
php_overload.dllObject overloading functionsBuilt in since PHP 4.3.0
php_pdf.dllPDF functionsNone
php_pgsql.dllPostgreSQL functionsNone
php_printer.dllPrinter functionsNone
php_shmop.dllShared Memory functionsNone
php_snmp.dllSNMP get and walk functionsNT only!
php_soap.dllSOAP functionsPHP >= 5.0.0
php_sockets.dllSocket functionsNone
php_sybase_ct.dllSybase functionsRequires: Sybase client libraries
php_tidy.dllTidy functionsPHP >= 5.0.0
php_tokenizer.dllTokenizer functionsBuilt in since PHP 4.3.0
php_w32api.dllW32api functionsNone
php_xmlrpc.dllXML-RPC functionsPHP >= 4.2.1 requires: iconv.dll (bundled)
php_xslt.dllXSLT functions PHP <= 4.2.0 requires sablot.dll, expat.dll (bundled). PHP >= 4.2.1 requires sablot.dll, expat.dll, iconv.dll (bundled).
php_yaz.dllYAZ functionsRequires: yaz.dll (bundled)
php_zip.dllZip File functionsRead only access
php_zlib.dllZLib compression functionsBuilt in since PHP 4.3.0


Rozdział 7. Installation of PECL extensions

Introduction to PECL Installations

PECL is a repository of PHP extensions that are made available to you via the PEAR packaging system. This section of the manual is intended to demonstrate how to obtain and install PECL extensions.

These instructions assume /your/phpsrcdir/ is the path to the PHP source distribution, and that extname is the name of the PECL extension. Adjust accordingly. These instructions also assume a familiarity with the pear command.

To be useful, a shared extension must be built, installed, and loaded. The methods described below provide you with various instructions on how to build and install the extensions, but they do not automatically load them. Extensions can be loaded by adding an extension directive. To this php.ini file, or through the use of the dl() function.

When building PHP modules, it's important to have known-good versions of the required tools (autoconf, automake, libtool, etc.) See the Anonymous CVS Instructions for details on the required tools, and required versions.


Downloading PECL extensions

There are several options for downloading PECL extensions, such as:

  • http://pecl.php.net

    The PECL web site contains information about the different extensions that are offered by the PHP Development Team. The information available here includes: ChangeLog, release notes, requirements and other similar details.

  • pear download extname

    PECL extensions that have releases listed on the PECL web site are available for download and installation using the pear command. Specific revisions may also be specified.

  • CVS

    Most PECL extensions also reside in CVS. A web-based view may be seen at http://cvs.php.net/pecl/. To download straight from CVS, the following sequence of commands may be used. Note that phpfi is the password for user cvsread:

    $ cvs -d:pserver:cvsread@cvs.php.net:/repository login 
    $ cvs -d:pserver:cvsread@cvs.php.net:/repository co pecl/extname

  • Windows downloads

    Windows users may find compiled PECL binaries by downloading the Collection of PECL modules from the PHP Downloads page, and by retrieving a PECL Snapshot. To compile PHP under Windows, read the appropriate chapter.


PECL for Windows users

As with any other PHP extension DLL, installation is as simple as copying the PECL extension DLLs into the extension_dir folder and loading them from php.ini. For example, add the following line to your php.ini:

extension=php_extname.dll

After doing this, restart the web server.


Compiling shared PECL extensions with PEAR

PEAR makes it easy to create shared PHP extensions. Using the pear command, do the following:

$ pear install extname

This will download the source for extname, compile, and install extname.so into your extension_dir. extname.so may then be loaded via php.ini

By default, the pear command will not install packages that are marked with the alpha or beta state. If no stable packages are available, you may install a beta package using the following command:

$ pear install extname-beta

You may also install a specific version using this variant:

$ pear install extname-0.1


Compiling shared PECL extensions with phpize

Sometimes, using the pear installer is not an option. This could be because you're behind a firewall, or it could be because the extension you want to install is not available as a PEAR compatible package, such as unreleased extensions from CVS. If you need to build such an extension, you can use the lower-level build tools to perform the build manually.

The phpize command is used to prepare the build environment for a PHP extension. In the following sample, the sources for an extension are in a directory named extname:

$ cd extname
$ phpize
$ ./configure
$ make
# make install

A successful install will have created extname.so and put it into the PHP extensions directory. You'll need to and adjust php.ini and add an extension=extname.so line before you can use the extension.

If the system is missing the phpize command, and precompiled packages (like RPM's) are used, be sure to also install the appropriate devel version of the PHP package as they often include the phpize command along with the appropriate header files to build PHP and its extensions.

Execute phpize --help to display additional usage information.


Compiling PECL extensions statically into PHP

You might find that you need to build a PECL extension statically into your PHP binary. To do this, you'll need to place the extension source under the php-src/ext/ directory and tell the PHP build system to regenerate its configure script.

$ cd /your/phpsrcdir/ext
$ pear download extname
$ gzip -d < extname.tgz | tar -xvf -
$ mv extname-x.x.x extname

This will result in the following directory:

/your/phpsrcdir/ext/extname

From here, force PHP to rebuild the configure script, and then build PHP as normal:

$ cd /your/phpsrcdir 
$ rm configure
$ ./buildconf --force
$ ./configure --help
$ ./configure --with-extname --enable-someotherext --with-foobar
$ make
$ make install

Notatka: To run the 'buildconf' script you need autoconf 2.13 and automake 1.4+ (newer versions of autoconf may work, but are not supported).

Whether --enable-extname or --with-extname is used depends on the extension. Typically an extension that does not require external libraries uses --enable. To be sure, run the following after buildconf:

$ ./configure --help | grep extname


Rozdział 8. Problems?

Read the FAQ

Some problems are more common than others. The most common ones are listed in the PHP FAQ, part of this manual.


Other problems

If you are still stuck, someone on the PHP installation mailing list may be able to help you. You should check out the archive first, in case someone already answered someone else who had the same problem as you. The archives are available from the support page on http://www.php.net/support.php. To subscribe to the PHP installation mailing list, send an empty mail to php-install-subscribe@lists.php.net. The mailing list address is php-install@lists.php.net.

If you want to get help on the mailing list, please try to be precise and give the necessary details about your environment (which operating system, what PHP version, what web server, if you are running PHP as CGI or a server module, tryb bezpieczny, etc...), and preferably enough code to make others able to reproduce and test your problem.


Bug reports

If you think you have found a bug in PHP, please report it. The PHP developers probably don't know about it, and unless you report it, chances are it won't be fixed. You can report bugs using the bug-tracking system at http://bugs.php.net/. Please do not send bug reports in mailing list or personal letters. The bug system is also suitable to submit feature requests.

Read the How to report a bug document before submitting any bug reports!


Rozdział 9. Runtime Configuration

The configuration file

The configuration file (called php3.ini in PHP 3, and simply php.ini as of PHP 4) is read when PHP starts up. For the server module versions of PHP, this happens only once when the web server is started. For the CGI and CLI version, it happens on every invocation.

php.ini is searched in these locations (in order):

  • SAPI module specific location (PHPIniDir directive in Apache 2, -c command line option in CGI and CLI, php_ini parameter in NSAPI, PHP_INI_PATH environment variable in THTTPD)

  • HKEY_LOCAL_MACHINE\SOFTWARE\PHP\IniFilePath (Windows Registry location)

  • The PHPRC environment variable

  • Current working directory (for CLI)

  • The web server's directory (for SAPI modules), or directory of PHP (otherwise in Windows)

  • Windows directory (C:\windows or C:\winnt) (for Windows), or --with-config-file-path compile time option

If php-SAPI.ini exists (where SAPI is used SAPI, so the filename is e.g. php-cli.ini or php-apache.ini), it's used instead of php.ini. SAPI name can be determined by php_sapi_name().

Notatka: The Apache web server changes the directory to root at startup causing PHP to attempt to read php.ini from the root filesystem if it exists.

The php.ini directives handled by extensions are documented respectively on the pages of the extensions themselves. The list of the core directives is available in the appendix. Probably not all PHP directives are documented in the manual though. For a complete list of directives available in your PHP version, please read your well commented php.ini file. Alternatively, you may find the the latest php.ini from CVS helpful too.

Przykład 9-1. php.ini example

; any text on a line after an unquoted semicolon (;) is ignored
[php] ; section markers (text within square brackets) are also ignored
; Boolean values can be set to either:
;    true, on, yes
; or false, off, no, none
register_globals = off
track_errors = yes

; you can enclose strings in double-quotes
include_path = ".:/usr/local/lib/php"

; backslashes are treated the same as any other character
include_path = ".;c:\php\lib"

Since PHP 5.1.0, it is possible to refer to existing .ini variables from within .ini files. Example: open_basedir = ${open_basedir} ":/new/dir".


How to change configuration settings

Running PHP as an Apache module

When using PHP as an Apache module, you can also change the configuration settings using directives in Apache configuration files (e.g. httpd.conf) and .htaccess files. You will need "AllowOverride Options" or "AllowOverride All" privileges to do so.

With PHP 4 and PHP 5, there are several Apache directives that allow you to change the PHP configuration from within the Apache configuration files. For a listing of which directives are PHP_INI_ALL, PHP_INI_PERDIR, or PHP_INI_SYSTEM, have a look at the List of php.ini directives appendix.

Notatka: With PHP 3, there are Apache directives that correspond to each configuration setting in the php3.ini name, except the name is prefixed by "php3_".

php_value name value

Sets the value of the specified directive. Can be used only with PHP_INI_ALL and PHP_INI_PERDIR type directives. To clear a previously set value use none as the value.

Notatka: Don't use php_value to set boolean values. php_flag (see below) should be used instead.

php_flag name on|off

Used to set a boolean configuration directive. Can be used only with PHP_INI_ALL and PHP_INI_PERDIR type directives.

php_admin_value name value

Sets the value of the specified directive. This can not be used in .htaccess files. Any directive type set with php_admin_value can not be overridden by .htaccess or virtualhost directives. To clear a previously set value use none as the value.

php_admin_flag name on|off

Used to set a boolean configuration directive. This can not be used in .htaccess files. Any directive type set with php_admin_flag can not be overridden by .htaccess or virtualhost directives.

Przykład 9-2. Apache configuration example

<IfModule mod_php5.c>
  php_value include_path ".:/usr/local/lib/php"
  php_admin_flag safe_mode on
</IfModule>
<IfModule mod_php4.c>
  php_value include_path ".:/usr/local/lib/php"
  php_admin_flag safe_mode on
</IfModule>
<IfModule mod_php3.c>
  php3_include_path ".:/usr/local/lib/php"
  php3_safe_mode on
</IfModule>

Uwaga!

PHP constants do not exist outside of PHP. For example, in httpd.conf you can not use PHP constants such as E_ALL or E_NOTICE to set the error_reporting directive as they will have no meaning and will evaluate to 0. Use the associated bitmask values instead. These constants can be used in php.ini


Changing PHP configuration via the Windows registry

When running PHP on Windows, the configuration values can be modified on a per-directory basis using the Windows registry. The configuration values are stored in the registry key HKLM\SOFTWARE\PHP\Per Directory Values, in the sub-keys corresponding to the path names. For example, configuration values for the directory c:\inetpub\wwwroot would be stored in the key HKLM\SOFTWARE\PHP\Per Directory Values\c\inetpub\wwwroot. The settings for the directory would be active for any script running from this directory or any subdirectory of it. The values under the key should have the name of the PHP configuration directive and the string value. PHP constants in the values are not parsed. However, only configuration values changeable in PHP_INI_USER can be set this way, PHP_INI_PERDIR values can not.


Other interfaces to PHP

Regardless of how you run PHP, you can change certain values at runtime of your scripts through ini_set(). See the documentation on the ini_set() page for more information.

If you are interested in a complete list of configuration settings on your system with their current values, you can execute the phpinfo() function, and review the resulting page. You can also access the values of individual configuration directives at runtime using ini_get() or get_cfg_var().


Rozdział 10. Podstawowa składnia

Wyskakiwanie z HTMLa

Kiedy PHP zaczyna przetwarzać plik, po prostu wyświetla tekst, który napotka. Zatem, jeśli zmienisz rozszerzenie pliku HTML na .php, ten plik będzie działał nadal.

Jeśli chcesz wstawić komendy PHP w jakimś miejscu w swoim dokumencie musisz to zasygnalizować, wchodząc w "tryb PHP" którymś ze sposobów podanych poniżej:

Przykład 10-1. Możliwości wyskoczenia z HTMLa

1.  <? echo ("To jest najprostszy test, instrukcja SGML\n"); ?>
    <?= wyrażenie ?> To jest skrót takiej formy: "<? echo wyrażenie ?>"

2.  <?php echo("Jeśli chcesz używać dokumentów XHTML i XML, rób to tak\n"); ?>

3.  <script language="php">
	echo ("Niektóre edytory (jak FrontPage)
	      nie lubią instrukcji wchodzących w 'tryb PHP'");
    </script>

4.  <% echo ("Możesz także użyć znaczników w stylu ASP"); %>
    <%= $variable; # To jest skrót takiej formy: "<%echo .." %>

Pierwszy sposób jest dostępny tylko kiedy zostały włączone krótkie znaczniki. Można to zrobić wpisując short_open_tag do pliku konfiguracyjnego PHP albo kompilując PHP dodając --enable-short-tags do configure.

Drugi sposób jest preferowany, zapewnia on następnej generacji XHTMLa łatwą implementację w PHP.

Czwarty sposób jest dostępny tylko kiedy znaczniki ASP zostały włączone poprzez uaktywnianie opcji konfiguracyjnej asp_tags.

Notatka: Obsługa dla znaczników ASP została dodana w wersji 3.0.4.

Znacznik zamykający blok będzie dodawał końcową nową linię, jeśli taka istnieje.

PHP pozawala ci używać takich struktur:

Przykład 10-2. Zaawansowane wyskakiwanie

<?php

if (wyrazenie-logiczne) {
    ?>
<strong>prawda </strong>
    <?php
} else {
    ?>
<strong>fałsz </strong>
    <?php
}
    ?>
Powyższy kod działa, ponieważ PHP traktuje tekst pomiędzy ?> i <?php jak gdyby była to funkcja echo().


Oddzielanie instrukcji

Instrukcje są oddzielane tak samo jak w C czy Perlu - należy kończyć każde wyrażenie średnikiem.

Znacznik zamykający (?>) także kończy instrukcję, więc poniższe przykłady są równoważne:

<?php
    echo "To jest test";
?>

<?php echo "To jest test" ?>


Komentarze

PHP obsługuje komentarze w stylu C, C++ oraz komentarze używane w powłokach uniksowych ("#"):

<?php
    echo "To jest test"; // to jest kometarz jednoliniowy w stylu C++
    /* to jest komentarz wieloliniowy
       a tutaj inna komentowana linia */
    echo "To jest jeszcze jeden test";
    echo "Ostatni test"; # to jest kometarz w stylu shell'a
?>

Komentarze typu jednoliniowego mają zasięg do końca linii w której się znajdują lub do końca bloku kodu PHP, zależnie co wystąpi pierwsze.

<h1>To jest <?php # echo "prosty";?> przykład.</h1>
<p>Powyższy kod wypisze zdanie "To jest przykład."

Pownieneś uważać by nie zagnieżdżać komentarzy w stylu C++ (szczególnie komentarzy wieloliniowych), co może się stać kiedy komentujesz dłuższy blok kodu.

<?php
 /*
    echo "To jest test"; /* ten komentarz spowoduje problem */
 */
?>


Rozdział 11. Typy danych

Wstęp

PHP obsługuje osiem typów prostych.

Cztery skalarne:

Dwa typy złożone:

Oraz dwa typy specjalne:

Notatka: W tym podręczniku często pojawia się typ mixed. Ten pseudotyp wskazuje na możliwość użycia danych różnego typu.

Typ danych zwykle nie jest ustalany przez programistę. Robi to PHP na podstawie kontekstu, w jakim zmienna jest używana.

Notatka: Aby sprawdzić typ i wartość konkretnego wyrażenia, należy użyć funkcji var_dump().

Aby mieć czytelną reprezentację typu dla potrzeb debugowania, należy użyć funkcji gettype(). Aby sprawdzić, czy zmienna jest jakiegoś konkretnego typu, nie używaj funkcji gettype(), tylko grupy funkcji is_jakiś_typ.

Aby narzucić konwersję zmiennej do określonego typu, można albo rzutować zmienną, albo użyć funkcji settype().

Proszę pamiętać, że w pewnych sytuacjach zmienne mogą się zachowywać różnie, w zależności od tego, jakiego typu są w danej chwili. Więcej informacji w rozdziale wykorzystywanie typów danych.


Zmienne Logiczne (Boolowskie - boolean)

Ten rodzaj jest najprostszy. Typ boolean wyraża logiczną prawdę lub fałsz. Może mieć wartości TRUE lub FALSE.

Notatka: Typ boolowski został wprowadzony w PHP 4.


Składnia

Aby utworzyć wartość boolowską, należy użyć słów kluczowych TRUE lub FALSE. Wielkość liter w tych słowach nie gra roli.

$foo = True; // przypisanie wartości logicznej prawda do $foo

Ten typ najczęściej używany jest przy operatorach, które zwracają wartość typu boolean, którą następnie przekazuje się do struktur kontrolnych.

// == jest operatorem, który zwraca wartość boolowską
if ($akcja == "pokaż_wersję") {
    echo "Wersja 1.23";
}

// to nie jest konieczne:
if ($pokaż_separatory == TRUE) {
    echo "<hr>\n";
}

// gdyż wystarczy tak:
if ($pokaż_separatory) {
    echo "<hr>\n";
}


Konwersja do typu boolowskiego

Aby jawnie skonwertować wartość na typ boolean, należy użyć rzutowania (bool) lub (boolean). Jednakże w większości przypadków nie ma potrzeby użycia rzutowania, ponieważ wartość będzie automatycznie skonwertowana na typ boolean, jeśli operator, funkcja lub struktura kontrolna wymaga argumentu tego właśnie typu.

Zobacz też wykorzysytwanie typów danych.

Przy konwersji na typ boolean, poniższe wartości otrzymują wartość logiczną FALSE:

Każda inna wartość otrzymuje logiczną wartość TRUE (włączając w to identyfikatory zasobów).

Ostrzeżenie

-1 także ma wartość TRUE, jak każda niezerowa (ujemna lub dodatnia) liczba!


Liczby całkowite (integer)

Typ integer to liczba całkowita, należąca do przedziału Z = {..., -2, -1, 0, 1, 2, ...}.

Zobacz też: Liczby całkowite dużej wielkości oraz Liczby zmiennoprzecinkowe


Składnia

Liczby całkowite mogą być zapisane w notacji dziesiętnej (opartej na 10), szesnastkowej (opartej na 16) lub ósemkowej (opartej na 8), opcjonalnie poprzedzone znakiem (- lub +).

Aby zapisać liczbę w notacji ósemkowej, należy poprzedzić właściwą liczbę symbolem 0 (zero). W notacji szesnastkowej liczbę należy poprzedzić symbolem 0x.

Przykład 11-1. Notacja liczb całkowitych

$a = 1234; # liczba dziesiętna
$a = -123; # ujemna liczba dziesiętna
$a = 0123; # liczba ósemkowa (odpowiednik dziesiętnej 83)
$a = 0x1A; # liczba szesnastkowa (odpowiednik dziesiętnej 26)
Maksymalna wielkość liczby całkowitej jest zależna od platformy operacyjnej, zwykle jest to około dwa miliardy (jest to 32 bity ze znakiem). PHP nie obsługuje liczb całkowitych bez znaku.


Wyjście poza zakres liczb całkowitych

W przypadku zapisania liczby całkowitej wykraczającej poza zakres typu integer, liczba ta zostanie potraktowana jako typ float. Również jeśli rezultat operacji będzie wykraczał poza typ integer, jako wynik zostanie zwrócony typ float.

$duża_liczba =  2147483647;
var_dump($duża_liczba);
// wynik: int(2147483647)

$duża_liczba =  2147483648;
var_dump($duża_liczba);
// wynik: float(2147483648)

// tak samo dzieje się przy wartościach szesnastkowych:
var_dump( 0x80000000 );
// wynik: float(2147483648)

$million = 1000000;
$duża_liczba =  50000 * $million;
var_dump($duża_liczba);
// wynik: float(50000000000)

Ostrzeżenie

Niestety, błąd w PHP powodował czasem nieprawidłową pracę z liczbami ujemnymi. Na przykład: wynikiem działania -50000 * $million była liczba -429496728. Błąd ten pojawiał się tylko przy liczbach ujemnych i nie dotyczył wartości dodatnich.

Powyższy problem został rozwiązany w PHP 4.1.0.

W PHP nie ma operatora dzielenia całkowitego. 1/2 daje wynik typu float o wartości 0.5.

var_dump( 25/7 );
// wynik: float(3.5714285714286)


Konwersja na liczby całkowite

Do jawnej konwersji wartości na typ integer używa się operatora rzutowania (int) lub (integer). W większości przypadków jednak rzutowanie nie jest potrzebne, gdyż wartość zostanie skonwertowana automatycznie, o ile operator, funkcja lub struktura kontrolna wymaga argumentu typu integer.

Zobacz też wykorzystywanie typów danych.


Z boolowskiej

FALSE będzie mieć wartość 0 (zero), a TRUE będzie mieć wartość 1 (jeden).


Z liczb zmiennoprzecinkowych

Przy konwersji z liczb zmiennoprzecinkowych do całkowitych, liczba zostanie zaokrąglona w dół.

Jeśli liczba zmiennoprzecinkowa jest poza zakresem liczb całkowitych, (zwykle +/- 2.15e+9 = 2^31), wynik operacji rzutowania jest niezdefiniowany, ponieważ liczba zmiennoprzecinkowa nie ma odpowiedniej precyzji, aby zwrócić dokładną liczbę całkowitą. W tej sytuacji nie pojawi się żadne ostrzeżenie ani informacja odnośnie powstałego błędu!

Ostrzeżenie

Nigdy nie należy rzutować nieznanego ułamka do typu integer, gdyż może to doprowadzić do otrzymania nieprzewidywalnych wyników.

echo (int) ( (0.1+0.7) * 10 ); // wyświetla 7!

Więcej informacji na ten temat w rozdziale precyzja liczb zmiennoprzecinkowych.


Z innych typów

Uwaga!

Wynik konwersji do liczb całkowitych z innych typów jest nieokreślony. Obecnie zachowanie jest takie samo, jakby zmienna została najpierw skonwertowana do typu boolowskiego. Nie należy jednak polegać na tym zachowaniu, gdyż może ono ulec zmianie bez żadnego ostrzeżenia.


Liczby zmiennoprzecinkowe (float)

Liczby zmiennoprzecinkowe (typ float, double lub liczby rzeczywiste) mogą być zapisane przy użyciu dowolnej z poniższych składni:
$a = 1.234; $a = 1.2e3; $a = 7E-10;
Maksymalna wielkość liczby zmiennoprzecinkowej jest zależna od platformy operacyjnej, zwykle jest to ~1.8e308, przy precyzji 14 liczb dziesiętnych po przecinku (jest to 64 bitowy format IEEE).

Precyzja liczb zmiennoprzecinkowych

Jest oczywiste, że nawet proste ułamki dziesiętne, takie jak 0.1 lub 0.7, nie mogą zostać skonwertowane na ich dwójkowe odpowiedniki bez niewielkiej straty dokładności. Może to powodować pewne problemy: na przykład wyrażenie floor((0.1+0.7)*10) zwykle ma wartość 7, zamiast oczekiwanej 8, gdyż wewnętrzna reprezentacja tego wartości to liczba 7.9999999999....

Powiązane jest to z faktem, że dla pewnych ułamków zwykłych nie istnieje skończone rozwinięcie dziesiętne. Na przykład 1/3 w reprezentacji dziesiętnej ma wartość 0.3333333. . ..

Dlatego nigdy nie należy wierzyć liczbom zmiennoprzecinkowym do ostatniej cyfry i nigdy nie należy wykonywać operacji porównania na stwierdzenie równości. Do operacji na liczbach zmiennoprzecinkowych o naprawdę dużej precyzji należy użyć biblioteki BCMath lub funkcji gmp.


Łańcuchy znaków (string)

Typ string oznacza łańcuch znaków. W PHP znak jest tym sam co bajt, co oznacza, że jest możliwych 256 różnych znaków. Oznacza to także, że PHP nie posiada żadnej wbudowanej obsługi Unikodu.

Notatka: Nie ma technicznych problemów, które utrudniałyby tworzenie bardzo długich ciągów znaków. Nie ma też ustalonej maksymalnej długości łańcuchów znaków obsługiwanych w PHP, więc nie ma powodu do obaw, że dany łańcuch jest zbyt długi.


Składnia

Łańcuch znaków można utworzyć na trzy sposoby.


Pojedyncze cudzysłowy

Najprostszym sposóbem na zdefiniowanie prostego łańcucha znaków, jest umieszczenie go w pojedynczych cudzysłowach (znak ').

Aby w takim łańcuch umieścić symbol pojedynczego cudzysłowu, należy go poprzedzić ukośnikiem wstecznym (\), tak jak w wielu innych językach programowania. Jeśli ukośnik wsteczny ma wystąpić przed symbolem pojedynczego cudzysłowu lub na końcu łańcucha, wtedy należy napisać go dwukrotnie. W przypadku użycia ukośnika wstecznego z innym znakiem, ukośnik też zostanie wyświetlony! Nie ma zatem potrzeby pisania ukośnika dwukrotnie w innych sytuacjach.

Notatka: W PHP 3, ostrzeżenie na poziomie E_NOTICE zostanie wyświetlone, jeśli zajdzie powyższa sytuacja.

Notatka: W przeciwieństwie do dwóch pozostałych składni, zmienne nie będą zamienione na swoje wartości, kiedy pojawią się pomiędzy pojedynczymi cudzysłowami.

echo 'przykładowy tekst';
echo 'Wewnątrz łańcuchów znaków mogą się znajdować przełamania linii,
o właśnie takie.';
echo 'Adam powiedział: "I\'ll be back"';
// wynik: ... "I'll be back"
echo 'Czy na pewno chcesz skasować C:\\*.*?';
// wynik: ... skasować C:\*.*?
echo 'Czy na pewno chcesz skasować C:\*.*?';
// wynik: ... skasować C:\*.*?
echo 'Próbuję w tym miejscu wprowadzić: \n znak nowej linii';
// wynik: ... wprowadzić: \n znak nowej linii


Podwójne cudzysłowy

Kiedy łańcuch znaków jest umieszczony pomiędzy podwójnymi cudzysłowami, PHP interpretuje więcej sekwencji cytowania dla znaków specjalnych:

Tabela 11-1. Znaki cytowane (specjalne)

sekwencjaznaczenie
\nnowa linia (LF lub 0x0A (10) w ASCII)
\rpowrót karetki (CR lub 0x0D (13) w ASCII)
\ttabulacja pozioma (HT lub 0x09 (9) w ASCII)
\\odwrotny ukośnik
\$znak dolara
\"cudzysłów podwójny
\[0-7]{1,3} sekwencja znaków pasująca do powyższego wyrażenia regularnego daje znak zapisany w notacji ósemkowej
\x[0-9A-Fa-f]{1,2} sekwencja znaków pasująca do powyższego wyrażenia regularnego daje znak zapisany w notacji szesnastkowej

Tak jak w poprzedniej składni, zapisanie ukośnika wstecznego przed każdym innymi znakiem spowoduje wyświetlenie zarówno ukośnika, jak i znaku.

Ale najważniejszą właściwością podwójnych cudzysłowów jest to, że zapisane w nich zmienne zostaną zamienione na ich wartości. Więcej informacji w rozdziale parsowanie łańcuchów znaków.


Składnia Heredoc

Jeszcze jednym sposobem na zapisanie łańcucha znaków jest użycie skladni heredoc ("<<<"). Po operatorze <<< powinno się umieścić identyfikator i takim samym identyfikatorem trzeba zakończyć łańcuch znaków.

Identyfikator zamykający musi zaczynać się w pierwszej kolumnie nowej linii. Identyfikator musi też podlegać regułom nazewnictwa w PHP: musi się składać wyłącznie z alfanumerycznych znaków oraz znaku podkreślenia i musi zaczynać się od litery lub znaku podkreślenia.

Ostrzeżenie

Ważne by pamiętać, że linia zawierająca identyfikator zamykający nie może zawierać żadnych innych znaków, z wyjątkiem średnika (;). Znaczy to przede wszystkim, że identyfikator zamykający nie może być wcinany, i nie może być żadnych spacji ani tabulacji przed lub za średnikiem.

Najbardziej dokuczliwym ograniczeniem jest to, że wewnątrz tego łańcucha znaków nie może być znaku powrotu karetki (\r) na końcu linii, jedynie znak nowej linii (\n). Ponieważ Microsoft Windows używa jako znaku końca linii sekwencji \r\n, łańcuchy znaków zapisne w składni heredoc mogą nie działać, jeśli skrypt zostanie napisany w edytorze windowsowym. Na szczęście większość edytorów tekstowych udostępnia możliwość zapisania pliku w uniksowym formacie końca linii.

Składnia heredoc zachowuje się podobnie jak tekst w cudzysłowach podwójnych. Oznacza to też, ze nie ma potrzeby cytowania cudzysłowów w tej składni, ale nadal można używać znaków cytowanych, opisanych powyżej. W tej składni nazwa zmiennej zamieniana jest na jej wartość, ale należy zachować ostrożność przy zapisie złożonych zmiennych razem z tekstem.

Przykład 11-2. Przykład składni heredoc

<?php
$str = <<<EOD
Przykład łańcucha znaków,
zajmującego kilka linii,
zapisanego w składni heredoc.

Przykładowe zastosowanie w przezentacji liryki.

Litwo! Ojczyzno moja! ty jesteś jak zdrowie;
Ile cię trzeba cenić, ten tylko się dowie,
Kto cię stracił. Dziś piękność twą w całej ozdobie
Widzę i opisuję, bo tęsknię po tobie.
\tAdam Mickiewicz - Pan Tadeusz
EOD;

/* Bardziej złożony przykład, ze zmiennymi */
class foo
{
    var $foo;
    var $bar;

    function foo()
    {
        $this->foo = 'Foo';
        $this->bar = array('Bar1', 'Bar2', 'Bar3');
    }
}

$foo = new foo();
$name = 'MojeImię';

echo <<<EOT
Nazywam się "$name". Wyświetlam $foo->foo.
A teraz wyświetlam z tablicy: {$foo->bar[1]}.
Po dwukropku powinien pojawić się znak 'A': \x41
EOT;
?>

Notatka: Obsługa składni heredoc została dodana w PHP 4.


Parsowanie zmiennych

Kiedy łańcuch znaków jest zapisany w cudzysłowach podwójnych lub w składni heredoc, zawarte w nim nazwy zmiennych są parsowane, tzn. zamieniane na ich wartości.

Są dwa rodzaje składni, prosta i złożona. Składnia prosta jest najbardziej popularna i najwygodniejsza, pozwala na parsowanie zmiennej, wartości z tablicy oraz właściwości obiektu.

Składnia złożona pojawiła się w PHP 4, i można ją rozpoznać po nawiasach klamrowych, otaczających wyrażenie.


Składnia prosta

Jeśli wewnątrz zmiennej pojawi się znak dolara ($), parser pobierze tyle znaków, ile tylko się da, aby utworzyć poprawną nazwę zmiennej. Aby jawnie określić koniec nazwy zmiennej, należy ją zapisać w klamrach.

$beer = 'Heineken';
echo "$beer's taste is great"; /* działa, "'" nie jest poprawnym znakiem nazwy
zmiennej*/
echo "He drunk some $beers"; /* nie działa, 's' jest poprawnym znakiem nazwy
zmiennej*/ 
echo "He drunk some ${beer}s"; // działa

Podobnie działa parsowanie elementu tablicy lub właściwości obiektu. Dla tablic, prawy nawias prostokątny (]) oznacza koniec indeksu. Dla właściwości obiektu obowiązują te same reguły jak dla zwykłych zmiennych, jednak nie działają tu opisane powyżej sztuczki ze zmiennymi.

$owoce = array( 'truskawka' => 'czerwona' , 'banan' => 'żółty' );

// zauważ że to działa inaczej poza cudzysłowami
echo "Banan jest $owoce[banan].";

echo "Kwadrat ma szerokość $kwadrat->szerokość metrów.";

// Nie działa. Trzeba tu zastosować składnię złożoną
echo "Kwadrat ma szerokość $kwadrat->szerokość00 centymetrów.";

Do wyrażeń bardziej skomplikowanych należy używać składni złożonej.


Składnia złożona

Nazwa tej składni nie pochodzi od skomplikowanego zapisu, tylko od możliwości obsługi bardziej złożonych wyrażeń.

Za pomocą tej składni można umieszczać w łańcuchach znaków każdą wartość istniejącą w przestrzeni nazw. Odpowiednie wyrażenie pisze się tak, jakby miało ono znajdować się gdziekolwiek poza łańcuchem znaków, a potem tylko umieszcza się je między { i }. Ponieważ nie można cytować "{", składnia ta będzie prawidłowo rozpoznana tylko wtedy, kiedy $ znajduje się bezpośrednio za {. (Użyj "{\$" lub "\{$" aby uzyskać "{$"). Poniżej kilka przykładów:

$fajne = 'fantastyczne';
echo "To jest { $fajne}"; // nie działa, zwraca: To jest { fantastyczne}
echo "To jest {$fajne}";  // działa, zwraca: To jest fantastyczne
echo "Kwadrat ma szerokość {$kwadrat->szerokość}00 centimetrów."; 
echo "To działa: {$arr[4][3]}";     

// Tak jest źle z tego samego powodu
// co $foo[bar] poza łańcuchem. 
echo "Tak jest źle: {$arr[foo][3]}"; 

echo "Prawidłowo jest tak: {$arr['foo'][3]}";
echo "Można nawet pisać tak: {$obj->wartości[3]->nazwa}";
echo "To jest wartość zmiennej o nazwie $nazwa: {${$nazwa}}";


Indeksowanie łańcucha (ofsety)

Dostęp do pojedynczego znaku łańcucha jest możliwy po podaniu jego indeksu (ofsetu) w nawiasach klamrowych, zaraz po nazwie zmiennej. Pierwszy znak w łańcuchu ma indeks zero.

Notatka: Dla zachowania kompatybilności wstecznej, nadal można używać nawiasów kwadratowych, jednak składnia ta w PHP 4 uznana jest za przestarzałą.

Przykład 11-3. Przykłady używania łańcuchów znaków

<?php
/* Przypisywanie łańcucha do zmiennej */
$str = "To jest łańcuch znaków";

/* Dołączanie innego łańcucha */
$str = $str . " a to jego dalsza część";

/* inny sposób dołączania, ze znakiem nowej linii na końcu */
$str .= " wraz ze znakiem nowej linii na końcu.\n";

/* Ten łańcuch będzie zawierać: "<p>Liczba: 9</p>" */
$num = 9;
$str = "<p>Liczba: $num</p>";

/* Natomiast tutaj będzie: "<p>Liczba: $num</p>" */
$num = 9;
$str = '<p>Liczba: $num</p>';

/* Pobranie pierwszego znaku łańcucha  */
$str = 'To jest przykład.';
$pierwszy = $str{0};

/* Ostatni znak łańcucha */
$str = 'Dalsza część przykładu.';
$ostatni = $str{strlen($str)-1};
?>


Przydatne funkcje i operatory

Łańcuchy znaków łączy się za pomocą operatora '.' (kropka). Proszę pamiętać, że operator dodawania '+' nie wykonuje operacji łączenia łańcuchów. Więcej informacji w rozdziale operatory łańcuchowe.

PHP posiada mnóstwo funkcji operujących na łańcuchach znaków.

Najwięcej na ten temat w rozdziale funkcje łańcuchowe. Poza tym obsługiwane są wyrażenia regularne dla potrzeb zaawnsowanych operacji znajdź i zamień (w dwóch odmianach: Perl oraz POSIX extended).

Są także funkcje obsługi łańcuchów URL, jak również funkcje szyfrowania i deszyfrowania łańcuchów (mcrypt oraz mhash).

Jeśli nadal nie znalazłeś tego, czego potrzebujesz, być może pomogą ci funkcje kontroli typu znaków.


Konwersja łańcuchów znaków

Jeśli łańcuch znaków jest konwertowany na postać liczbową, rezultat konwersji będzie zależał od poniższych czynników.

Łańcuch zostanie skonwertowany do typu float, jeśli zawiera znaki ".", "e" lub "E". W przeciwnym razie zostanie skonwertowany do typu integer.

Wartość liczbowa łańcucha znaków zależy od pierwszych znaków tego łańcucha. Jeśli łańcuch zaczyna się od poprawnej wartości liczbowej, wartość ta będzie używa przy konwersji. W przeciwnym razie zwrócona będzie wartość 0 (zero). Poprawna wartość liczbowa zaczyna się od opcjonalnego znaku, po którym znajduje się jedna, lub kilka cyfr (opcjonalnie zawierające przecinek dziesiętny), po którym opcjonalnie znajduje się eksponent. Eksponent jest to znak "e" lub "E", po którym następuje jedna, lub więcej cyfr.

Kiedy pierwszym wyrażeniem jest łańcuch znaków, typ zmiennej będzie zależał od drugiego wyrażenia.

$foo = 1 + "10.5";              // $foo jest typu float (11.5)
$foo = 1 + "-1.3e3";            // $foo jest typu float (-1299)
$foo = 1 + "bob-1.3e3";         // $foo jest typu integer (1)
$foo = 1 + "bob3";              // $foo jest typu integer (1)
$foo = 1 + "10 małych świnek";    // $foo jest typu integer (11)
$foo = 1 + "10 malutkich świnek"; // $foo jest typu integer (11)
$foo = "10.0 świnek " + 1;        // $foo jest typu float (11)
$foo = "10.0 świnek " + 1.0;      // $foo jest typu float (11)

Więcej informacji na temat tej konwersji znajduje się w podręczniku Uniksa, na stronie polecenia strtod(3).

Jeśli chciałbyś przetestować któryś z przykładów w tym rozdziale, możesz je skopiować i wkleić, a następnie dodać poniższą linię i obserwować rezultaty.

echo "\$foo==$foo; jest typu " . gettype ($foo) . "<br>\n";


Tablice (array)

Tablica w PHP jest obecnie uporządkowaną mapą. Mapa jest typem, który przyporządkowuje wartości do kluczy. Typ ten jest optymalizowany na wiele sposobów, więc można go używać jako typową tablicę, albo listę (wektorową), tablicę asocjacyjną (która jest jedną z implementacji mapy), słownik, kolekcję, stos, kolejkę, i temu podobne. Ponieważ wartością tablicy może być inna tablica PHP, można także łatwo symulować drzewa.

Wyjasnienie wspomnianych struktur wykracza poza problematykę tego podręcznika, aczkolwiek poniżej uwzględniono conajmniej jeden przykład na każdą z nich. Głębiej zainteresowanych czytelników odsyłamy do odpowiedniej literatury informatycznej.


Składnia

Tworzenie za pomocą array()

Tablicę można utworzyć za pomocą konstrukcji językowej array(). Argumentem tej konstrukcji są rozdzielone przecinkiem pary klucz => wartość.

klucz może być albo nieujemną liczbą całkowitą, albo łańcuchem znaków. Jeśli klucz jest standardową reprezentacją nieujemnej liczby całkowitej, zostanie zinterpretowany tak, jak jest (tzn. '8' będzie zinterpretowane jako 8, podczas gdy '08' będzie zinterpretowane jako '08').

Wartością może być cokolwiek.

Jeśli pominiesz klucz, to jako klucz zostanie użyty najwyższy indeks całkowity + 1. Jeśli nie ma w ogóle indeksu całkowitego, to klucz będzie miał wartość 0 (zero). Jeśli użyjesz klucza, do którego już wcześniej została przypisana wartość, wartość ta zostanie nadpisana.

array( [klucz =>]
wartość
     , ...
     )
// klucz jest albo łańcuchem znaków, albo nieujemną
                                    liczbą całkowitą
// wartość może być dowolna


Tworzenie i edytowanie składnią nawiasów kwadratowych

Można zmieniać istniejącą tablicę jawnie ustawiając wartości.

Robi się to przez przypisanie wartości do tablicy z podaniem klucza w nawiasach kwadratowych. Można także pominąć klucz i użyć pustej pary nawiasów ("[]").
$arr[klucz] = wartość;
$arr[] = wartość;
// klucz jest albo łańcuchem znaków, albo nieujemną
                                    liczbą całkowitą
// wartość może być dowolna
Jeśli tablica $arr nie istnieje, zostanie stworzona. Jest to więc metoda na tworzenie tablic. Aby zmienić wartość konkretnego klucza, po prostu przypisz nową wartość do niego. Aby usunąć parę klucz/wartość, trzeba użyć funkcji unset().


Przydatne funkcje

Jest wiele przydatnych funkcji obsługi tablic, o czym więcej w rozdziale Tablice.

Notatka: Funkcja unset() pozwala kasować komórki tablicy. W takiej sytuacji jednak tablica NIE zostanie zreindeksowana.

$a = array( 1 => 'jeden', 2 => 'dwa', 3 => 'trzy' );
unset( $a[2] );
/* to tak, jakby utworzyć tablicę:
   $a = array( 1 => 'jeden', 3 => 'trzy');
   ale NIE:
   $a = array( 1 => 'jeden', 2 => 'trzy');
*/

Struktura kontrolna foreach została stworzona specjalnie dla potrzeb tablic. Dzięki niej można łatwo trawersować tablicę.


Co wolno, a czego nie w tablicach?

Dlaczego zapis $foo[bar] jest niepoprawny?

W starych skryptach można spotkać taką składnię:

$foo[bar] = 'coś';
echo $foo[bar];
// itd.

Ten zapis jest niepoprawny, ale działa. Dlaczego zatem jest niepoprawny? Powód jest to, co opisano w rozdziale składnia, że pomiędzy nawiasami kwadratowymi ('[' i ']') musi znajdować się wyrażenie. Oznacza to, że można używać czegoś takiego:

echo $arr[ foo(true) ];

Jest to przykład użycia wartości zwracanej przez funkcję jako indeksu tablicy. PHP zna też stałe, więc można spotkać zastosowanie E_*.

$opis_błędu[E_ERROR] = "Wystąpił poważny błąd";
$opis_błędu[E_WARNING] = "PHP wysłało ostrzeżenie";
$opis_błędu[E_NOTICE] = "To jest tylko nieformalna uwaga";

Proszę pamiętać, że E_ERROR jest także ważnym identyfikatorem, tak jak bar w pierwszym przykładzie. Ale ostatni przykład znaczy to samo co:

$opis_błędu[1] = "Wystąpił poważny błąd";
$opis_błędu[2] = "PHP wysłało ostrzeżenie";
$opis_błędu[8] = "To jest tylko nieformalna uwaga";

ponieważ E_ERROR znaczy to samo co 1, itd.

W takiem razie, jak to możliwe, że $foo[bar] działa? To działa, ponieważ bar, zgodnie z jego zapisem powinien być stałą. Jednakże w tym przypadku nie instnieje stała o nazwie bar. PHP teraz zakłada, że masz na myśli bar literalnie, czyli jako łańucuch "bar", tylko że zapomniałeś napisać cudzysłowów.


Więc dlaczego tak jest źle?

Kiedyś w przyszłości grupa PHP może chcieć dodać jeszcze jedną stałą lub słowo kluczowe i wtedy będziesz miał kłopot. Dla przykładu, obecnie już nie można używać słów empty i default, gdyż są to specjalne słowa kluczowe.

Poza tym, jeśli dotąd argumenty nie przekonują cię: ta składnia jest po prostu odrzucona i kiedyś może przestać działać.

Notatka: Po przełączeniu error_reporting na E_ALL, zobaczysz, że PHP generuje ostrzeżenie, kiedy tylko powyższa składnia zostanie użyta. Tak samo generowane będą ostrzeżenia odnośnie innych odrzuconych "udogodnień". (umieść w swoim skrypcie linię error_reporting(E_ALL);)

Notatka: Składnia ta jest dozwolona wewnątrz łańcucha znaków w podwójnych cudzysłowach. Więcej szczegółów na ten temat w rozdziale parsowanie zmiennych.


Przykłady

Typ tablicowy w PHP jest bardzo różnorodny, co prezentują poniższe przykłady.

// to:
$a = array( 'kolor' => 'czerowny'
          , 'smak' => 'słodki'
          , 'kształt' => 'okrągły'
          , 'nazwa'  => 'jabłko'
          ,            4        // kluczem będzie 0
          );

// znaczy dokładnie to samo, co to:
$a['kolor'] = 'czerwony';
$a['smak'] = 'słodki';
$a['kształt'] = 'okrągły';
$a['nazwa'] = 'jabłko';
$a[]        = 4;        // kluczem będzie 0

$b[] = 'a';
$b[] = 'b';
$b[] = 'c';
// znaczy to samo co: array( 0 => 'a' , 1 => 'b' , 2 => 'c' ),
// albo prościej: array('a', 'b', 'c')

Przykład 11-4. Użycie array()

// tablica jako mapa właściwości
$mapa = array( 'version'    => 4
            , 'OS'         => 'Linux'
            , 'lang'       => 'polski'
            , 'short_tags' => true
            );
            
// tylko klucze liczbowe
$array = array( 7
              , 8
              , 0
              , 156
              , -10
              );
// znaczy to samo co array( 0 => 7, 1 => 8, ...)

$zmiany = array(            10 // klucz = 0
                  , 5    =>  6
                  , 3    =>  7 
                  , 'a'  =>  4
                  ,         11 // klucz = 6 (najwyższy indeks całkowity był 5)
                  , '8'  =>  2 // klucz = 8 (całkowity!)
                  , '02' => 77 // klucz = '02'
                  , 0    => 12 // wartość 10 będzie nadpisana przez 12
                  );
                  
// pusta tablica
$pusta = array();

Przykład 11-5. Kolekcja

$kolory = array('czerwony','niebieski','zielony','żółty');

foreach ( $kolory as $kolor ) {
    echo "Czy lubisz $kolor?\n";
}

/* wynik:
Czy lubisz czerwony?
Czy lubisz niebieski?
Czy lubisz zielony?
Czy lubisz żółty?
*/

Obecnie nie jest możliwa zmiana wartości w tabeli przy użyciu takiej pętli. Można to jednak rozwiązać tak:

Przykład 11-6. Collection

foreach ($kolory as $klucz => $kolor) {
    // nie działa:
    //$kolor = strtoupper($kolor);
    
    // działa:
    $kolory[$klucz] = strtoupper($kolor);
}
print_r($kolory);

/* wynik:
Array
(
    [0] => CZERWONY
    [1] => NIEBIESKI
    [2] => ZIELONY
    [3] => ŻÓŁTY
)
*/

Poniższy przykład tworzy tablicę z pierwszym kluczem 1.

Przykład 11-7. Pierwszy klucz 1

$kwartał  = array(1 => 'Styczeń', 'Luty', 'Marzec');
print_r($kwartał);

/* wynik:
Array 
(
    [1] => 'Styczeń'
    [2] => 'Luty'
    [3] => 'Marzec'
)
*/

Przykład 11-8. Wypełnianie prawdziwej tablicy

// wypełnij tablicę zawartością folderu
$uchwyt = opendir('.');
while ($plik = readdir($uchwyt)) 
{
    $pliki[] = $plik;
}
closedir($uchwyt);

Dane w tablicach są uporządkowane. Ich kolejność może być zmieniona za pomocą różnorodnych funkcji sortujących. Więcej na ten temat w rozdziale tablice.

Przykład 11-9. Sortowanie tablic

sort($pliki);
print_r($pliki);

Ponieważ wartością tablicy może być wszystko, może też nią być inna tablica. Można w ten sposób tworzyć tablice rekursywne i wielowymiarowe.

Przykład 11-10. Tablice rekursywne i wielowymiarowe

$owoce = array ( "owoce"  => array (   "a" => "pomarańcza"
                                     , "b" => "banan"
                                     , "c" => "jabłko"
                                     )
                , "liczby" => array ( 1
                                     , 2
                                     , 3
                                     , 4
                                     , 5
                                     , 6
                                     )
                , "dziury"   => array (      "pierwsza"
                                     , 5 => "druga"
                                     ,      "trzecia"
                                     )
                );

Obiekty (object)

Inicjowanie obiektów

Aby zainicjować obiekt, należy użyć słowa kluczowego new aby przypisać instancję obiektu do zmiennej.

<?php
class foo
{
    function do_foo()
    {
        echo "Doing foo."; 
    }
}

$bar = new foo;
$bar->do_foo();
?>

Pełna informacja na ten temat znajduje się w rozdziale Klasy i Obiekty.


Identyfikator zasobów (resource)

Identyfikator zasobów jest specjalną zmienną, przechowywującą odnośnik do zewnętrznego źródła zasobów. Identyfikatory zasobów są tworzone i wykorzystywane przez specjalne funkcje. Zobacz suplement z listą tych funkcji i powiązanych z tym typów zasobów.

Notatka: Identyfikator zasobów został wprowadzony w PHP 4.


Zwalnianie zasobów

Dzięki systemowi kontroli zasobów, wprowadzonemu w opracowanym przez Zend silniku skryptowym PHP 4, automatycznie wykrywana jest sytuacja, kiedy nie ma już odnośników do zasobu (tak jak w Java). W takie sytuacji zasoby systemowe używane do tego zasobu zostają zwolnione przez destruktor zasobów. Dlatego nie jest konieczne, aby zwalniać pamięć ręcznie za pomocą funkcji typu free_result.

Notatka: Wyjątkiem są tu stałe połączenia z serwerami baz danych, które nie są niszczone przez destruktor zasobów. Zobacz też stałe połączenia.


Typ NULL (null)

Specjalna wartość NULL oznacza, że zmienna nie przechowuje żadnej wartości. NULL jest jedyną możliwą wartością typu NULL.

Notatka: Typ NULL został wprowadzony w PHP 4.


Składnia

Jest tylko jedna wartość, jaką może mieć typ NULL i jest nią słowo kluczowe NULL. Wielkość liter słowa NULL nie gra roli.

$var = NULL;


Wykorzystywanie typów danych

PHP nie wymaga (a nawet nie obsługuje) jawnej deklaracji typów zmiennych. Typ zmiennej jest określany na podstawie kontekstu, w jakim ta zmienna jest używana. Oznacza to m.in., że przy przypisaniu łańcucha znaków do zmiennej var, zmienna ta zmienia swój typ na string. Jeśli potem zostanie przypisana wartość całkowita, var zmienia swój typ na integer.

Przykładem automatyczniej konwersji typów jest operator dodawania '+'. Jeśli którykolwiek z operandów jest typu float, to wszystkie operandy zostaną potraktowane jako liczby float i taki też typ będzie zwrócony jako wynik dodawania. W przeciwnym razie operandy zostaną potraktowane jako liczby całkowite i wynikiem także będzie liczba całkowita. Proszę jednak zwrócić uwagę, że działanie to NIE zmienia typów samych operandów; zmienia jedynie sposób ich interpretacji przez operator dodawania.

$foo = "0";  // $foo jest łańcuchem znaków (ASCII 48)

$foo += 2;   // $foo jest liczbą całkowitą (2)
$foo = $foo + 1.3;  // $foo jest liczbą zmiennoprzecinkową (3.3)
$foo = 5 + "10 Małych świnek"; // $foo jest liczbą całkowitą (15)
$foo = 5 + "10 Większych świnek";     // $foo jest liczbą całkowitą (15)

Jeśli dwa ostanie przykłady wydają się tobie dziwne, zajrzyj do rozdziału Konwersja łańcuchów znaków.

Jeśli chcesz skonwertować zmienną z jednego typu do innego, użyj rzutowania typów. Aby zmienić typ zmiennej, użyj settype().

Jeśli chcesz przetestować którykolwiek z przykładów z tego rozdziału, możesz użyć funkcji var_dump().

Notatka: Efekty automatycznej konwersji do tablicy są aktualnie nieokreślone.

$a = 1;       // $a jest liczbą całkowitą
$a[0] = "f";  // $a staje się tablicą, $a[0] zawiera "f"

W powyższym przykładzie wydawać się może oczywiste, że $a stanie się tablicą z pierwszym elementem "f"; rozważ jednak poniższy przykład:

$a = "1";     // $a jest łańcuchem znaków
$a[0] = "f";  // Co z ofsetami łańcuchów? Co się dzieje?

Ponieważ PHP obsługuje indeksowanie łańcuchów za pomocą ofsetów, używając tej samej składni co indeksowanie tablic, powyższy przykład powoduje problem: czy $a powinno zostać tablicą z pierwszym elementem o wartości "f", czy raczej "f" powinno zostać pierwszym znakiem łańcucha $a?

Z tego właśnie powodu, od PHP 3.0.12 i PHP 4.0b3-RC4, efekt automatycznej konwersji pozostaje nieokreślony. Dyskusje odnośnie tego problemu trwają.


Rzutowanie typów

Rzutowanie typów w PHP działa mniej więcej tak jak w języku C: nazwa docelowego typu umieszczana jest w nawiasach przed nazwą zmiennej, która ma być zrzutowana.

$foo = 10;   // $foo jest liczbą całkowitą
$bar = (float) $foo;   // $bar jest typu float (zmiennoprzecinkowego)

Operatory rzutowania są następujące:

  • (int), (integer) - rzutowanie do liczb całkowitych

  • (bool), (boolean) - rzutowanie do typu boolowskiego

  • (float), (double), (real) - rzutowanie do liczb zmiennoprzecinkowych

  • (string) - rzutowanie do łańcucha znaków

  • (array) - rzutowanie do tablicy

  • (object) - rzutowanie do obiektu

Notatka: Zamiast rzutować zmienną do łańcucha znaków operatorem, można też umieścić zmienną w cudzysłowie podwójnym.

Wewnątrz nawiasów operatora rzutowania mogą znajdować się tabulacje i spacje, więc poniższe przykłady są funkcjonalnie identyczne:

$foo = (int) $bar;
$foo = ( int ) $bar;

Efekt rzutowania pomiędzy niektórymi typami nie zawsze daje spodziewany wynik. Więcej informacji o skutkach rzutowania w rozdziałach:

Przy rzutowaniu lub wymuszeniu konwersji z tablicy do łańcucha znaków, rezultatem będzie słowo Array. Przy rzutowaniu lub wymuszeniu konwersji z obiektu do łańcucha znaków, rezultatem będzie słowo Object.

Przy rzutowaniu ze zmiennej skalarnej lub łańcucha do tablicy, wartość zmiennej stanie się pierwszym elementem tablicy:

$var = 'ciao';
$arr = (array) $var;
echo $arr[0];  // wynik: 'ciao'

Przy rzutowaniu ze zmiennej skalarnej lub łańcucha do obiektu, wartość zmiennej stanie się właściwością obiektu; właściwość ta będzie nazywać się 'scalar':

$var = 'ciao';
$obj = (object) $var;
echo $obj->scalar;  // wynik: 'ciao'


Rozdział 12. Zmienne

Podstawy

Każdą zmienną w PHP zapisuje się, poprzedzając jej nazwę znakiem dolara "$". Wielkość liter w nazwie zmiennej jest rozróżniana.

Nazw zmiennych dotyczą te same reguły, co innych rodzajów nazw w PHP. Poprawna nazwa zmiennej zaczyna się od litery lub znaku podkreślenia "_", po których może wystąpić dowolna ilość liter, cyfr lub znaków podkreślenia. Jako wyrażenie regularne, można to zapisać tak: '[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*'

Notatka: W naszym rozumieniu, litery to znaki a-z, A-Z i symbole ASCII od 127 do 255 (0x7f-0xff).

$var = "Bob";
$Var = "Joe";
echo "$var, $Var";      // wyświetla "Bob, Joe"

$4site = 'not yet';     // niepoprawna nazwa - zaczyna się od cyfry
$_4site = 'not yet';    // poprawna nazwa - zaczyna się znakiem podkreślenia
$jaźń = 'not yet';    // poprawna nazwa - "ń" i "ź" należą do ASCII > 127

W PHP 3, przypisanie zmiennych jest możliwe tylko przez wartość. Innymi słowy, jeśli przypiszesz do zmiennej jakieś wyrażenie, wartość tego wyrażenia zostanie skopiowana do zmiennej. Oznacza to, że po przypisaniu wartości jednej zmiennej do drugiej, późniejsza zmiana wartości jednej z nich nie spowoduje zmiany wartości drugiej. Więcej informacji na ten temat w rozdziale Wyrażenia.

PHP 4 oferuje jeszcze jeden sposób przypisywania wartości do zmiennych: przypisanie przez referencję. Oznacza to, że nowa zmienna tylko odnosi się (innymi słowy, "staje się aliasem" lub "wskazuje na") do pierwotnej zmiennej. Zmiany wykonane na nowej zmiennej oddziałują także na pierwotną zmienną i vice versa. Ma to też takie znaczenie, że nie następuje żadna operacja skopiowania, czyli przypisanie następuje szybciej. Jednakże wyraźne przyspieszenie działania może być widoczne tylko w pętlach zwartych (ang. tight loops), lub przy przypisywaniu dużych tablic lub obiektów.

Aby przypisać przez referencję, postaw znak ampersand (&) przed nazwą zmiennej przypisywanej (zmiennej od której pobierasz wartość). Na przykład poniższy kod wyświetla "To jest PHP" dwa razy:

<?php
$foo = "PHP";               // Przypisz wartość "PHP" do $foo.
$bar = &$foo;               // Przypisz referencyjnie $foo do $bar.
$bar = "To jest $bar";      // Zmień $bar...

echo $bar;
echo $foo;                  // $foo też się zmieniło.
?>

Należy pamiętać, że tylko wyrażenia posiadające nazwę mogą być przypisane przez referencję.

<?php
$foo = 25;
$bar = &$foo;      // Przypisanie poprawne.
$bar = &(24 * 7);  // Przypisanie niepoprawne - do nienazwanego wyrażenia.

function test()
{
   return 25;
}

$bar = &test();    // Niepoprawne.
?>


Zmienne predefiniowane

PHP udostępnia dla każdego pracującego skryptu dużą ilość predefiniowanych zmiennych. Jednakże wiele spośród tych zmiennych nie może być w pełni objaśnionych, gdyż są zależne od rodzaju serwera, jego wersji i ustawień i innych czynników. Niektóre z tych zmiennych nie będą dostępne dla skryptów PHP uruchomionych z linii poleceń. Lista tych zmiennych znajduje się w rozdziale predefiniowane zmienne.

Ostrzeżenie

W PHP 4.2.0 i późniejszych, domyślne ustawienie, które udostępniało predefiniowane zmienne w zasięgu globalnym, zostało zmienione. Zmienne nadchodzące metodą GET i POST oraz zmienne serwera domyślnie nie są już umieszczane w zasięgu globalnym. Zamiast tego umieszczane są w odpowiednich tablicach superglobalnych.

Nadal można uruchomić udostępnianie tych zmiennych w zasięgu globalnym przez ustawienie dyrektywy konfiguracyjnej register_globals na "On" w pliku php.ini.

Więcej informacji odnośnie tej zmiany, wraz z wyjaśnieniem przyczyn, w PHP 4.1.0 Release Announcement.

Począwszy od wersji 4.1.0, PHP udostępnia zestaw predefiniowanych tablic, które zawierają zmienne serwera, zmienne środowiskowe oraz zmienne użytkownika. Tablice te są dość specyficzne, gdyż są one automatycznie globalne, tzn. automatycznie dostępne w każdym zasięgu. Dlatego nazywa się je "autoglobalami" albo "superglobalami". (W PHP nie ma mechanizmu pozwalającego użytkownikowi na definiowanie własnych superglobali.) Superglobale PHP wymienione są poniżej, jednakże wykaz ich zawartości i głębsze omówienie prefiniowanych zmiennych PHP oraz ich natury znajduje się w rozdziale predefiniowane zmienne.

Superglobale PHP

$GLOBALS

Zawiera referencje do każdej ze zmiennych aktualnie dostępnych w zasięgu globalnym skryptu. Kluczami tablicy są nazwy zmiennych globalnych.

$_SERVER

Zmienne tworzone przez serwer lub bezpośrednio powiązane ze środowiskiem uruchomieniowym danego skryptu. Analogiczna do dawnej tablicy $HTTP_SERVER_VARS (która jest nadal dostępna, ale uznana za przestarzałą).

$_GET

Zmienne dostarczone do skryptu za pomocą metodą GET protokołu HTTP. Analogiczna do dawnej tablicy $HTTP_GET_VARS (która jest nadal dostępna, ale uznana za przestarzałą).

$_POST

Zmienne dostarczone do skryptu metodą POST protokołu HTTP. Analogiczna do dawnej tablicy $HTTP_POST_VARS (która jest nadal dostępna, ale uznana za przestarzałą).

$_COOKIE

Zmienne dostarczone do skryptu przez ciasteczka HTTP. Analogiczna do dawnej tablicy $HTTP_COOKIE_VARS (która jest nadal dostępna, ale uznana za przestarzałą).

$_FILES

Zmienne dostarczone do skryptu przez przesłanie plików do serwera metodą POST protokołu HTTP. Analogiczna do dawnej tablicy $HTTP_POST_FILES (która jest nadal dostępna, ale uznana za przestarzałą). Więcej na ten temat w rozdziale przesyłanie plików metodą POST.

$_ENV

Zmienne dostarczone do skryptu przez środowisko operacyjne. Analogiczna do dawnej tablicy $HTTP_ENV_VARS (która jest nadal dostępna, ale uznana za przestarzałą).

$_REQUEST

Zmienne użytkownika dostarczone do skryptu przez każdy mechanizm wejścia, przez co NIE są one godne zaufania. Uwaga: kiedy skrypt jest uruchomiony z linii poleceń, tablica ta nie zawiera zmiennych argv i argc. Zmienne te są dostępne w tablicy $_SERVER. Obecność i kolejność dołączania zmiennych do tej tablicy zależy od dyrektywy konfiguracyjnej variables_order. Tablica ta nie posiada swoich odpowiedników we wcześniejszych wersjach PHP.

$_SESSION

Zmienne aktualnie zarejestrowane jako sesyjne. Analogiczne do dawnej tablicy $HTTP_SESSION_VARS (która jest wciąż dostępna, ale uznana za przestarzałą). Więcej informacji w rozdziale funkcje obsługi sesji.


Zasięg zmiennych

Zasięg zmiennej jest zależny od miejsca, w jakim została zdefiniowana. Najczęściej zmienne PHP widoczne są tylko w pojedynczym zasięgu. Taki zasięg rozciąga się na pliki dołączane funkcjami include() i require(). Na przykład:

$a = 1;
include "b.inc";

Tutaj zmienna $a będzie dostępna także w dołączonym pliku b.inc. Jednakże w funkcjach zdefiniowanych przez użytkownika zmienne mają zasięg lokalny. Każda zmienna użyta wewnątrz funkcji jest domyślnie ograniczona do zasięgu lokalnego, np.

$a = 1; /* zasięg globalny */ 

function Test()
{ 
    echo $a; /* odwołanie do zmiennej o zasięgu lokalnym */ 
} 

Test();

Ten skrypt nie wyświetli niczego, ponieważ instrukcja echo odwołuje się do zmiennej lokalnej $a, której jak dotąd nie została przypisana żadna wartość. Można tu zauważyć różnicę w stosunku do języka C, gdzie zmienne globalne są zawsze dostępne wewnątrz definicji funkcji, o ile nie zostały nadpisane przez lokalną definicję zmiennej. Może to spowodować taki problem, że ktoś może nieodwracalnie zmienić wartość zmiennej globalnej. W PHP zmienne globalne muszą być jawnie określone jako globalne wewnątrz funkcji, w której mają być użyte, do czego używamy słowa kluczowego global. Na przykład:

$a = 1;
$b = 2;

function Sum()
{
    global $a, $b;

    $b = $a + $b;
} 

Sum();
echo $b;

Powyższy skrypt wyświetli wynik "3". Przez zadeklarowanie wewnątrz funkcji globalności zmiennych $a i $b, wszystkie odwołania do tych zmiennych będą odnosiły się do ich globalnych wersji. Nie ma żadnych ograniczeń w ilości zmiennych globalnych, na których chcemy operować wewnątrz funkcji.

Drugim sposobem uzyskania dostępu do zmiennych globalnych wewnątrz funkcji jest użycie specjalnej, zdefiniowanej przez PHP tablicy $GLOBALS. Powyższy przykład można zatem przepisać tak:

$a = 1;
$b = 2;

function Sum()
{
    $GLOBALS["b"] = $GLOBALS["a"] + $GLOBALS["b"];
} 

Sum();
echo $b;

$GLOBALS jest tablicą asocjacyjną, gdzie nazwa zmiennej jest kluczem, a zawartość zmiennej wartością komórki tablicy.

Jeszcze jedną ważną rzeczą, związaną z zasięgiem zmiennych jest zmienna statyczna (ang. static variable). Zmienna statyczna może mieć wyłącznie zasięg lokalny, ale nie traci swojej wartości, kiedy program opuści ten zasięg lokalny, w którym dana zmienna statyczna się znajduje. Proszę rozważyć poniższy przykład:

function Test ()
{
    $a = 0;
    echo $a;
    $a++;
}

Ta funkcja jest bezużyteczna, gdyż przy każdym jej wywołaniu zmienna $a otrzymuje wartość 0, w związku z czym funkcja stale wyświetla "0". Występująca potem inkrementacja $a++ nie ma żadnego znaczenia, gdyż funkcja się kończy i zmienna $a znika. Aby powyższa funkcja miała jakiś sens, należy zapobiec gubieniu wartości $a, do czego używamy słowa kluczowego static:

function Test()
{
    static $a = 0;
    echo $a;
    $a++;
}

Teraz, za każdym wywołaniem funkcji test, zostanie wyświetlona wartość zmiennej $a, po czym ta zmienna zostanie inkrementowana.

Zmienne statyczne pozwalają też na wykorzystanie funkcji rekurencyjnych, czyli takich, które wywołują same siebie. Funkcje rekurencyjne należy pisać ostrożnie, gdyż łatwo jest wywołać nieskończoną rekurencję. Musisz być pewny, że masz odpowiednie mechanizmy do zatrzymania rekurencji w pewnym momencie. Poniższa funkcja rekurencyjnie liczy do 10, używając zmiennej statycznej $licznik, aby wiedzieć, kiedy ma się zatrzymać:

function Test()
{
    static $licznik = 0;

    $licznik++;
    echo $licznik;
    if ($licznik < 10) {
        Test ();
    }
    $licznik--;
}


Zmienne zmienne

W niektórych przypadkach jest wygodne, by móc użyć zmiennej o zmiennej nazwie. To znaczy zmiennej, której nazwa może być zmieniana dynamicznie. Zwykła zmienna jest ustawiana wyrażeniem jak poniżej:

$a = "witaj";

Zmienna zmienna pobiera wartość jednej zmiennej i traktuje ją jako nazwę zmiennej. W powyższym przykładzie, witaj może stać się nazwą zmiennej, przy użyciu dwóch znaków dolara, tzn.

$$a = "świecie";

W tym momencie dwie zmienne zostały zdefiniowane i umieszczone w drzewie symbolicznym PHP: $a zawierająca "witaj" i $witaj zawierająca "świecie". Zatem poniższy zapis:

echo "$a ${$a}";

znaczy to samo, co:

echo "$a $witaj";

tzn. obydwa wyświetlą: witaj świecie.

Aby używać zmiennych zmiennych jako tablic, trzeba rozwiązać pewną niejasność. Mianowicie, jeśli napiszesz $$a[1], parser musi wiedzieć, czy chesz użyć $a[1] jako nazwy zmiennej, czy $$a jako nazwy tablicy, której rekord [1] cię interesuje. W tym przypadku należy zastosować odrębną składnię: ${$a[1]} dla pierwszego przypadku a ${$a}[1] dla drugiego.

Proszę pamiętać, że zmienne zmienne nie mogą być używane z nowymi superglobalami PHP. Oznacza to, że nie będą działać wyrażenia typu ${$_GET}. Jeśli szukasz sposobu na obsługę osiągalności superglobali i starych tablic $HTTP_*_VARS, spróbuj użyć referencji.


Zmienne spoza PHP

Formularze HTML (GET i POST)

Kiedy do skryptu PHP zostanie wysłany formularz, każda zmienna z tego formularza zostanie automatycznie dostarczona do tego skryptu przez PHP. Jeśli dyrektywa track_vars jest włączona, to zmienne te będą umieszczone w tablicach asocjacyjnych $HTTP_POST_VARS (zmienne wysłane metodą POST), $HTTP_GET_VARS (zmienne wysłane metodą GET), i/lub $HTTP_POST_FILES (plik wysłane metodą POST), w zależności od rodzaju zmiennych w zapytaniu.

Więcej informacji na ten temat w rozdziale Zmienne predefiniowane.

Przykład 12-1. Prosty formularz ze zmienną

<form action="foo.php" method="post">
    Name: <input type="text" name="username"><br>
    <input type="submit">
</form>

Kiedy powyższy formularz zostanie wysłany, wartość wprowadzona do pola tekstowego będzię dostępna w $HTTP_POST_VARS['username']. Jeśli dyrektywa register_globals jest włączona, zmienna z formularza będzie także dostępna jako zmienna globalna $username.

Notatka: Dyrektywa konfiguracyjna magic_quotes_gpc oddziałuje na zmienne z Get, Post i Cookie. Jeśli włączona, tekst (It's "PHP!") automagicznie zmieni się w (It\'s \"PHP!\"). Jest to potrzebne przy wpisywaniu danych do baz danych. Zobacz też addslashes(), stripslashes() i magic_quotes_sybase.

PHP obsługuje także tablice w kontekście zmiennych z formularzy (zajrzyj do FAQ). Można na przykład pogrupować razem powiązane zmienne lub użyć tej możliwości do pobrania wartości z pola wyboru (select):

Przykład 12-2. Bardziej złożone zmienne w formularzach

<form action="array.php" method="post">
    Nazwisko: <input type="text" name="personal[nazwisko]"><br>
    Email: <input type="text" name="personal[email]"><br>
    Piwo: <br>
    <select multiple name="piwo[]">
        <option value="zywiec">Żywiec
        <option value="tyskie">Tyskie
        <option value="lech">Lech
        </select>
    <input type="submit">
</form>

W PHP 3 tablice w formularzach mogły być tylko jednowymiarowe. W PHP 4 nie ma takich ograniczeń.


Nazwy zmiennych dla SUBMIT w postaci obrazka

Przy tworzeniu formularza, można użyć obrazka, zamiast standardowego przycisku Wyślij, za pomocą takiego znacznika:

<input type="image" src="image.gif" name="sub">

Kiedy użytkownik kliknie gdzieś na obrazku, formularz, którego to dotyczy, zostanie wysłany do serwera z dwiema dodatkowymi zmiennymi, sub_x i sub_y. Zawierają one koordynaty miejsca kliknięcia na obrazek. Można przy tym zauważyć, że w nazwach zmiennych jest kropka a nie podkreślnik, ale PHP konwertuje kropkę na podkreślnik automatycznie. (Zobacz Kropki w nazwach nadchodzących zmiennych).


Ciasteczka HTTP

PHP bez problemu obsługuje ciasteczka HTTP, takie jak zdefiniowano w Specyfikacji Netscape'a. Ciasteczka są mechanizmem przechowywania informacji w przeglądarce klienta w celu śledzenia lub identyfikowania stałych bywalców strony. Ciasteczka ustawia się za pomocą funkcji setcookie(). Ciasteczka są częścią nagłówka HTTP, więc funkcja SetCookie musi być wywołana zanim jakakolwiek inna informacja zostanie wysłana do przeglądarki. Takie samo ograniczenie dotyczy funkcji header(). Wszystkie ciasteczka odebrane od klienta zostaną automatycznie zamienione w zmienne PHP, podobnie jak dane odebrane metodą GET lub POST.

Jeśli chcesz przypisać wiele wartości do jednego ciasteczka, dodaj [] do jego nazwy. Na przykład:

setcookie("MyCookie[]", "Testing", time()+3600);

Pamiętaj, że wysłane ciasteczko zastąpi wcześniejsze ciasteczko o tej nazwie, o ile ścieżka lub domena nie są różne. Na przykład dla koszyka do zakupów możesz potrzebować licznika a jego wartość stale przekazywać dalej, tzn.

Przykład 12-3. Przykład zastosowania SetCookie

$ilosc++;
setcookie("ilosc", $ilosc, time()+3600);
setcookie("koszyk[$ilosc]", $towar, time()+3600);
P&

Zmienne środowiskowe

PHP samoczynnie udostępnia zmienne środowiskowe jak zwykłe zmienne PHP.

echo $HOME;  /* Wyświetli zmienną środowiskową HOME, o ile ta ma jakąś wartość 
             */

Ponieważ informacje nadchdzące przez GET, POST i ciasteczka również są udostępniane jako zmienne, czasem jest lepiej odczytać zmienne środowiskowe bezpośrednio ze środowiska, aby mieć pewność, że otrzymuje się prawdziwą wartość zmiennej. W tym celu używa się funkcji getenv(). Można także samodzielnie ustawić wartość zmiennej środowiskowej za pomocą funkcji putenv().


Kropki w nazwach nadchodzących zmiennych

PHP normalnie nie zmienia nazw zmiennych przekazywanych do skryptu. Jednakże należy pamiętać, że kropka "." nie jest poprawnym znakiem w nazwie zmiennej. Dlaczego, proszę spojrzeć na to:
$varname.ext;  /* niepoprawna nazwa zmiennej */
To co widzi parser, to zmienna o nazwie $varname, po której pojawia się operator konkatenacji, a następnie pusty łańcuch (czyli taki, który nie jest żadnym słowem kluczowym, ani zarezerwowanym) "ext". Oczywiście, nie daje to żadnego sensownego wyniku.

Warto zatem wiedzieć, że PHP automatycznie zastąpi podkreślnikiem "_" każdą kropkę w nazwie nadchodzącej zmiennej.


Określanie typów zmiennych

Ponieważ PHP samodzielnie określa typy zmiennych i konwertuje je (zasadniczo) jak potrzeba, nie zawsze jest jasne, jakiego typu jest dana zmienna w danym momencie. PHP zawiera kilka funkcji do określania typów zmiennych. Są to: gettype(), is_array(), is_float(), is_int(), is_object() i is_string().


Rozdział 13. Stałe

Stała jest identyfikatorem (nazwą) dla prostej wartości. Jak sama nazwa wskazuje, wartość ta nie może się zmieniać podczas działania skryptu (poza magicznymi stałymi, które na właściwie nie są stałymi). Domyślnie, przy stałych uwzględniana jest wielkość liter. Przyjęto, że stałe są pisane dużymi literami.

Nazwa stałej podlega takim samym zasadom jak każda inna w PHP. Prawidłowa nazwa stałej rozpoczyna się literą, znakiem podkreślenia ("_"), następnie mogą występować litery, cyfry lub znaki podkreślenia. Dobrze reprezentuje to takie wyrażenie regularne: [a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*

Przykład 13-1. Prawidłowe i nieprawidłowe nazwy stałych

<?php 
     
    // Poprawne nazwy stałych 
    define("FOO",     "cokolwiek"); 
    define("FOO2",    "cokolwiek innego"); 
    define("FOO_BAR", "cokolwiek wiecej"); 
     
    // Nieprawidłowa nazwa stałej 
    define("2FOO",    "cokolwiek"); 
     
	// To jest prawidłowe, ale powinno być unikane:
	// PHP może pewnego dnia wprowdzić magiczą stałą
    // która spowoduje załamanie Twojego skryptu	
	 
    define("__FOO__", "cokolwiek"); 
     
    ?>

Notatka: Na nasze potrzeby, litery to a-z, A-Z, oraz znaki ASCII od 127 do 255 (0x7f-0xff).

Tak jak i superglobals, zasięg stałych jest globalny. Możesz odwołać się do stałych w dowolnym miejscu w Twojego skryptu, bez uważania na zasięg. Więcej informacji na temat zasięgu, przeczytasz w sekcji podręcznika zasięg zmiennych.


Składnia

Możesz definiować stałą używając funkcji define(). Kiedy stała zostanie zdefiniowana, nie może być już zmieniona albo undefined.

Tylko skalarne typy danych (boolean, integer, float i string) mogą być zawarte w stałych. Nie definiuj stałych typu zasób.

Możesz użyć wartości stałej poprzez zwykłe użycie jej nazwy. Inaczej niż przy zmiennych, w stałych NIE powinieneś prepend stałej znakiem $. Możesz także użyć funkcji constant(), aby odczytać wartość stałej, której nazwa jest przekazywana dynamicznie. Użyj funkcji get_defined_constants() aby otrzymać listę zdefiniowanych stałych.

Notatka: Stałe i globlane zmienne są pisane inaczej, a to oznacza, że np. TRUE i $TRUE są różne.

Jeśli użyjesz niezdefiniowanej stałej, PHP przyjmuje, że chcesz użyć nazwy stałej samej w sobie, poprostu tak jakbyś wywołał ją jako string (STALA kontra "STALA"). Jeśli to nastąpi zostanie wygenerowany błąd z poziomu E_NOTICE. Zobacz także w podręczniku artykuł o tym dlaczego $foo[bar] jest błędne (chyba, że wcześniej zdefiniujesz define() bar jako stałą). Jeśli, chcesz sprawdzić czy stała jest ustawiona, użyj funkcji defined().

Różnice pomiędzy stałymi, a zmiennymi:

  • Stałe nie mają znaku dolara ($) przed nazwą;

  • Stałe mogą być zdefiniowane wyłącznie używając funkcji define(), nie przez proste przypisanie;

  • Stałe mogą być definiowane oraz używane wszędzie bez zważania na zasady dotyczące zakresu ich dostępności;

  • Stałe nie mogą być redefiniowane lub undefined po tym jak raz zostały zdefiniowane; i

  • Stałe mogą zawierać tylko wartości skalarne.

Przykład 13-2. Definiowanie stałych

<?php
define("STALA", "Hello world!");
echo STALA; // wyświetli "Hello world!"
echo Stala; // wyświetli "Stala" i zgłosi ostrzeżenie
?>

Patrz także Stałe klasowe.


Magiczne stałe

PHP zapewnia dużą liczbę predefiniowanych stałych każdemu uruchamianemu skryptowi. Wiele z tych stałych, jednakże jest tworzona przez rozmaite rozszeżenia, i mogą być jedynie obecne gdy te rozszeżenia są dostępne, przez dynamiczne ładowanie (bibliotek) lub dlatego, że zostały one wkompilowane.

Istnieje pięć magicznych stałych, których zmiana zależy od tego gdzie zostaną użyte. Np. wartość __LINE__ zależy od numeru lini Twojego skryptu gdzie zostanie wstawiona. Specjalne stałe nie rozróżniają wielkich i małych liter i są to następujące:

Tabela 13-1. Kilka "magicznych" stałych PHP

NazwaOpis
__LINE__ Bieżący numer lini pliku.
__FILE__ Pełna ścieżka i nazwa pliku. Jeśli zostanie użyte w includowanym pliku, zwracana jest nazwa includowanego pliku. Od PHP 4.0.2, __FILE__ zawsze zawiera bezwzględną ściężkę, we wcześniejszych wersjach zawierała w pewnych okolicznościach ścieżkę względną.
__FUNCTION__ Nazwa funkcji, (Dodano w PHP 4.3.0) Od PHP 5 ta stała zwracana nazwę funkcji tak jak została ona zadeklarowana (z rozróżnianiem wielkości znaków). W PHP 4 wartość zawsze była zamieniana na małe litery.
__CLASS__ Nazwa klasy, (Dodano w PHP 4.3.0) Od PHP 5 ta stała zwracana nazwę klasy tak jak została ona zadeklarowana (z rozróżnianiem wielkości znaków). W PHP 4 wartość zawsze była zamieniana na małe litery.
__METHOD__ Nazwa metody klasy, (Dodano w PHP 5.0.0) Nazwa metody jest zwracana tak jak została ona zadeklarowana (z rozróżnianiem wielkości znaków).

Patrz także get_class(), get_object_vars(), file_exists() i function_exists().


Rozdział 14. Wyrażenia

Wyrażenia są naważniejszymi elementami składowymi PHP. W PHP prawie wszystko co napiszesz jest wyrażeniem. Najprostszą i najdokładniejszą definicją wyrażenia jest "wszystko co ma wartość".

Najbardziej podstawową formą wyrażeń są stałe i zmienna. Jeśli napiszesz "$a = 5" przypisujesz '5' do '$a'. '5' ma oczywiście wartość 5, lub innymi słowy '5' jest wyrażeniem o wartości 5 (w tym przypadku, '5' jest stałą liczbą całkowitą).

Po tym przypisaniu możesz się spodziwać, że wartością $a jest także 5, więc jeśli napiszesz "$b = $a" możesz się spodziewać, że będzie to równoznaczne z napisaniem "$b = 5". Innymi słowy, $a jest wyrażeniem o wartości 5. Jeśli wszystko działa prawidłowo, wszystko będzie się dziać tak jak napisano wyżej.

Trochę bardziej złożonymi przykładami wyrażeń są funkcje. Przyjrzyj się poniższej funkcji:

<?php
function foo ()
{
    return 5;
}
?>

Zakładając że oswoiłeś się z koncepcją funkcji (jeśli nie, przejrzyj najpierw rozdział o funkcjach), możesz założyć, że napisanie $c = foo() jest równoznaczne z napisaniem $c = 5, i masz racię. Funkcje są wyrażeniami o wartości którą zwracają. Ponieważ foo() zwraca 5, wartością wyrażenia 'foo()' jest 5. Zazwyczaj funkcje nie zwracają statycznej wartości, ale coś obliczają.

Oczywiście wartości w PHP nie muszą być liczbami całkowitymi, i bardzo często nie są nimi. PHP obsługuje 3 skalarne warotści danych: wartości całkowite (integer), wartości rzeczywiste (float i ciągi znaków (string) (wartości skalarne to takie, których nie możesz 'rozbić' na mniejsze kawałki, w przeciwieństwie do np. tablic). PHP obsługuje także dwa złożone (nieskalarne) typy danych: tablice i obiekty. Każdą z tych wartości można przypisać do zmiennych lub może być zwrócona przez funkcję.

PHP rozwija wyrażenia znacznie bardziej, podobnie jak wiele innych języków programowania. PHP jest językiem zorientowanym na wyrażenia, co oznacza że prawie wszystko jest wyrażeniem. Przyjrzyj się przykładowi który już analizowaliśmy, '$a = 5'. Łatwo jest zauważyć, że są tu dwie wartości. Wartość stałej całkowitej '5', a także wartość $a, która zostanie zamieniona na 5. Ale tak naprawdę jest tu jeszcze jedna wartość, którą jest wartość operacji przypisania. Przypisanie przyjmuje wartość przypisywanej wartości, w tym przypadku 5. W praktyce oznacza to, że '$a = 5', niezależnie co to robi, jest wyrażeniem o wartości 5. Wynika z tego, że napisanie '$b = ($a = 5)' jest równoznaczne napisaniu '$a = 5; $b = 5;' (średnik oznacza koniec instrukcji). Ponieważ przypisania są przetwarzane od prawej do lewej, możesz także napisać '$b = $a = 5'.

Kolejnym dobrym przykładem orientacji wyrażeniowej jest pre- i postinkrementacja i dekrementacja. Użytkownicy PHP i wielu innych języków mogą być już zaznajomieni z notacją zmienna++ i zmienna--. Są to operatory inkrementacji i dekrementacji. W PHP/FI 2 instrukcja '$a++' nie ma wartości (nie jest wyrażeniem), więc nie możesz jej przypisać lub użyć w jakikolwiek sposób. PHP rozszerza możliwości inkrementacji/dekrementacji robiąc także z nich wyrażenia, podobnie jak w C. W PHP, tak jak w C, sa dwa typy inkrementacji: preinkrementacja i postinkrementacja. I pre- i postinkrementacja zwiększają wartość zmiannej, więc efekt w stosunku do zmiennej jest taki sam. Różnica jest w wartości wyrażenia inkrementacji. Preinkrementacja, która jest oznaczana jako '++$zmienna', zwraca zwiększoną wartość (PHP zwiększa zmienną przed odczytaniem wartości, dlatego nazywa się to 'pre-inkrementacją'). Postinkrementacja, która jest oznaczana jako '$zmienna++', zwraca orginalną wartość $zmienna przed zwiększeniem jej wartości (PHP zwiększa wartość po odczytaniu jej wartości, stąd nazwa 'post-inkrementacja').

Popularnym typem wyrażeń są porównania. Wyrażenia te zwracają wartość FALSE lub TRUE. PHP obsługuje > (większy), >= (większy lub równy), == (równy), != (nie równy), < (mniejszy) i <= (mniejszy lub równy). Język obsługuje także zbiór operatorów ścisłego porównania: === (równy i tego samego typu) i !== (nie równy lub różnego typu). Wyrażenia te są powszechnie używane przy sprawdzaniu warunków, jak na przykład instrukcje if.

Ostatnim przykładem, którym będziemy się tu zajmować są połączone wyrażenia operacji i przypisania. Już wiesz, że jeśli chcesz zwiększyć wartość zmiennej $a o 1, możesz po prostu napisać '$a++' lub '++$a'. Ale co jeśli chcesz dodać do niej więcej niż jeden, na przykład 3? Mógłbyś napisać wielokrotnie '$a++', ale nie jest to sposób ani efektywny ani wygodny. Częściej spotykane jest używanie instrukcji '$a = $a + 3'. '$a + 4' zwraca wartość zmiennej $a plus 3, która jest przypisywana z powrotem do $a, co oznacza zwiększenie wartości zmiennej $a o 3. W PHP, tak jak kilku innych językach jak na przykład C, możesz napisać to krócej, co z czasem stanie się także bardziej przejrzyste i łatwiejsze do zrozumienia. Dodanie 4 do bieżącej wartości $a może być zapisane jako '$a += 4'. Oznacza to dokładnie "weź wartość $a, dodaj do niej 3 i przypisz ją z powrotem do $a". Oprócz bycia krótszą i bardziej przejrzystą, instrukcja ta jest także szybsza w wykonaniu. Wartość '$a += 5', tak jak wartość zwykłego przypisania, jest przypisywaną wartością. Zauważ, że NIE jest to 4, ale połączona warotść $a i 4 (jest to wartość która jest przypisywana do $a). Dowolne dwuoperandowe operatory mogą być użyte w trybie operacji-przypisania, na przykład '$a -= 5' (odejmij 5 od wartości $a), '$b *= 7' (pomnóż wartość $b przez 7), itp.

Jest jeszcze jedno wyrażenie, które może się wydać dziwne jeśli nie widziałeś go w innych językac, trójoperandowy operator warunkowy:

<?php
$pierwsze ? $drugie : $trzecie
?>

Jeśli wartością pierwszego podwyrażenia jest TRUE (rózna od zera), to zwracany jest drugie podwyrażanie, i jest to wynik wyrażenia warunkowego. W przeciwnym wypadku, zwracana jest wartość trzeciego podwyrażenia.

Poniższy przykład powinien pomóc w lepszym zrozumieniu pre- i postinkrementacji i ogólnie koncepcji wyrażeń:

<?php
function double($i)
{
    return $i*2;
}
$b = $a = 5;        /* przypisz wartość pięc do zmiennej $a i $b */
$c = $a++;          /* postinkrementuj, przypisz początkową wartość
                       $a (5) do $c */
$e = $d = ++$b;     /* preinkrementuj, przypisz zwiększoną wartość
                       $b (6) to $d i $e */

/* w tym momencie i $d i $e są równe 6 */

$f = double($d++);  /* przypisz podwojoną wartość $d przed
                       inkrementacji, 2*6 = 12 do $f */
$g = double(++$e);  /* przypisz podwojoną wartość $e po
                       inkrementacji, 2*7 = 14 do $g */
$h = $g += 10;      /* na początku $g jest zwiększane o 10 i przyjmuje 
                       wartość 24; wartość przypisania (24) jest później
                       przypisywana do $h, które przyjmuje wartość 24. */
?>

Na początku rozdziału powiedzieliśmy, że będziemy opisywać różne typy instrukcji, i tak jak obiecywaliśmy, wyrażenia mogą być instrukcjami. Jednakże nie każde wyrażenie jest instrukcją. Niektóre wyrażenia mogą być instrukcjami. Ten przypadek ma postać 'wyrażenie' ';', czyli wyrażenie a po nim średnik. W '$b=$a=5;', $a=5 jest poprawnym wyrażeniem, ale nie jest instrukcją. Jednakże '$b=$a=$b;' jest poprawną intrukcją.

Ostatnią rzeczą wartą uwagi jest wartość prawdy wyrażeń. W wielu przypadkach, głównie przy sprawdzaniu warunkow i w pętlach, nie interesuje cię wartość wyrażenia, ale tylko czy oznacza TRUE czy FALSE. Stałe TRUE i FALSE (niezależne od wielkości znaków) są dwiema możliwymi wartościami logicznymi. Kiedy to konieczne, wyrażenie jest automatycznie konwertowane na typ boolean. Zobacz rozdział o rzutowaniu typów jeśli interesują cię szczegóły jak to jest przeprowadzane.

PHP dostarcza pełnej i potężnej implementacji wyrażeń i całkowita ich dokumentacja przekracza ramy tego podręcznika. Powyższe przykłady powinny dać ci ogólne pojęcie czym są wyrażenia i jak możesz konstruować przydatne wyrażenia. Przez resztę podręcznika będziemy pisać expr aby oznaczyć dowolne poprawne wyrażenie PHP.


Rozdział 15. Operatory


Priorytety operatorów

Priorytet operatora określa, jak "silnie" operator wiąże ze sobą dwa stojące obok niego wyrażenia. Na przykład, w wyrażeniu 1 + 5 * 3, wynik wynosi 16, nie 18 ponieważ operator mnożenia ("*") ma wyższy priorytet niż operator dodawania ("+"). Za pomocą nawiasów można zmieniać priorytet działań według reguł arytmetyki. Na przykład: (1 + 5) * 3 jest równe 18.

Poniższa tabela zawiera priorytet operatorów, od najniższego priorytetu na górze.

Tabela 15-1. Priorytety operatorów

PowiązanieOperator
lewe,
leweor
lewexor
leweand
praweprint
lewe = += -= *= /= .= %= &= |= ^= ~= <<= >>=
lewe? :
lewe||
lewe&&
lewe|
lewe^
lewe&
bez powiązania== != === !==
bez powiązania< <= > >=
lewe<< >>
lewe+ - .
lewe* / %
prawe! ~ ++ -- (int) (double) (string) (array) (object) @
prawe[
bez powiązanianew


Operatory Arytmetyczne

Czy pamiętasz podstawy arytmetyki ze szkoły? Operatory w PHP działają niemalże tak samo.

Tabela 15-2. Operatory Arytmetyczne

PrzykładNazwaOpis
$a + $bDodawanieSuma $a i $b.
$a - $bOdejmowanieRóżnica $a od $b.
$a * $bMnożenieIloczyn $a i $b.
$a / $bDzielenieIloraz $a przez $b.
$a % $bDzielenie ModuloReszta z dzielenia $a przez $b.

Operator dzielenia ("/") zawsze zwraca wartość zmiennoprzecinkową (typu float), nawet wówczas kiedy obydwa operandy sš całkowite, lub są łańcuchami znaków skonwertowanymi do liczb całkowitych.


Operatory Przypisania

Podstawowym operatorem przypisania jest "=". Twoim pierwszym skojarzeniem może być "jest równy". Nie! Tak naprawdę oznacza to, że operand z lewej strony operatora "=" otrzymuje wartość wyrażenia stojącego po prawej stronie (tak właśnie się tłumaczy: "otrzymuje wartość wyrażenia po prawej").

Wartością całego wyrażenia przypisania jest wartość przypisywana do zmiennej stojacej po lewej. Na przykład wartością "$a = 3" jest 3. To pozwala na wykonywanie bardziej skomplikowanych przypisań:

$a = ($b = 4) + 5; // teraz $a jest równe 9, a $b jest równe 4.

Poza podstawowym operatorem przypisania, istnieją jeszcze złożone operatory odnoszące się do wszystkich arytmetycznych i łańcuchowych operatorów. Pozwalają one użyć zmiennej jako jednego z operandów, a następnie zapisać wynik działania operacji w tej właśnie zmiennej. Na przykład:

$a = 3;
$a += 5; // ustawia wartość $a na 8, tak jakby napisać: $a = $a + 5;
$b = "Witaj ";
$b .= "Świecie!"; // ustawia wartość $b na "Witaj Świecie!", dokładnie tak jak 
$b = $b . "Świecie!";

Zwróć uwagę, że przypisanie kopiuje wartość oryginalnej zmiennej do nowej zmiennej (tzw. przypisanie przez wartość). Skutki tego mogą być widoczne przy kopiowaniu np. dużej tablicy wewnątrz zwartej (ciasnej) pętli (ang. tight loop). PHP 4 pozwala na przypisanie przez referencję (odniesienie), za pomocą składni $zmienna = &$innaZmienna;. Taka możliwość pojawiła się dopiero w PHP 4 i nie była dostępna w PHP 3. "Przypisanie przez referencję" oznacza, że obydwie zmienne wskazują te same wartości, natomiast nic się nie kopiuje. Aby dowiedzieć się więcej na temat referencji, przeczytaj rodział wyjaśnienie referencji.


Operatory Bitowe

Operatory bitowe służą do operowania na wartościach konkretnych bitów w liczbie. Jeśli zarówno lewo jak i prawostronne operandy są typu string, operatory bitowe będą wykonywać operacje na poszczególnych znakach tych łańcuchów.

<?php 
      echo 12 ^ 9; // Zwraca '5' 
    
      echo "12" ^ "9"; // Zwraca znak Backspace (ascii 8)
                       // ('1' (ascii 49)) ^ ('9' (ascii 57)) = #8 
    
      echo "hallo" ^ "hello"; // Zwraca wartości ascii #0 #4 #0 #0 #0 
                              // 'a' ^ 'e' = #4 
  ?>

Tabela 15-3. Operatory Bitowe

PrzykładNazwaOpis
$a & $bMnożenie bitoweDany bit wynikowy jest równy 1 tylko jeśli obydwa bity składowe są równe 1.
$a | $bSumowanie bitoweDany bit wynikowy jest równy 1 jeśli conajmniej jeden bit składowy jest równy 1.
$a ^ $bSumowanie bitowe modulo 2Dany bit wynikowy jest równy 1 wtedy i tylko wtedy, kiedy jeden z bitów składowych jest równy 1 a drugi jest równy 0.
~ $aNegacja bitowaBity w zmiennej $a mające wartość 1 otrzymują wartość 0 i na odwrót.
$a << $bPrzesunięcie w lewo Przesuwa bity w zmiennej $a o $b kroków w lewo (każdy krok znaczy "pomnożone razy dwa").
$a >> $bPrzesunięcie w prawo Przesuwa bity w zmiennej $a o $b kroków w prawo (każdy krok znaczy "podzielone przez dwa").

Operatory Porównania

Jak wskazuje ich nazwa, operatory te służą do porównywania dwóch wartości.

Tabela 15-4. Operaatory Porównania

PrzykładNazwaOpis
$a == $bRównyTRUE jesli $a jest równe $b
$a === $bIdentyczny TRUE jeśli $a jest równe $b, i obydwa operandy są tego samego typu. (tylko w PHP 4)
$a != $bRóżnyTRUE jeśli $a nie jest równy $b.
$a <> $bRóżnyTRUE jeśli $a nie jest równy $b.
$a !== $bNie identyczny TRUE jeśli $a nie jest równy $b, lub nie są tego samego typu. (tylko w PHP 4)
$a < $bMniejszy niżTRUE jeśli $a jest mniejszy od $b.
$a > $bWiększy niżTRUE jeśli $a jest większy od $b.
$a <= $bMniejszy lub równyTRUE jeśli $a jest mniejszy lub równy $b.
$a >= $bWiększy lub równyTRUE jeśli $a jest większy lub równy $b.

Jeszcze jednym operatorem warunkowym jest operator "?:" (tzw. ternariusz - operator trójargumentowy), działający tak jak w C i wielu innych językach.

(expr1) ? (expr2) : (expr3);

Wartością wyrażenia jest expr2, jeśli expr1 jest równe TRUE, lub expr3, jeśli expr1 jest równe FALSE.


Operatory Kontroli Błędów

PHP obsługuje obecnie jeden operator kontroli błędów: znak małpy (@). Jeśli znak ten zostanie postawiony przed dowolnym wyrażeniem w PHP, jakiekolwiek powiadomienia o błędach wygenerowane przez to wyrażenie zostaną pominięte (nie będą wyświetlone).

Jeśli mechanizm track_errors został włączony, jakiekolwiek powiadomienie o błędzie zostanie zapisane do zmiennej globalnej $php_errormsg. Należy jednak pamiętać, że zawartość tej zmiennej jest nadpisywana przy każdym błędzie, więc po wystąpieniu kolejnego błędu w skrypcie, informacja o poprzednim błędzie jest tracona.

<?php
/* Zamierzony błąd obsługi pliku */
$my_file = @file ('nieistniejący_plik') or
    die ("Błąd przy otwieraniu pliku: treść błędu: '$php_errormsg'");

// mechanizm ten działa dla wszystkich wyrażeń, nie tylko dla funkcji:
$value = @$cache[$key]; 
// spowoduje niewyświetlenie powiadomienia, jeśli nie istnieje wpis do tablicy o
// indeksie $key.

?>

Notatka: Operator @ działa tylko na wyrażeniach. Tłumacząc to łopatologicznie: jeśli da się pobrać wartość czegoś, można postawić operator @ przed tym czymś. Zgodnie z powyższą regułą, można postawić @ przed zmiennymi, wywołaniami funkcji, instrukcjami include(), stałymi, itp. Nie można stawiać @ przed definicjami funkcji bądź klasy, lub strukturami warunkowymi, takimi jak if lub foreach, itd.

Patrz także: error_reporting().

Notatka: Operator "@" nie ukrywa komunikatów o błędach, które są wynikiem błędu parsowania (parse error).

Ostrzeżenie

Obecnie operator kontroli błędów "@" wyłączy wyświetlanie powiadomienia o błędzie nawet dla błędów krytycznych, które przerwą wykonywanie skryptu. Oznacza to, że jeśli użyjesz tego operatora przed wywołaniem funkcji, która jest nieosiągalna lub ma literówkę w nazwie, skrypt przerwie pracę nie powiadamiając dlaczego.


Operatory Wykonania Polecenia Systemowego

PHP posiada jeden operator wykoania polecenia systemowego: apostrof wsteczny (``). Zauważ że jest to coś innego niż apostrof zwykły! Zawartość apostrofu wstecznego zostanie wykonana jako polecenie systemowe. Wynik polecenia zostanie zwrócony (tzn. nie będzie wysłany do przeglądarki tylko będzie dostępny do przypisania do zmiennej).

$output = `ls -al`;
echo "<pre>$output</pre>";

Notatka: Operator ten nie działa kiedy safe mode jest włączony, lub shell_exec() jest zablokowana.

Zobacz też escapeshellcmd(), exec(), passthru(), popen(), shell_exec() i system().


Operatory Inkrementacji i Dekrementacji

PHP obsługuje te operatory w stylu języka C.

Tabela 15-5. Operatory Inkrementacji i Dekrementacji

PrzykładNazwaOpis
++$aPre-inkrementacjaNajpierw zwiększa wartość $a o jeden, potem zwraca $a.
$a++Post-inkrementacjaNajpierw zwraca $a, potem zwiększa $a o jeden.
--$aPre-dekrementacjaNajpierw zmniejsza wartość $a o jeden, potem zwraca $a.
$a--Post-dekrementacjaNajpierw zwraca $a, potem zmniejsza $a o jeden.

Prosty skrypt przykładowy:

<?php
echo "<h3>Post-inkrementacja</h3>";
$a = 5;
echo "Powinno być 5: " . $a++ . "<br />\n";
echo "Powinno być 6: " . $a . "<br />\n";

echo "<h3>Pre-inkrementacja</h3>";
$a = 5;
echo "Powinno być 6: " . ++$a . "<br />\n";
echo "Powinno być 6: " . $a . "<br />\n";

echo "<h3>Post-dekrementacja</h3>";
$a = 5;
echo "Powinno być 5: " . $a-- . "<br />\n";
echo "Powinno być 4: " . $a . "<br />\n";

echo "<h3>Pre-dekrementacja</h3>";
$a = 5;
echo "Powinno być 4: " . --$a . "<br />\n";
echo "Powinno być 4: " . $a . "<br />\n";
?>


Operatory Logiczne

Tabela 15-6. Opearotory Logiczne

PrzykładNazwaOpis
$a and $bITRUE jeśli zarówno $a jak i $b są TRUE.
$a or $bLubTRUE jeśli $a lub $b jest TRUE.
$a xor $bWyłacznie-LubTRUE jeśli $a lub $b jest TRUE, ale nie jednocześnie.
! $aNieTRUE jeśli $a nie jest TRUE.
$a && $bITRUE jeśli zarówno $a jak i $b są TRUE.
$a || $bLubTRUE jeśli $a lub $b jest TRUE.

Operatory "or" i "and" mają inny priorytet niż "||" i "&&" i właśnie z tego powodu w PHP są dwa różne operatory dla "lub" i "i". (Zobacz Priorytety Operatorów.)


Operatory Stringów

W PHP są dwa operatory operujące na łańcuchach znaków (stringach). Pierwszym z nich jest operator konkatenacji (połączenia) ('.'), który zwraca łańcuch będący połączeniem zawartości lewego i prawego operandu. Drugim z nich jest operator przypisania konkatenacyjnego ('.='), który dołącza zawartość wyrażenia stojacego z prawej strony do zmiennej stojacej z lewej strony. Zobacz także Operatory Przypisania.

$a = "Witaj ";
$b = $a . "Świecie!"; // teraz $b zawiera ciąg "Witaj Świecie!"

$a = "Witaj ";
$a .= "Świecie!";     // teraz $a zawiera ciąg "Witaj Świecie!"


Operatory Tablicowe

Jedynym operatorem tablicowym w PHP jest +. Dopisuje on prawy operand tablicowy do lewego, przy czym zduplikowane klucze NIE są nadpisywane.

$a = array("a" => "jabłko", "b" => "banan");
$b = array("a" =>"gruszka", "b" => "truskawka", "c" => "wisienka");

$c = $a + $b;

var_dump($c);
array(3) {
  ["a"]=>
  string(5) "jabłko"
  ["b"]=>
  string(6) "banan"
  ["c"]=>
  string(6) "wisienka"
}


Rozdział 16. Struktury kontrolne

Każdy skrypt PHP zbudowany jest z wyrażeń. Wyrażeniem może być przypisanie, odwołanie do funkcji, pętla, wyrażenie warunkowe, a nawet wyrażenie, które nic nie robi (puste wyrażenie). Wyrażenia zwykle kończą się znakiem średnika. Dodatkowo, wyrażenia mogą być grupowane przez umieszczenie ich w nawiasach sześciennych. Grupa wyrażeń sama także jest wyrażeniem. W tym rozdziale opisano rozmaite rodzaje wyrażeń.


if

Instrukcja if (jeżeli) jest jednym z najważniejszych mechanizmów dostępnych w wielu językach z PHP włącznie. Pozwala na wyodrębnienie fragmentu kodu, który zostanie wykonany pod określonym warunkiem. Instrukcja if w PHP jest bardzo podobna do swojego odpowiednika z języka C:

if (warunek)
    wyrażenie

Jak opisano w rozdziale na temat wyrażeń, obliczana jest wartość logiczna wyrażenia warunek. Jeśli warunek jest równy TRUE wyrażenie zostanie wykonane; w przeciwnym razie zostanie pominięte. Więcej informacji na temat obliczania logicznych wartości wyrażeń w rozdziale 'Konwersja do typu boolowskiego'.

Poniższy przykład wyświetli napis a jest większe niż b, jeśli $a będzie większe od $b:

if ($a > $b)
    print "a jest większe niż b";

Często potrzeba, aby więcej niż jedna instrukcja była wykonana pod przyjętym warunkiem. Nie ma oczywiście potrzeby umieszczać każdej z tych instrukcji w osobnej strukturze if. Zamiast tego należy zgrupować te instrukcje za pomocą instrukcji grupującej. Na przykład poniższy kod wyświetli a jest większe niż b, jeżeli $a jest większe niż $b, i przypisze wartość $a do $b:

if ($a > $b) {
    print "a jest większe niż b";
    $b = $a;
}

Instrukcje if mogą być dowolnie umieszczane wewnątrz innych instrukcji if, co zapewnia autorowi programu kompletną elastyczność przy ustalaniu warunkowego wykonywania poszczególnych części programu.


else

Często potrzeba wykonać jedną instrukcję programu, gdy pewien warunek jest spełniony, lub inną inną, gdy ten sam warunek nie jest spełniony. Służy do tego instrukcja else. else rozszerza możliwości instrukcji if do sytuacji kiedy warunek opisany przy instrukcji if ma wartość FALSE. Na przykład poniższy kod wyświetli a jest większe niż b jeżeli $a jest większe niż $b, lub a NIE jest większe niż b w przeciwnym przypadku.:

if ($a > $b) {
    print "a jest większe niż b";
} else {
    print "a NIE jest większe niż b";
}

Kod zawarty w instrukcji else wykonywany jest tylko wówczas, kiedy wyrażenie logiczne przy instrukcji if ma wartość FALSE, a jeśli w tej samej grupie znajdowały się też instrukcje elseif - tylko wówczas jeśli i w tych instrukcjach wyrażenia logiczne miały wartość FALSE (Patrz także: instrukcja elseif).


elseif

Instrukcja elseif, jak sama jej nazwa wskazuje, stanowi połączenie instrukcji if i else. Podobnie jak else rozszerza instrukcję if do sytuacji, kiedy wyrażenie logiczne stojące przy if ma wartość FALSE. Jednakże w przeciwieństwie do typowej instrukcji else, kod objęty tą instrukcją będzie wykonany, jeśli wyrażenie logiczne stojące przy tej instrukcji będzie miało wartość TRUE. Poniższy przykład wyświetli a jest większe niż b, a jest równe b lub a jest mniejsze niż b:

if ($a > $b) {
    print "a jest większe niż b";
} elseif ($a == $b) {
    print "a jest równe b";
} else {
    print "a jest mniejsze niż b";
}

Można użyć kilku instrukcji elseif w jednym bloku instrukcji if. Wykonany wtedy będzie ten blok, który pierwszy będzie mieć wartość TRUE. W PHP można też napisać 'else if' (dwoma słowami) zamiast 'elseif' (jednym słowem). Z punktu widzenia składni języka, wyrażenia te różnią się od siebie (jeśli znasz się na C, jest to ta sama różnica co w C), jednak wynik ich działania jest ten sam.

Dana instrukcja elseif będzie wykonana tylko wówczas, jeśli wszystkie poprzedzające ją instrukcje if i elseif w danym bloku miały wartość logiczną FALSE, a ona sama ma wartość logiczną TRUE.


Składnia alternatywna w strukturach kontrolnych

PHP oferuje alternatywną składnię dla niektórych struktur kontrolnych, a dokładnie dla: if, while, for, foreach i switch. W każdym przypadku podstawowa forma składni alternatywnej polega na zamianie nawiasu otwierającego na dwukropek (:), a nawiasu zamykającego na odpowiednie słowo: endif;, endwhile;, endfor;, endforeach; lub endswitch;.

<?php if ($a == 5): ?>
A jest równe 5
<?php endif; ?>

W przykładzie powyżej, blok HTML "A jest równe 5" jest zagnieżdżony w instrukcji if napisanej w składni alternatywnej. Ten fragment kodu HTML zostanie wyświetlony tylko wówczas, kiedy $a będzie równe 5.

Alternatywna składnia obejmuje też wyrażenia else i elseif. Poniższy przykład prezentuje obydwa wyrażenia zapisane przy pomocy składni alternatywej:

if ($a == 5):
    print "a jest równe 5";
    print "...";
elseif ($a == 6):
    print "a jest równe 6";
    print "!!!";
else:
    print "a jest różne od 5 lub 6";
endif;

Więcej przykładów w rozdziałach: while, for, i if.


while

Pętla while jest najprostszym typem pętli w PHP. Zachowuje się ona identycznie jak jej odpowiednik z języka C. Jej podstawowa forma wygląda następująco:

while (wyrażenie) instrukcja

Znaczenie instrukcji while jest bardzo proste. Nakazuje ona PHP tyle razy wykonywać określone instrukcje, jak długo wyrażenie przy słowie while ma wartość TRUE. Wartość tego wyrażenia jest sprawdzana za każdym razem na początku wykonywania nowej iteracji pętli, więc jeśli jego wartość zmieni się w trakcie wykonywania instrukcji, wykonanie całej pętli nie skończy się do momentu zakończenia całej iteracji. Jedna iteracja jest to jednokrotne wykonanie wszystkich instrukcji w pętli. Jeśli wyrażenie logiczne ma wartość FALSE już na samym początku, instrukcje wewnątrz pętli nie będą w ogóle wykonane.

Podobnie jak w instrukcji if, w pętli while można grupować instrukcje za pomocą nawiasów klamrowych, lub przez użycie składni alternatywnej:

while (wyrażenie): instrukcja; instrukcja; ... endwhile;

Poniższe przykłady są identyczne i obydwa wyświetlają liczby od 1 do 10:

/* przykład 1*/

$i = 1;
while ($i <= 10) {
    print $i++;  /* zmienna $i będzie inkrementowana po wyświetleniu
                    (post-inkrementacja) */
}

/* przykład 2 */

$i = 1;
while ($i <= 10):
    print $i;
    $i++;
endwhile;


do..while

Pętla do..while zachowuje się bardzo podobnie do pętli while, z wyjątkiem tego, że wartość wyrażenia logicznego sprawdzana jest na końcu iteracji, a nie na początku. Wynikającą z tego główną różnicą jest to, że pierwsza iteracja w pętli do..while na pewno zostanie wykonana (gdyż wyrażenie logiczne będzie sprawdzone dopiero na koniec iteracji). Natomiast w pętli while, gdzie wyrażenie logiczne jest sprawdzane na początku iteracji, może dojść do sytuacji, że pętla w ogóle nie zostanie wykonana, jeśli to wyrażenie będzie miało wartość FALSE od początku.

Pętla do..while ma tylko jeden rodzaj składni:

$i = 0;
do {
   print $i;
} while ($i>0);

Powyższa pętla zostanie wykonana tylko raz, gdyż po pierwszej iteracji, wartość wyrażenia logicznego wynosić będzie FALSE ($i nie jest większe od 0) i pętla zostanie zakończona.

Zaawansowani programiści C są zaznajomieni z innym wykorzystaniem pętli do..while, które służy do przerwania wykonywania bloku instrukcji w określonym momencie przez użycie do..while(0) i instrukcji break. Demonstruje to poniższy kod:

do {
    if ($i < 5) {
        print "i jest za małe";
        break;
    }
    $i *= $factor;
    if ($i < $minimum_limit) {
        break;
    }
    print "i jest w porządku";

     ...operacje na i...

} while(0);

Nie przejmuj się, jeśli nie rozumiesz tego do końca lub w ogóle. Możesz tworzyć skrypty, nawet zaawansowane skrypty bez użycia tego "mechanizmu".


for

Pętla for jest najbardziej skomplikowanym rodzajem pętli w PHP. Zachowuje się identycznie jak jej odpowiedniki z C. Jej składnia wygląda następująco:

for (wyrażenie1; wyrażenie2; wyrażenie3) instrukcje

wyrażenie1 jest wykonywane tylko raz, na początku pętli.

Na początku każdej nowej iteracji, obliczana jest wartość logiczna wyrażenia wyrażenie2. Jeśli wynikiem obliczenia jest TRUE, to pętla kontynuuje i następuje wykonanie instrukcji umieszczonych w pętli. Jeśli jednak wyrażenie ma wartość FALSE, to wykonanie pętli zostaje przerwane.

Na końcu każdej iteracji zostaje wykonane wyrażenie3.

Każde z wyrażeń może być puste. Puste wyrażenie2 oznacza, że pętla jest nieskończona (PHP interpretuje to jako wartość TRUE, podobnie z resztą jak C). Nie jest to jednak tak bezużyteczne, jak to się może wydawać, gdyż często stosuje się to w połączeniu z instrukcją break, co zastępuje wyrażenie2 w pętli for.

Wszystkie poniższe przykłady wyświetlają liczby od 1 do 10. Proszę zauważyć rozmaite odmiany składni:

/* przykład 1 */

for ($i = 1; $i <= 10; $i++) {
    print $i;
}

/* przykład 2 */

for ($i = 1;;$i++) {
    if ($i > 10) {
        break;
    }
    print $i;
}

/* przykład 3 */

$i = 1;
for (;;) {
    if ($i > 10) {
        break;
    }
    print $i;
    $i++;
}

/* przykład 4 */

for ($i = 1; $i <= 10; print $i, $i++);

Oczywiście najzgrabniejsza składnia jest w przykładzie pierwszym (albo czwartym), ale w wielu sytuacjach puste wyrażenia w pętli for bardzo się przydają.

PHP obsługuje również składnię alternatywną (z dwukropkiem) w pętli for.

for (wyrażenie1; wyrażenie2; wyrażenie3): instrukcja; ...; endfor;

Inne języki programowania posiadają pętlę foreach do obsługi tablic itp. W PHP 3 nie ma takiej pętli, natomiast została ona dodana do PHP 4. Więcej na ten temat w odpowiednim rozdziale. W PHP 3 można połączyć instrukcje while, list() i each() co pozwoli osiągnąć ten sam efekt. Przykłady na to znajdują się w rozdziałach dotyczących wyżej wymienionych instrukcji.


foreach

PHP 4 zawiera, czego brak w PHP 3, konstrukcję foreach, podobną do jej odpowiedników z Perla i innych języków. Pętla ta umożliwia łatwą iterację wewnątrz tablic. foreach działa tylko na tablicach i każda próba użycia tej pętli na innym typie lub na niezainicjowanej zmiennej będzie skwitowana komunikatem o błędzie. Istnieją dwie składnie tej konstrukcji, przy czym druga jest mniej ważnym, lecz użytecznym rozszerzeniem pierwszej:

foreach(wyrażenie_tablicowe as $wartość) wyrażenie
foreach(wyrażenie_tablicowe as $klucz => $wartość) wyrażenie

Pierwsza odmiana iteruje wewnątrz tablicy podanej w wyrażenie_tablicowe. Przy każdej iteracji, wartość aktualnego elementu tablicy jest przypisywana do zmiennej $wartość, a wewnętrzny wskaźnik tablicy jest przesuwany o jeden (więc w następnej iteracji przypisany zostanie kolejny element tablicy).

Druga odmiana działa tak samo jak pierwsza, przy czym klucz aktualnego elementu tablicy zostanie przypisany do zmiennej $klucz w każdej iteracji.

Notatka: Kiedy rozpoczyna się wykonywanie pętli foreach, wewnętrzny wskaźnik tablicy jest automatycznie resetowany, co ustawia go na pierwszym elemencie tablicy. Oznacza to, że nie trzeba wywoływać komendy reset() przed rozpoczęciem pętli foreach.

Notatka: Proszę także pamiętać, że konstrukcja foreach operuje na kopii tablicy, a nie na oryginale, więc położenie kursora tablicy nie jest modyfikowane jak w konstrukcji each(), a zmiany dokonane na pobranym elemencie tablicy nie oddziałują na oryginalną tablicę. Jednakże wewnętrzny kursor oryginalnej tablicy jest przesuwany w trakcie trawersowania tablicy. Zakładając, że pętla foreach będzie działać aż do przetworzenia całej tablicy, kursor tablicy będzie się znajdował na końcu tablicy.

Notatka: foreach nie pozwala na ukrycie komunikatów o błędach za pomocą '@'.

Można zauważyć, że poniższe przykłady są funkcjonalnie identyczne:

$arr = array("jeden", "dwa", "trzy");
reset ($tabl);
while (list(, $wartość) = each ($tabl)) {
    echo "Wartość: $wartość<br>\n";
}

foreach ($tabl as $wartość) {
    echo "Wartość: $wartość<br>\n";
}

Poniższe przykłady są również funkcjonalnie identyczne:

reset ($tabl);
while (list($klucz, $wartość) = each ($tabl)) {
    echo "Klucz: $klucz; Wartość: $wartość<br>\n";
}

foreach ($tabl as $klucz => $wartość) {
    echo "Klucz: $klucz; Wartość: $wartość<br>\n";
}

Więcej przykładów demonstrujących użycie tej pętli:

/* przykład 1 foreach: tylko wartość */

$a = array (1, 2, 3, 17);

foreach ($a as $v) {
   print "Aktualna wartość \$a: $v.\n";
}

/* przykład 2 foreach: wartość (z kluczem generowanym dla potrzeb ilustracji)*/

$a = array (1, 2, 3, 17);

$i = 0; /* tylko dla potrzeb ilustracyjnych */

foreach($a as $v) {
    print "\$a[$i] => $v.\n";
    $i++;
}

/* przykład 3 foreach: klucz i wartość */

$a = array (
    "jeden" => 1,
    "dwa" => 2,
    "trzy" => 3,
    "siedemnaście" => 17
);

foreach($a as $k => $v) {
    print "\$a[$k] => $v.\n";
}

/* przykład 4 foreach: tablice wielowymiarowe */

$a[0][0] = "a";
$a[0][1] = "b";
$a[1][0] = "y";
$a[1][1] = "z";

foreach($a as $v1) {
    foreach ($v1 as $v2) {
        print "$v2\n";
    }
}

/* przykład 5 foreach: tablice dynamiczne */

foreach(array(1, 2, 3, 4, 5) as $v) {
    print "$v\n";
}


break

break zakańcza wykonywanie aktualnej instrukcji for, foreach while, do..while lub switch.

break akceptuje opcjonalny argument, który mówi, ile zagnieżdzonych struktur kontrolnych ma zostać przerwanych w danym momencie.

$arr = array ('jeden', 'dwa', 'trzy', 'cztery', 'stop', 'pięć');
while (list (, $val) = each ($arr)) {
    if ($val == 'stop') {
        break;    /* Można tu też napisać: 'break 1;' */
    }
    echo "$val<br>\n";
}

/* Użycie opcjonalnego argumentu: */

$i = 0;
while (++$i) {
    switch ($i) {
    case 5:
        echo "Na 5<br>\n";
        break 1;  /* Wyjdź tylko ze switch. */
    case 10:
        echo "Na 10; wyjście<br>\n";
        break 2;  /* Wyjdź ze switch i z while. */
    default:
        break;
    }
}


continue

continue używane jest wewnątrz instukcji pętli do przerwania wykonywania danej iteracji pętli i rozpoczęcia zupełnie nowej iteracji.

continue akceptuje opcjonalny argument liczbowy, który mówi, ilu poziomów zagnieżdżonych pętli dana instrukcja continue dotyczy.

while (list ($klucz, $wartość) = each ($arr)) {
    if (!($klucz % 2)) { // opuść klucze nieparzyste
        continue;
    }
    zrób_coś_z_nieparzystymi ($wartość);
}

$i = 0;
while ($i++ < 5) {
    echo "Zewnętrzna<br>\n";
    while (1) {
        echo "&nbsp;&nbsp;Środkowa<br>\n";
        while (1) {
            echo "&nbsp;&nbsp;Wewnętrzna<br>\n";
            continue 3;
        }
        echo "To się nigdy nie wyświetli.<br>\n";
    }
    echo "Ani to.<br>\n";
}


switch

Instrukcja switch jest podobna do serii instrukcji IF z warunkiem na to samo wyrażenie. W wielu przypadkach istnieje potrzeba porównania jednej zmiennej (lub wyrażenia) z wieloma różnymi wartościami i wykonania różnych fragmentów kodu, w zależności od wyniku porównania tej zmiennej z różnymi wartościami. Do tego właśnie służy instrukcja switch.

Poniżej znajdują się dwa przykłady wykonujące dokładnie to samo, przy czym jeden z nich wykorzystuje serię instrukcji if, zaś drugi używa instrukcji switch:

if ($i == 0) {
    print "i jest równe 0";
} elseif ($i == 1) {
    print "i jest równe 1";
} elseif ($i == 2) {
    print "i jest równe 2";
}

switch ($i) {
    case 0:
        print "i jest równe 0";
        break;
    case 1:
        print "i jest równe 1";
        break;
    case 2:
        print "i jest równe 2";
        break;
}

Ważne jest by zrozumieć, jak działa instrukcja switch, żeby uniknąć błędów. Instrukcja switch jest wykonywana linia po linii (dokładnie wyrażenie po wyrażeniu). Na początku żaden fragment kodu nie jest wykonywany. Dopiero kiedy zostaje odnalezione wyrażenie case, którego wartość odpowiada wyrażeniu przy instrukcji switch, PHP rozpoczyna wykonywanie kodu od miejsca, gdzie znajduje się ta instrukcja case. PHP wykonuje instrukcje aż do momentu kiedy blok switch się skończy, lub do momentu znalezienia instrukcji break. Jeśli nie napiszesz instrukcji break na końcu instrukcji w danym wyrażeniu case to PHP będzie wykonywać dalej instrukcje z następnego wyrażenia case. Na przykład:

switch ($i) {
    case 0:
        print "i jest równe 0";
    case 1:
        print "i jest równe 1";
    case 2:
        print "i jest równe 2";
}

W tym przypadku, jeśli $i jest równe 0, to PHP wykona wszystkie trzy instrukcje print. Jeśli natomiast będzie równe jeden - wtedy tylko dwie ostatnie. Zachowanie zgodne z oczekiwaniami będzie wtedy, kiedy $i będzie równe 2 - wtedy wykonane będzie tylko ostatnia instrukcja print. Trzeba zatem pamiętać o umieszczaniu na końcu instrukcji break, chyba że planuje się wykorzystać jakieś specjalne możliwości instrukcji switch, o czym dalej.

W instrukcji switch wartość wyrażenia jest obliczana tylko raz, a następnie jest porównywana z każdym z wyrażeń przy etykiecie case. Natomiast w instrukcji elseif wartość wyrażenia jest obliczana ponownie. Dlatego, jeśli twoje wyrażenie jest bardziej skomplikowane od zwykłego porównania, lub znajduje się w zwartej pętli (tight loop), switch może być szybszy.

Po etykiecie case mogą nie występować żadne instrukcje, co oznacza po prostu, że sterowanie zostaje przekazane do następnej etykiety case.

switch ($i) {
    case 0:
    case 1:
    case 2:
        print "i jest mniejsze od 3, ale nie jest ujemne";
        break;
    case 3:
        print "i jest równe 3";
}

Specjalną etykietą jest etykieta warunku domyślnego - default. Etykieta ta dotyczy sytuacji, w której wyrażenie nie pasowało do wartości przy innych etykietach typu case. W instrukcji switch ta etykieta powinna być ostatnia z listy. Na przykład:

switch ($i) {
    case 0:
        print "i jest równe 0";
        break;
    case 1:
        print "i jest równe 1";
        break;
    case 2:
        print "i jest równe 2";
        break;
    default:
        print "i jest różne od 0, 1 i 2";
}

Etykieta case może zawierać dowolną wartość typu prostego, czyli liczbę całkowitą, zmiennoprzecinkową lub łańcuch znaków. Tablice lub obiekty nie mogą być użyte, o ile nie zostaną przekształcone w jakiś typ prosty.

Instrukcja switch obsługuje też składnię alternatywną. Więcej informacji na ten temat w rozdziale Składnia alternatywna w strukturach kontrolnych.

switch ($i):
    case 0:
        print "i jest równe 0";
        break;
    case 1:
        print "i jest równe 1";
        break;
    case 2:
        print "i jest równe 2";
        break;
    default:
        print "i jest różne od 0, 1 i 2";
endswitch;


declare

Instrukcja declare służy do ustawienia dyrektyw wykonawczych dla bloku kodu. Składnia instrukcji jest podobna do składni innych struktur kontrolnych:

declare (dyrektywa) instrukcje

Argument dyrektywa pozwala na ustawienie zachowania się danego bloku declare. W chwili obecnej rozpoznawana jest tylko jedna dyrektywa: ticks. (Więcej informacju na temat dyrektywy ticks w dedykowanym podrozdziale).

Kod zawarty w bloku instrukcje będzie wykonywany. Sposób i poboczne efekty wykonania tego kodu mogą zależeć od argumentu dyrektywa.


Ticks

Tyknięcie (tick) jest zdarzeniem, które następuje po każdych N niskopoziomowych instrukcjach wykonywanych przez parser wewnątrz bloku declare. Wartość parametru N jest określana przez umieszczenie wyrażenia ticks=N wewnątrz argumentu dyrektywa danego bloku declare.

Zdarzenie wywoływane na każde tyknięcie określa się przez użycie funkcji register_tick_function(). Więcej szczegółów znajduje się w poniższym przykładzie. Proszę pamiętać, że z każdym tyknięciem może być wywoływane więcej niż jedno zdarzenie.

Przykład 16-1. Profilowanie sekcji kodu PHP

<?php
// funkcja, która zapisuje czas jej wywołania
function profile ($wyrzuć = FALSE)
{
    static $profile;

    // zwróć tablicę czasów wywołania i wykasuj jej lokalną kopię
    if ($wyrzuć) {
        $temp = $profile;
        unset ($profile);
        return ($temp);
    }

    $profile[] = microtime ();
}

// ustal wskaźnik tyknięcia
register_tick_function("profile");

// zainicjowanie funkcji przed blokiem declare
profile ();

// wykonaj poniższy kod, generując tyknięcie co 2 instrukcje
declare (ticks=2) {
    for ($x = 1; $x < 50; ++$x) {
        echo similar_text (md5($x), md5($x*$x)), "<br />";
    }
}

// Wyświetl dane przechowywane w profilerze
print_r (profile (TRUE));
?>
Powyższy przykład profiluje kod PHP wewnątrz bloku "declare", zapisując czas wywołania co drugiej niskopoziomowej instrukcji w bloku instrukcji. Informację tę można wykorzystać do wykrycia fragmentów kodu wykonywanych w zbyt wolnym tempie. Problem wyszukania takich fragmentów można zrealizować na wiele sposobów, przy czym użycie tyknięć jest najwygodniesze i najłatwiejsze do zaimplementowania.

Tyknięcia są doskonale przystosowane dla potrzeb debugowania, implementacji prostej wielozadaniowości, wykonywania operacji We/Wy w tle i wielu innych zadań.

Patrz także register_tick_function() i unregister_tick_function().


return

Instrukcja return(), wywołana z wnętrza funkcji, natychmiastowo zakańcza wykonywanie tej funkcji i zwraca jako jej wartość swój argument. return() zakańcza również wykonywanie instrukcji eval() lub danego pliku skryptowego.

Instrukcja ta, wywołana w zasięgu globalnym, zakańcza wykonywanie całego pliku skryptowego. Jeśli dany skrypt był dołączony funkcjami include() lub require(), sterowanie zostaje zwrócone do pliku wywołującego. Poza tym, jeśli plik został dołączony funkcją include(), argument przekazany do funkcji return() będzie zwrócony jako wartość funkcji include(). Jeśli funkcja return() zostanie wywołana w głównym pliku skryptowym, nastąpi zakończenie całego skryptu. Jeśli dany skrypt został wywołany przez dyrektywy konfiguracyjne auto_prepend_file lub auto_append_file w php.ini, wtedy wykonywnie tego pliku skryptowego zostanie zakończone.

Więcej informacji w rozdziale zwracanie wartości.

Notatka: Proszę zauważyć, że ponieważ return() jest konstrukcją językową a nie funkcją, nawiasy otaczające jej argumenty nie są konieczne. W rzeczywistości częściej są one opuszczane przez programistów, choć opuszczenie ich, czy nie, nie zmienia niczego.


require()

Instrukcja require() służy do wczytania i wykonania skryptu z określonego pliku.

require() wczytuje i wykonuje skrypt z podanego pliku. Szczegółowa informacja odnośnie tego, jak działa wczytywanie opisana jest w dokumentacji dla instrukcji include().

Instrukcje require() i include() są identyczne w każdym szczególe, z wyjątkiem obsługi błędów. W razie niepowodzenia, include() generuje ostrzeżenie (Warning), podczas gdy require() generuje błąd krytyczny (Fatal Error). Innymi słowy, instrukcji require() używa się do wczytywania plików, które są niezbędne do działania skryptu i w przypadku ich braku wykonywanie skryptu musi zostać przerwane. Instukcja include() nie zachowuje się w ten sposób. W jej przypadku, przy braku pliku wykonywanie skryptu będzie kontynuowane. Proszę również pamiętać o właściwym ustawieniu dyrektywy konfiguracyjnej include_path.

Przykład 16-2. Podstawowe przykłady użycia require()

<?php

require 'nagłówek.php';

require $plik;

require ('jakiś_plik.txt');

?>

Więcej przykładów w dokumentacji instrukcji include().

Notatka: Począwszy od PHP 4.0.2, zachowanie instrukcji jest następujące: require() będzie zawsze próbować odczytać plik docelowy, nawet jeśli linia w której ona się znajduje nigdy nie zostanie wykonana. Instrukcja warunkowa nie wpływa na działanie require(). Jednakże, jeśli linia, w której pojawia się require() nie zostaje wykonana, zawartość pliku wczytywanego też nie zostaje wykonana. Podobnie, instrukcje pętli nie wpływają na działanie require(). Chociaż kod zawarty w pliku docelowy wciąż jest podmiotem pętli, require() działa tylko raz.

Ostrzeżenie

PHP w wersji starszej niż 4.3.0, pracujące pod kontrolą systemów Windows, nie obsługują dostępu do zdalnych plików w tej funkcji, nawet jeśli opcja allow_url_fopen jest włączona.

Patrz także include(), require_once(), include_once(), eval(), file(), readfile(), virtual() i include_path.


include()

Instrukcja include() służy do wczytania i wykonania kodu z określonego pliku w trakcie wykonywania skryptu.

Poniższa dokumentacja dotyczy także instrukcji require(). Obydwie instrukcje są identyczne w każdym szczególe, z wyjątkiem obsługi błędów. include() generuje błąd typu Warning, podczas gdy require() generuje błąd Fatal Error. Innymi słowy, funkcji require() używa się, by zatrzymać przetwarzanie skryptu, gdy brakuje jakiegoś pliku. Jeżeli zostanie użyta funkcja include(), to w powyższej sytuacji skrypt będzie przetwarzany dalej. Proszę pamiętać o właściwym ustawieniu dyrektywy include_path.

Kiedy plik zostanie wczytany instrukcją include(), zawarty w nim kod dziedziczy zasięg zmiennych po linii, w której znajdowała się instrukcja wczytania. Każda zmienna dostępna w linii z instrukcją include() będzie dostępna we wczytywanym pliku od miejsca wczytania naprzód.

Przykład 16-3. Podstawowe wykorzystanie include()

vars.php
<?php

$kolor = 'zielone';
$owoc = 'jabłko';

?>

test.php
<?php

echo "Jedno $kolor $owoc"; // Jedno

include 'vars.php';

echo "Jedno $kolor $owoc"; // Jedno zielone jabłko

?>

Jeśli instrukcja wczytania znajduje się wewnątrz deklaracji funkcji, to cały kod zawarty w pliku wczytywanym będzie zachowywał się, jakby był zdefiniowany wewnątrz tej funkcji. Znaczy to, że odziedziczy zasięg zmiennych po tej funkcji.

Przykład 16-4. Wczytywanie wewnątrz funkcji

<?php

function foo()
{
global $kolor;

    include 'vars.php';

    echo "Jeden $kolor $owoc";
}

/* vars.php znajduje się w zasięgu foo(), więc *
 * $owoc NIE jest dostępny poza zasięgiem tej  *
 * funkcji. Natomiast $kolor jest dostępny,    *
 * ponieważ został zadeklarowany w zasięgu     *
 * globalnym.                                  */
 
foo();                    // Jedno zielone jabłko
echo "A $kolor $owoc";   // Jedno zielone

?>

Na początku wczytywanego pliku parsowanie wychodzi z trybu PHP do trybu HTML i wraca do trybu początkowego na końcu. Z tego powodu każdy kod wewnątrz wczytywanego pliku będzie wykonany jako kod PHP, o ile będzie zawarty w ważnych znacznikach początku i końca kodu PHP.

Jeśli "URL fopen wrappers" są włączone w PHP (takie jest domyślne ustawienie) można podać nazwę pliku do wczytania używając adresu URL (przez protokół HTTP lub innym obsługiwanym sposobem - zajrzyj do Dodatek M aby zapoznać się z listą obsługiwanych protokołów), zamiast podawać ścieżkę lokalną. Jeśli podany w adresie serwer interpretuje plik docelowy jako kod PHP, można do tego skryptu przekazać zmienne w taki sam sposób jak przy metodzie GET protokołu HTTP. Ściśle mówiąc, nie jest to to samo, co wczytywanie pliku lokalnego; jest to wykonanie pliku na zdalnym serwerze i wklejenie rezultatu jego działania do skryptu wywołującego. W tym przypadku, rzecz jasna, zasięg globalny zmiennych nie obejmuje pliku wczytywanego tą metodą.

Ostrzeżenie

PHP w wersji starszej niż 4.3.0, pracujące pod kontrolą systemów Windows, nie obsługują dostępu do zdalnych plików w tej funkcji, nawet jeśli opcja allow_url_fopen jest włączona.

Przykład 16-5. include() i protokół HTTP

<?php
/* Przykład ten zakłada, że serwer www.example.com jest tak skonfigurowany,
 * że wykonuje skrypty w plikach .php natomiast nie wykonuje skryptów w plikach
 * .txt. Pojęcie 'działa', znaczy tutaj, że zmienne $foo i $bar są dostępne
 * we wczytywanym pliku                                                       */

// Nie działa: file.txt nie jest traktowany jak skrypt php
include 'http://www.example.com/file.txt?foo=1&bar=2';

// Nie działa: PHP będzie szukać pliku o nazwie 'file.php?foo=1&bar=2' 
// w lokalnym systemie plików
include 'file.php?foo=1&bar=2';

// Działa.
include 'http://www.example.com/file.php?foo=1&bar=2';

$foo = 1;
$bar = 2;
include 'file.txt';  // Działa.
include 'file.php';  // Działa.

?>
Patrz także Korzystanie ze zdalnych plików, fopen() i file().

Ponieważ include() i require() są specialnymi konstrukcjami językowymi, muszą być umieszczone w instrukcji grupującej, aby mogły działać w instrukcji warunkowej.

Przykład 16-6. include() i instrukcja warunkowa

<?php

// Ten kod jest NIEPOPRAWNY i nie zadziała zgodnie z oczekiwaniami.
if ($warunek)
    include $plik;
else
    include $inny;


// Natomiast ten kod jest POPRAWNY.
if ($warunek) {
    include $plik;
} else {
    include $inny;
}

?>

Obsługa zwracanych wartości: można wywołać instrukcję return() wewnątrz wczytywanego pliku, aby zakończyć jego wykonywanie i powrócić do pliku wywołującego. Można też zwracać wartości z wczytywanych plików, co upodabnia wczytywanie plików do wykorzystywania funkcji.

Notatka: W PHP 3 instrukcja return() może pojawić się w bloku instrukcji tylko wówczas, jeśli znajduje się on wewnątrz funkcji. W takim przypadku, oczywiście, return() odnosi się do tej funkcji a nie do całego pliku.

Przykład 16-7. include() i wyrażenie return()

return.php
<?php

$var = 'PHP';

return $var;

?>

noreturn.php
<?php

$var = 'PHP';

?>

testreturns.php
<?php

$foo = include 'return.php';

echo $foo; // wyświetla 'PHP'

$bar = include 'noreturn.php';

echo $bar; // wyświetla 1

?>

Zmienna $bar ma wartość 1, ponieważ wczytywanie pliku zakończyło się powodzeniem. Proszę zauważyć istotną różnicę pomiędzy powyższymi przykładami. Pierwszy używa instrukcji return() wewnątrz wczytywanego pliku, natomiast drugi nie. Inne możliwości "wczytania" plików do zmiennych to fopen(), file() lub przez użycie include() razem z Funkcjami Kontroli Wyjścia.

Patrz także require(), require_once(), include_once(), readfile(), virtual(), i include_path.


require_once()

Instrukcja require_once() służy do wczytania i wykonania kodu z określonego pliku w trakcie wykonywania skryptu. Zachowanie jej jest identyczne z instrukcją require() z jednym wyjątkiem, tzn. jeśli dany plik został już raz wczytany do tego skryptu, nie będzie wczytany ponownie. Więcej informacji na temat działania tej instrukcji w dokumentacji odnośnie require().

require_once() powinno być używane w przypadku, gdy ten sam plik mógłby zostać wczytany i wykonany wielokrotnie, ale ty chcesz mieć pewność, że zostanie wczytany dokładnie raz, aby uniknąć problemów z redefiniowaniem funkcji, nadpisywaniem zmiennych itp.

Przykłady użycia require_once() i include_once() znajdują się w kodzie PEAR dołączonym do najnowszych dystrubucji kodu źródłowego PHP.

Notatka: require_once() dodano w PHP 4.0.1pl2

Notatka: Proszę pamiętać, że require_once() oraz include_once() mogą zachowywać się w sposób nieoczekiwany na systemach operacyjnych nierozróżniających wielkości liter (non case-sensitive) - takich jak Windows.

Przykład 16-8. require_once() zwraca uwagę na wielkość liter

require_once("a.php"); // to wczyta plik a.php 
  require_once("A.php"); // na Windows to ponownie wczyta a.php !

Ostrzeżenie

PHP w wersji starszej niż 4.3.0, pracujące pod kontrolą systemów Windows, nie obsługują dostępu do zdalnych plików w tej funkcji, nawet jeśli opcja allow_url_fopen jest włączona.

Patrz także: require(), include(), include_once(), get_required_files(), get_included_files(), readfile(), i virtual().


include_once()

Instrukcja include_once() służy do wczytania i wykonania kodu z określonego pliku w trakcie wykonywania skryptu. Działanie instrukcji podobne jest do include(), z jednym wyjątkiem, tzn. jeśli dany plik został już raz do danego skryptu wczytany, nie będzie już wczytany ponownie. Wskazuje na to nazwa instrukcji: include_once znaczy wczytaj_raz.

include_once() powinno być stosowane w przypadkach, gdzie ten sam plik może być wczytany więcej niż raz w czasie wykonywania skryptu, ale ty chcesz mieć pewność że będzie wczytany tylko jeden raz, aby uniknąć problemów z redefiniowaniem funkcji, nadpisaniem wartości zmiennych, itp.

Więcej przykładów wykorzystania require_once() i include_once() znajdziesz w kodzie PEAR dołączonym do najnowszych dystrybucji kodu źródłowego PHP.

Notatka: include_once() dodano w PHP 4.0.1pl2

Notatka: Proszę pamiętać, że require_once() oraz include_once() mogą zachowywać się w sposób nieoczekiwany na systemach operacyjnych nierozróżniających wielkości liter (non case-sensitive) - takich jak Windows.

Przykład 16-9. include_once() zwraca uwagę na wielkość liter

include_once("a.php"); // to wczyta plik a.php 
  include_once("A.php"); // na Windows to ponownie wczyta a.php !

Ostrzeżenie

PHP w wersji starszej niż 4.3.0, pracujące pod kontrolą systemów Windows, nie obsługują dostępu do zdalnych plików w tej funkcji, nawet jeśli opcja allow_url_fopen jest włączona.

Patrz także include(), require(), require_once(), get_required_files(), get_included_files(), readfile(), i virtual().


Rozdział 17. Funkcje

Funkcje zdefiniowane przez użytkownika

Funkcja może być zdefiniowana używając składni takiej jak poniższa:

Przykład 17-1. Pseudo-kod ilustrujący zastosowanie funkcji

<?php
function foo ($arg_1, $arg_2, /* ..., */ $arg_n)
{
    echo "Przykładowa funkcja.\n";
    return $retval;
}
?>

Dowolny poprawny kod PHP może się pojawić wewnątrz funkcji, także definicje innych funkcji i klas.

Nazwy funkcji podlegają takim samym ograniczeniom jak wszystkie inne etykiety w PHP. Poprawna nazwa funkcji zaczyna się od litery lub podkreślenia, po których następuje dowolna liczba liter, liczb lub podkreśleń. Powyższa zasada w postaci wyrażenia regularnego przedstawia się następująco: [a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*.

W PHP 3, funkcje muszą być zdefiniowane przed odwołaniem do nich. W PHP 4 nie ma takiego wymagania. Wyjątkiem jest warunkowe definiowanie funkcji, tak jak pokazano to w dwóch przykładach zamieszczonych poniżej.

Kiedy funkcja jest definiowana w postaci warunkowej, tak jak to przedstawiono na dwóch poniższych przykładach, jej definicja musi następować przed jej wywołaniem.

Przykład 17-2. Funkcje warunkowe

<?php

$makefoo = true;

/* Nie można wywołać foo() z tego miejsca,
   ponieważ funkcja ta jeszcze nie istnieje.
   Można natomiast wywołać bar() */

bar();

if ($makefoo) {
  function foo()
  {
    echo "Nie istnieję dopóki wykonanie programu nie dojdzie do tego miejsca.\n";
  }
}

/* W tym momencie można spokojnie wywołać foo()
   ponieważ $makefoo ma wartość true */

if ($makefoo) foo();

function bar() 
{
  echo "Istnieję od samego początku działania programu.\n";
}

?>

Przykład 17-3. Funkcje wewnątrz funkcji

<?php
function foo() 
{
  function bar() 
  {
    echo "Nie istnieję dopóki foo() nie zostanie wywołana.\n";
  }
}

/* Nie można wywołać bar()
   ponieważ nie istnieje. */

foo();

/* Teraz można wywołać bar(),
   ponieważ wywołanie foo() utworzyło
   tą funkcję. */

bar();

?>

Wszystkie funkcje i klasy w PHP mają zasięg globalny - można je wywołać spoza ciała funkcji, nawet jeśli zostały w niej zdefiniowane, i vice versa.

PHP nie obsługuje przeciążania funkcji. Nie jest także możliwa od-definiowanie lub przedefiniowanie wcześniej zadeklarowanych funkcji.

Notatka: W nazwach funkcji nie jest istotna wielkość znaków, jednakże dobrze jest wywoływać funkcje tak, jak zostały zdeklarowane.

PHP 3 nie obsługuje funkcji o zmiennej liczbie argumentów, ale obsługuje domyślne argumenty (zobacz rozdzial Wartości domyślne argumentów aby uzyskać więcej informacji). Od wersji PHP 4 obsługiwane są jedne i drugie: zobacz Listy argumentów o zmiennej długości i opisy funkcji func_num_args(), func_get_arg(), i func_get_args() aby uzyskać więcej informacji.

W PHP możliwe jest rekurencyjne wywoływanie funkcji. Należy jednak unikać rekurencyjnych wywołań funkcji lub metod o głębokości większej niż 100-200 poziomów, gdyż może to zniszczyć stos i spowodować przerwanie działania skryptu.

Przykład 17-4. Funkcje rekurencyjne

<?php
function rekurencja($a)
{
    if ($a < 20) {
        echo "$a\n";
        rekurencja($a + 1);
    }
}
?>


Argumenty funkcji

Informacje mogą być przekazywane do funkcji przez listę argumentów, która jest separowaną przecinkami listą wyrażeń.

PHP obsługuje przekazywanie argumentów przez wartość (domyślnie), przez referencję , i wartości domyślne argumentów. Listy argumentów o zmiennej długości są obsługiwane tylko w PHP 4 i nowszych; zobacz rozdział Listy argumentów o zmiennej długości i opisy funkcji func_num_args(), func_get_arg(), i func_get_args() aby uzyskać więcej informacji. Podobny efekt może być uzyskany w PHP 3 przez przekazywanie tablicy argumentów do funkcji.

Przykład 17-5. Przekazywanie tablic do funkcji

function pobiera_tablice($wejscie)
{
    echo "$wejscie[0] + $wejscie[1] = ", $wejscie[0]+$wejscie[1];
}


Przekazywanie argumentów przez referencję

Domyślnie, argumenty funkcji są przekazywane przez wartość (a więc jeśli zmienisz wartość argumentu wewnątrz funkcji, nie zmieni się ona poza funkcją). Jeśli chcesz pozwolić funkcji na modyfikację swoich argumentów, musisz przekazać je przez referencję.

Jeśli chcesz, aby argumenty były zawsze przekazywane przez referencję, przed nazwą zmiennej w definicji funkcji wstaw znak ampersand (&):

Przykład 17-6. Przekazywanie argumentów przez referencję

<?php
function dodaj_cos_extra(&$string)
{
    $string .= 'i coś extra.';
}
$str = 'To jest string, ';
dodaj_cos_extra($str);
echo $str;    // wyświetla 'To jest string string, i coś extra.'
?>


Wartości domyślne argumentów

Funkcja może definiować, podobnie jest w C++, wartości domyślne dla argumentów skalarnych.

Przykład 17-7. Użycie domyślnych wartości argumentów

<?php
function rob_kawe ($typ = "cappucino")
{
    return "Robię kubek $typ.\n";
}
echo rob_kawe ();
echo rob_kawe ("espresso");
?>

Powyższy kawałek kody wyświetli:

Robię kubek cappucino.
Robię kubek espresso.

PHP pozwala także na korzystanie z tablic i specjalnego typu NULL jako wartości domyślnych.

Przykład 17-8. Używanie nieskalarnych typów jako wartości domyślne

<?php
function rob_kawe($typy = array("cappuccino"), $urzadzenie = NULL)
{
    $urzadzenie = is_null($urzadzenie) ? "rece" : $urzadzenie;
    return "Robie kubek ".join(", ", $types)." poprzez $urzadzenie.\n";
}
echo rob_kawe();
echo rob_kawe(array("cappuccino", "lavazza"), "ekspres");
?>

Domyślna wartość musi być stałym wyrażeniem, nie (na przykład) zmienną. członkiem klasy lub wywołaniem funkcji.

Zauważ, że używając domyślnych argumentów, argumenty zawierające wartości domyślne powinny być po prawej stronie tych nie zawierających wartości domyślnych; w przeciwnym przypadku funkcja może nie działać tak jak się tego spodziewałeś. Przedstawione to zostało na poniższym przykładzie.

Przykład 17-9. Błędne zastosowanie domyślnych argumentów funkcji

<?php
function robjogurt ($typ = "acidophilus", $smak)
{
    return "Robię miskę $typ $smak.\n";
}
 
echo robjogurt ("malinowy");   // nie działa tak jak się spodziewaliśmy
?>

Powyższy przykład wyświetli:

Warning: Missing argument 2 in call to robjogurt() in 
/usr/local/etc/httpd/htdocs/php3test/functest.html on line 41
Robię miskę malinowy .

Porównaj powyższy przykład z tym:

Przykład 17-10. Poprawne użycie domyślnych argumentów funkcji

<?php
function robjogurt ($smak, $typ = "acidophilus")
{
    return "Robię miskę $type $flavour.\n";
}
 
echo robjogurt ("malinowy");   // działa tak jak się spodziewaliśmy
?>

Powyższy kod wyświetli:

Robię miskę acidophilus malinowy.

Notatka: Od PHP 5, domyślne argumenty funkcji mogą być przekazywane przez referencję.


Listy argumentów o zmiennej długości

PHP 4 i nowsze obsługują listy o zmiennej długości w funkcjach zdefiniowanych przez użytkownika. Jest naprawdę prostę przy użyciu funkcji func_num_args(), func_get_arg() i func_get_args().

Nie wymagana jest żadna specjalna składnia. Listy argumentów mogą być ciągle jawnie podane przy definicji funkcji i będą się zachowywać normalnie.


Zwracane wartości

Wartości są zwracane przy użyciu opcjonalnej instrukcji return. Może być zwracany dowonlny typ, włączając w to tablice i obiekty. Spowoduje to natychmiastowe zakończenie działania funkcji i przekazanie kontroli do linii, z której była wywołana. Więcej informacji w opisie return().

Przykład 17-11. Zastosowanie return()

<?php
function kwadrat ($num)
{
    return $num * $num;
}
echo kwadrat (4);   // wyświetla '16'.
?>

Nie można zwracać zwracać wielu wartości z funkcji, ale podobne efekty mogą być uzyskane przez zwracanie listy.

Przykład 17-12. Zwracanie tablicy dla uzyskania wielu wyników

<?php
function maleLiczby()
{
    return array (0, 1, 2);
}
list ($zero, $jeden, $dwa) = maleLiczby();
?>

Aby funkcja zwracała referencję, musisz użyć operatora referencji & i w deklaracji funkcji i przy przypisywaniu zwracanej wartości do zmiennej.

Przykład 17-13. Zwracanie referencji przez funkcję

<?php
function &zwrocReferencje()
{
    return $jakasref;
}

$nowaref =& zwrocReferencje();
?>

Więcej informacji na temat referencji w rozdziale References Explained.


Zmienne funkcje

PHP obsługuje koncepcję zmiennych funkcji. Oznacza to, że jeśli po nazwie zmiennej występują nawiasy, PHP będzie szukało funkcji o nazwie będącej wartością zmiennej i będzie próbowało wywołać ją. Między innymi może być to użyte do implementacji funkcji callback, tablicy funkcji itp.

Zmienne funkcje nie będą działać z elementami składowymi języka takimi jak echo(), print(), unset(), isset(), empty(), include(), require() i innymi podobnymi. Aby zastosować zmienne funkcje z takimi składowymi, niezbędne jest zastosowanie funkcji obudowujących.

Przykład 17-14. Przykład zmiennej funkcji

<?php
function foo() {
    echo "W foo()<br />\n";
}

function bar($arg = '') {
    echo "W bar(); argumentem jest '$arg'.<br />\n";
}

// Funkcja obudowująca składnię echo

function echoIt($string) {
    echo $string;
}

$func = 'foo';
$func(); // wywoła foo()

$func = 'bar';
$func('test'); // wywoła bar()

$func = 'echoIt';
$func('test'); // wywoła echoIt()
?>

Możliwe jest także wywołanie metody obiektu korzystając z mechanizmu zmiennych funkcji. You can also call an object's method by using the variable functions feature.

Przykład 17-15. Przykład zmiennych metod

<?php
class Foo
{
    function Zmienna()
    {
        $name = 'Bar';
        $this->$name(); // Wywoła metodę Bar()
    }
    
    function Bar()
    {
        echo "To jest Bar";
    }
}

$foo = new Foo();
$funkcja = "Zmienna";
$foo->$funkcja();  // Wywoła $foo->Zmienna()

?>

Patrz także call_user_func(), variable variables i function_exists().


Wewnętrzne (wbudowane) funkcje

PHP standardowo zawiera wiele funkcji i składni. Istnieje także wiele funkcji, które wymagają skompilowania konkretnych rozszerzeń PHP, gdyż w przeciwnym wypadku próba ich wywołania spowoduje błąd "undefined function". Na przykład, aby używać funkcji przetwarzania obrazów, jak na przykład imagecreatetruecolor(), niezbędne jest skompilowanie PHP z obsługą GD. Podobnie, aby skorzystać z funkcji mysql_connect(), trzeba mieć PHP skompilowane z obsługą MySQL. Jest także wiele funkji, które są zawarte w każdej wersji PHP, jak na przykład funkcje obsługi ciągów znakowych czy zmiennych. Listę załadowanych rozszerzeń można uzyskać przez wywołanie funkcji phpinfo() lub get_loaded_extensions(). Warto zauważyć, że niektóre rozszerzenia są domyślnie włączone, a także że podręcznik PHP jest podzielony według rozszerzeń. Informacje na temat przygotowania swojego PHP można znaleźć w rozdziałach poświęconych konfiguracji, instalacji, a także w rozdziałach dotyczących poszczególnych rozszerzeń.

Czytanie i rozumienie prototypów funkcji zostało wyjaśnione w rozdziale Jak czytać definicje funkcji. Bardzo ważne jest zrozumienie co funkcja zwraca lub czy funkcja operuje bezpośrednio na przekazywanych wartościach. Na przykład, str_replace() zwróci zmodyfikowany ciąg znakowy, natomiast usort() pracuje bezpośrednio na tablicy przekazanej jako argument. Każda strona podręcznika zawiera także konkretne informacje na temat argumentów wywołania funkcji, zmian zachowania, zwracanych wartościach, zarówno w przypadku powodzenia jak i wystąpienia błędu, a także informacje o dostępności. Znajomość tych ważnych, choć czasem subtelnych różnic, jest kluczowa dla pisania poprawnego kodu PHP.

Patrz także function_exists(), indeks funkcji, get_extension_funcs() i dl().


Rozdział 18. Klasy i obiekty (PHP 4)

klasa

Klasa jest to zbiór zmiennych i funkcji operujących na tych zmiennych. Do definicji klasy używana jest następująca składnia:

<?php
class Koszyk {
    var $zakupy;  // Zakupy w naszym koszyku
   
    // Dodaj $num artykułów typu $artnr do wózka
 
    function dodaj_produkt ($artnr, $num) {
        $this->zakupy[$artnr] += $num;
    }
   
    // Usuń $num artykułów typu $artnr z wózka
 
    function usun_produkt ($artnr, $num) {
        if ($this->zakupy[$artnr] > $num) {
            $this->zakupy[$artnr] -= $num;
            return true;
        } elseif ($this->zakupy[$artnr] == $num) {
            unset($this->zakupy[$artnr]);
            return true;
        } else {
            return false;
        }   
    }
}
?>

Definiuje to klasę o nazwie Koszyk, która zawiera tablicę asocjacyjną artykułów znajdujących się w wózku i dwie funkcje do dodawania i usuwania produktów z koszyka.

Ostrzeżenie

NIE jest możliwe rozbicie definicji klasy na wiele plików. Także NIE jest możliwe rozbicie definicji klasy na wiele bloków PHP, chyba że rozbicie to znajduje się wewnątrz definicji metody. Poniższy kod nie będzie działać.

<?php
class test {
?>
<?php
    function test() {
        print 'OK';
    }
}
?>

Jednakże poniższy kod jest dozwolony:

<?php
class test {
    function test() {
        ?>
        <?php
        print 'OK';
    }
}
?>

Poniższe uwagi dotyczą PHP 4.

Uwaga!

Nazwa stdClass jest używana wewnętrznie przez Zend i jest zarezerwowana. W PHP nie możesz zdefiniować klasy o nazwie stdClass.

Uwaga!

Nazwy funkcji __sleep i __wakeup mają magiczne znaczenie dla klas w PHP. Klasy nie mogą zawierać funkcji o tych nazwach, chyba że zgadzasz się na przypisanie do nich magicznej funkcjonalności. Poniżej możesz znaleźć więcej informacji.

Uwaga!

PHP rezerwuje wszystkie nazwy funkcji zaczynające się od __ na funkcje magiczne. Zalecane jest nieużywanie funkcji z nazwami zaczynającymi się od __ chyba że chcesz jakiejś magicznej funkcjonalności.

W PHP 4 dozwolone są tylko stałe inicjalizatory zmiennych var. Aby zainicjalizować zmienne z nie-stałymi wartościami, potrzebujesz funkcję inicjalizacyjną, która jest wywoływana automatycznie zaraz po utworzeniu obiektu z danej klasy. Taka funkcja zwana jest konstruktorem (zobacz poniżej).

<?php
class Koszyk {
/* Nic z tego nie będzie działać w PHP 4. */
    var $dzisiejsza_data = date("Y-m-d");
    var $nazwa = $imie;
    var $wlasciciel = 'Fred ' . 'Jones';
/* Jednakże tablice zawierające stałe - będą */
    var $artykuly = array("VCR", "TV");
}

/* Teraz wszystko zadziala. */
class Koszyk {
    var $dzisiejsza_data;
    var $nazwa;
    var $wlasciciel;
    var $artykuly = array("VCR", "TV");

    function Koszyk() {
        $this->dzisiejsza_data = date("Y-m-d");
        $this->nazwa = $GLOBALS['imie'];
        /* itp. . . */
    }
?>

Klasy są typami, które są w zasadzie tylko schematami dla właściwych zmiennych. Zmienne pożądanego typu musisz stworzyć korzystając z operatora new.

<?php
$koszyk = new Koszyk;
$koszyk->dodaj_produkt("10", 1);

$inny_koszyk = new Koszyk;
$inny_koszyk->dodaj_produkt("0815", 3);

Kod ten tworzy obiekty $koszyk i $inny_koszyk, oba klasy Koszyk. Funkcja dodaj_produkt() obiektu $koszyk zostaje wywołana w celu dodania 1 artykułu typu "10" do koszyka $koszyk. 3 przedmioty typu "0815" dodawane są do koszyka $inny_koszyk.

I $koszyk i $inny_koszyk mają funkcje dodaj_produkt(), usun_produkt() i zmienne. Są to osobne funkcje i zmienne. Obiekty mogą być postrzegane jako katalogi w systemie plików. W systemie plików możesz mieć dwa różne pliki README.TXT, ale tylko jeśli istnieją w osobnych katalogach. Aby odczytać plik, będąc w głównym katalogu, musisz podać pełną ścieżkę do tego pliku. Tak samo jest przy obiektach: musisz podać pełną nazwę funkcji, z której chcesz skorzystać. W terminologii PHP katalogiem głównym będzie globalna przestrzeń nazw a separatorem ścieżki będzie ->. W związku z tym nazwy $koszyk i $inny_koszyk zawierają zupełnie inne zmienne. Zauważ, że zmienna nazywa się $koszyk->artykuly, a nie $koszyk->$artykuly, ponieważ nazwa zmiennej może zawierać tylko jeden znak dolara.

<?php
// poprawnie, jeden $
$koszyk->artykuly = array("10" => 1); 

// niepoprawnie, poniważ $koszyk->$artykuly zamienia się na $koszyk->""
$koszyk->$artykuly = array("10" => 1);

// poprawnie, ale może (ale nie musi) nie być tym, co zamierzaliśmy:
// $koszyk->$zmienna staje się $koszyk->artykuly
$zmienna = 'artykuly';
$koszyk->$zmienna = array("10" => 1);
?>

Wewnątrz definicji klasy, nie wiesz pod jaką nazwą obiekt będzie dostępny dla twojego programu: w momencie pisania klasy Koszyk, nie było wiadomo, czy obiekty będą się nazywać $koszyk, $inny_koszyk, lub inaczej. W związku z tym nie możesz napisać $koszyk->artykuly wewnątrz klasy Koszyk. Zamiast tego, aby uzyskać dostęp do funkcji i zmiennych zawartych w klasie, można użyć pseudo-zmiennej $this, która może być odczytana jako 'moje własne' lub 'bieżący obiekt'. A więc '$this->artykuly[$nrart] += $liczba' może być odczytane jako 'dodaj $liczba do licznika $nrart z mojej własnej tablicy artykuly' lub 'dodaj $liczba do licznika $nrartz tablicy artykuly zawartej w bieżącym obiekcie'.

Notatka: The $this pseudo-variable is not usually defined if the method in which it is hosted is called statically. This is not, however, a strict rule: $this is defined if a method is called statically from within another object. In this case, the value of $this is that of the calling object. This is illustrated in the following example:

<?php
class A
{
    function foo()
    {
        if (isset($this)) {
            echo '$this is defined (';
            echo get_class($this);
            echo ")\n";
        } else {
            echo "\$this is not defined.\n";
        }
    }
}

class B
{
    function bar()
    {
        A::foo();
    }
}

$a = new A();
$a->foo();
A::foo();
$b = new B();
$b->bar();
B::bar();
?>

Powyższy przykład wyświetli:

$this is defined (a)
$this is not defined.
$this is defined (b)
$this is not defined.

Notatka: Istnieje kilka przyjemnych funkcji do obsługi klas i obiektów. Możesz je zobaczyć w rozdziale Funkcje obsługi klas i obiektów.


extends

Bardzo często zachodzi potrzeba stworzenia klasy o funkcjach i zmiennych podobnych do już istniejącej klasy. Zasadniczo dobrze jest stworzyć szablonową klasę, która może być użyta we wszystkich twoich projektach i przystosowywać ją do specyficznych potrzeb twojego projektu. Aby ułatwić ten proces, klasy mogą być rozszerzeniami innych klas. Rozszerzone, lub mówiąc inaczej 'dziedziczone', klasy mają wszystkie zmienne i funkcje klasy podstawowej (nazywa się to dziedziczeniem, mimo że nikt nie umarł) oraz to co do niej dodałeś w definicji rozszerzenia. Nie można odjąć pewnych rzeczy z klasy podstawowej, czyli oddefiniować istniejących w klasie podstawowej funkcji i zmiennych. Rozszerzona klasa jest zawsze zależna od jednej klasy bazowej - dziedziczenie wielokrotne nie jest obsługiwane. Klasy można rozszerzyć używając słowa kluczowego 'extends'.

<?php
class Nazwany_Koszyk extends Koszyk {
    var $wlasciciel;
  
    function ustaw_wlasciciela ($nazwa) {
        $this->wlasciciel = $nazwa;
    }
}
?>

Definiuje to klasę Nazwany_Koszyk, który ma wszystkie zmienne i funkcje klasy Koszyk plus dodatkowa zmienna $wlasciciel i dodatkowa funkcja ustaw_wlasciciela(). Nazwany koszyk tworzy się normalnym sposobem. Możesz teraz ustawiać i pobierać nazwę właściciela koszyka. Cały czas możesz używać zwykłych funkcji koszyka dla nazwanego koszyka:

<?php
$nkoszyk = new Nazwany_Koszyk;        // Stwórz nazwany koszyk
$nkoszyk->ustaw_wlasciciela("kris");  // Nazwij koszyk
print $nkoszyk->wlasciciel;           // Wyświetl właściciela koszyka
$nkoszyk->dodaj_przedmiot("10", 1);   // (funkcjonalność odziedziczona z
                                      // koszyka)
?>

Taka relacja nazywana jest często relacją "rodzic-potomek". Tworzysz klasę - rodzica - i używasz extends aby stworzyć klasę opartą o klasę rodzica: klasę potomną. Możesz także tworzyć nowe klasy potomne oparte o tą klasę potomną.

Notatka: Klasy musza być zdefiniowane zanim zostaną użyte! Jeśli chcesz, aby klasa Nazwany_Koszyk rozszerzała klasę Koszyk, musisz zdefiniować klasę Koszyk jako pierwszą. Jeśli chcesz stworzyć kolejną klasę nazwaną Niebieski_Nazwany_Koszyk opartą o klasę Nazwany_Koszyk, musisz najpierw zdefiniować klasę Nazwany_Koszyk. W skrócie: kolejność, w jakiej klasy są definiowane, jest bardzo ważna.


Konstruktory

Konstruktory są funkcjami klasy, które są automatycznie wywoływane przy tworzeniu nowej instancji klasy korzystając z operatora new. Funkcja staje się konstruktorem kiedy ma taką samą nazwę jak klasa. Jeśli klasa nie ma konstruktora, użyty zostanie konstruktor klasy nadrzędnej, jeśli taka istnieje.

<?php
class Auto_Koszyk extends Koszyk {
    function Auto_Koszyk()
    {
        $this->dodaj_artykul ("10", 1);
    }
}
?>

Ten kod definiuję klasę Auto_Koszyk, który jest klasą Koszyk pluc konstruktor, który inicjalizuje wózek z jednym artykułem "10" za każdym razem, kiedy Auto_Koszyk jest tworzony operatorem "new". Konstruktory mogą pobierać argumenty i te argumenty mogą być opcjonalne, przez co są jeszcze bardziej użyteczne. Aby w dalszym ciągu móc używać klasy bez parametrów, wszystkie parametry konstruktora powinny stać się opcjonalne przez dodanie domyślnych wartości.

<?php
class Kontruktor_Koszyk extends Koszyk {
    function Konstruktor_Koszyk($artykul = "10", $ilosc = 1)
    {
        $this->dodaj_artykul ($artykul, $ilosc);
    }
}
 
// Kup te same nudne rzeczy...
$zwykly_koszyk = new Konstruktor_Koszyk;
 
// Czas na prawdziwe zakupy...
$inny_koszyk = new Konstruktor_Koszyk("20", 17);
?>

Możesz także użyć operatora @ aby wyciszyć błędy zachodzące w konstruktorze, np. @new

<?php
class A
{
    function A()
    {
        echo "Jestem konstruktorem klasy A.<br />\n";
    }

    function B()
    {
        echo "Jestem zwykłą funkcją o nazwie B w klasie A.<br />\n";
        echo "Nie jestem konstruktorem w klasie A.<br />\n";
    }
}

class B extends A
{
}

// Wywoła to B() jako konstruktor.
$b = new B;
?>

Funkcja B() z klasy A niespodziewanie stanie się konstruktorem w klasie B, pomimo że wcale nie miała nim być. PHP 4 nie obchodzi czy funkcja została zdefiniowana w klasie B czy została odziedziczona.

Uwaga!

PHP 4 nie wywołuje automatycznie konstruktora klasy bazowej z kontruktora klasy pochodnej. Twoim zadaniem jest propagacja wywołań konstruktorów klas nadrzędnych, jeśli to konieczne.

Destruktory są funkcjami, które są wywoływanie automatycznie kiedy obiekty są niszczone albo przez użycie unset() albo przez wyjście z zasięgu. W PHP nie ma destruktorów. Można jednak użyć funkcji register_shutdown_function() aby symulować działanie destruktorów.


Operator rozróżnienia zasięgu (::)

Uwaga!

Poniższe dotyczy tylko PHP 4 i nowszych.

Czasami dobrze jest odnosić się do funkcji i zmiennych w klasie bazowej lub odnosić się do funkcji i klas które nie mają jeszcze instancji. Służy do tego operator ::.

<?php
class A {
    function przyklad() {
        echo "Jestem orginalną funkcją A::przyklad().<br />\n";
    }
}

class B extends A {
    function przyklad() {
        echo "Jestem przedefiniowaną funkcją B::przyklad().<br />\n";
        A::przyklad();
    }
}

// nie ma obiektu klasy A.
// poniższe wyświetli
//   Jestem orginalną funkcją A::przyklad().<br />
A::przyklad();

// stwórz nowy obiekt klasy B.
$b = new B;

// poniższe wyświetli
//   Jestem przedefiniowaną funkcją B::przyklad().<br />
//   Jestem orginalną funkcją A::przyklad().<br />
$b->przyklad();
?>

Powyższy przekład wywołuje funkcję przyklad() z klasy A, ale nie tworząc obiektu tej klasy, przez co nie możemy napisać nic w stylu $a->przyklad(). Zamiast tego możemy wywołać przyklad() jako 'funkcję klasy', czyli jako funkcję tylko klasy, nie żadnego obiektu tej klasy.

Istnieją funkcje klasy, ale nie ma zmiennych klasy. Faktycznie w czasie wykonania nie ma żadnego obiektu. W związku z tym funkcje klasy nie mogą używać żadnych zmiennych obiektu (ale mogą używać zmiennych lokalnych i globalnych), ani w ogóle $this.

W powyższym przykładzie, klasa B przedefiniowuje funkcję przyklad(). Orginalna definicja z klasy A jest zasłonięta i niedostępna, chyba że odwołasz się do konkretnej implementacji poprzez operator ::. Aby to zrobić, napisz A::przyklad() (powinieneś jednak użyć parent::przyklad(), tak jak to pokazano w następnej części).

W tym kontekście, istnieje bieżący obiekt i który ma zmienne obiektu. W związu z tym jeśli funkcja jest użyta Z WEWNĄTRZ funkcji obiektu, możesz używać $this i zmiennych obiektu.


parent

Może się zdarzyć, że będziesz pisał kod, który odnosi się do funkcji i zmiennych klasy bazowej. Jest to możliwe jeśli twoja klasa pochodna jest uściśleniem lub specjalizacją klasy bazowej.

Zamiast jawnego podawania nazwy klasy bazowej w kodzie, powinieneś użyć specjalnej nazwy parent, która odnosi się do nazwy klasy bazowej podanej przy extends podczas deklaracji twojej klasy. Robiąc to, unikasz użycia nazwy klasy bazowej w więcej niż jednym miejscu. Jeśli twoje drzewo dziedziczenia zmieniłoby się podczas implementacji, zmiana będzie wymagała poprawki tylko w jednym miejscu - przy słowie kluczowym extends w deklaracji klasy.

<?php
class A {
    function przyklad() {
        echo "Jestem A::przyklad() I dostarczam podstawową funkcjonalność.<br />\n";
    }
}

class B extends A {
    function przyklad() {
        echo "Jestem B::przyklad() i dostarczam dodatkową funkcjonalność.<br />\n";
        parent::przyklad();
    }
}

$b = new B;

// Wywoła to B::przyklad(), który z kolei wywoła A::przyklad().
$b->przyklad();
?>


Serializacja obiektów - obiekty w sesjach

Notatka: W PHP 3 obiekty tracą powiązania między klasami w czasie procesu serializacji i odserializacji. Wynikowa zmienna będzie typu obiekt, ale bez klasy i bez metod, a więc w zasadzie bezużyteczną (zostanie poprostu zmienną ze śmieszną składnią).

Uwaga!

Poniższe informacje dotyczą tylko PHP > 4.

serialize() zwraca string będący reprezentacją dowolnej wartości, która może być przechowywana przez PHP. unserialize() może użyć tego stringu aby odtworzyć orginalne wartości zmiennej. Użycie serializacji do zapisania obiektu zachowa wszystkie zmienne z obiektu. Zapisane nie będą funkcje z obiektu, a jedynie nazwa klasy.

Aby istniała możliwość użycia funkcji unserialize() do odzyskania obiektu, musi być zdefiniowana klasa tego obiektu. Oznacza to, że jeśli obiekt $a klasy A istnieje na page1.php i zostanie on zserializowany, otrzymany zostanie ciąg znakowy, który odnosi się do klasy A i zawiera wartości wszystkich zmiennych zawartych w $a. Aby istniała możliwość deserializacji tego obiektu na page2.php, na page2.php musi istnieć definicja klasy A. Można to zrobić na przykład przez przechowywanie definicji klasy A w zewnętrznym pliku dołączanym przez page1.php i page2.php.

<?php
// classa.inc:
  class A {
      var $jeden = 1;
    
      function pokaz_jeden() {
          echo $this->jeden;
      }
  }
  
// page1.php:

  include("classa.inc");
  
  $a = new A;
  $s = serialize($a);
  // przechowaj $s gdzieś, gdzie page2.php będzie mogła go znaleźć
  $fp = fopen("store", "w");
  fwrite($fp, $s);
  fclose($fp);

// page2.php:

  // to jest niezbędne aby funkcja unserialize działała prawidłowo.
  include("classa.inc");

  $s = implode("", @file("store"));
  $a = unserialize($s);

  // teraz użyj funkcji pokaz_jeden z obiektu $a.
  $a->pokaz_jeden();
?>

Jeśli używasz sesji i session_register() do rejestracji obiektów, te obiekty są serializowane automatycznie na końcu każdej strony PHP i odserializowane automatycznie na każdej z następnych stron. Zasadniczo znaczy to, że te obiekty mogą pokazać się na dowolnej z twoich stron jeśli tylko staną się częścią twojej sesji.

Mocno zalecane jest includowanie definicji klas wszystkich zarejestrowanych obiektów na wszystkich twoich stronach, nawet jeśli nie używasz tych zmiennych na twoich stronach. Jeśli tego nie zrobisz a obiekty zostaną odserializowane bez definicji klasy, powiązania klasowe zostaną utracone a obiek stanie się obiektem klasy stdClass bez żadnych dostępnych funkcji, a więc będzie całkiem bezużyteczny.

A więc jeśli w powyższym przykładzie $a stanie się częścią sesji przez wywołanie session_register("a"), powinieneć includować plik classa.inc na wszystkich stronach, nie tylko page1.php i page2.php.


Magiczne funkcje __sleep i __wakeup

serialize() sprawdza, czy twoja klasa zawiera funkcję o magicznej nazwie __sleep. Jeśli tak, ta funkcja jest wywoływana przed każdą serializacją. Może ona czyścić obiekt i powinna zwracać tablicę z nazwami wszystkich zmiennych obiektu, które powinny być serializowane.

Założonym użyciem __sleep jest zamknięcie wszystkich połączeń do baz danych, które obiekt może utrzymywać, zatwierdzenie wszystkich oczekujących danych lub wykonanie innych podobnych czynności czyszczących. Funkcja ta jest także przydatna jeśli masz bardzo duże obiekty, które nie muszą być zachowane w całości.

Analogicznie, unserialize() sprawdza czy istnieje funkcja o magicznej nazwie __wakeup. Jeśli tak, funkcja może rekonstruować dowolne zasoby które obiekt może posiadać.

Założonym użyciem __wakeup jest odnowienie połączeń z bazami danych, które mogły zostac utracone w procesie serializacji, oraz wykonanie innych czynności odbudowujących obiekt.


Referencje wewnątrz konstruktora

Tworzenie referencji wewnątrz konstruktora może prowadzić do dziwnych efektów. Ten rozdział ma pomóc w unikaniu takich problemów.

<?php
class Foo {
    function Foo($nazwa) {
        // stworz referencje wewnatrz globalnej tablicy $globalref
        global $globalref;
        $globalref[] = &$this;
        // ustaw nazwę na przekazaną wartość
        $this->ustawNazwe($nazwa);
        // i wyświetl ją
        $this->wyswietlNazwe();
    }

    function wyswietlNazwe() {
        echo "<br />",$this->nazwa;
    }
	
    function ustawNazwe($nazwa) {
        $this->nazwa = $nazwa;
    }
}
?>

Sprawdźmy, czy jest jakaś różnica pomiędzy $bar1, który jest tworzony przy pomocy operatora przypisania =, a $bar2, który został stworzony używając operatora referencji =&...

<?php
$bar1 = new Foo('ustawione w konstruktorze');
$bar1->wyswietlNazwe();
$globalref[0]->wyswietlNazwe();

/* wyjście:
ustawione w konstruktorze
ustawione w konstruktorze
ustawione w konstruktorze */

$bar2 =& new Foo('ustawione w konstruktorze');
$bar2->wyswietlNazwe();
$globalref[1]->wyswietlNazwe();

/* wyjście:
ustawione w konstruktorze
ustawione w konstruktorze
ustawione w konstruktorze */
?>

Wydaje się, że nie ma żadnej różnicy, ale na prawdę jest jedna, i to bardzo istotna: $bar1 i $globalref[0] NIE są referencjami, NIE są tą samą zmienna. Dzieje się tak, ponieważ "new" nie zwraca domyślnie referencji, ale kopię.

Notatka: Zwracanie kopii zamiast referencji nie powoduje utraty wydajności (od PHP 4 używane jest zliczanie referencji). Jednakże zazwyczaj lepiej jest pracować poprostu z kopiami zamiast referencji, poniewać tworzenie referencji zabiera trochę czasu, podczas gdy tworzenie kopii obiektów teoretycznie w ogóle nie zabiera czasu (chyba że któraś z tych zmiennych jest dużą tablicą lub obiektem i jedno z nich ulega zmianie, po czym tej samej zmianie ulegają pozostałe zmienne; wtedy lepiej jest użyć referencji do zmieniania ich równolegle).

Aby udowodnić to, co zostało zapisane powyżej, przyjrzyjmy się poniższemu programowi.

<?php
// teraz zmienimy nazwę. czego się spodziewasz?
// możesz się spodziewać, że i $bar1 i $globalref[0] zmienią swoje nazwy...
$bar1->ustawNazwe('ustawiona z zewnątrz');

// jak napisano powyżej, nic takiego się nie stanie
$bar1->wyswietlNazwe();
$globalref[0]->wyswietlNazwe();

/* wyjście:
ustawiona z zewnątrz
ustawiona w konstruktorze */

// zobaczmy co się dzieje z $bar2 i $globalref[1]
$bar2->ustawNazwe('ustawiona z zewnątrz');

// na szczęście ta zmienna nie zachowuje się jak ta z poprzedniego przypadku
// są to te same zmienne, z więc $bar2->nazwa i $globalref[1]->nazwa są także
// tymi samymi zmiennymi
$bar2->wyswietlNazwe();
$globalref[1]->wyswietlNazwe();

/* wyjście:
ustawiona z zewnątrz
ustawiona z zewnątrz */
?>

Ustatni przykład. Postaraj się go zrozumieć/

<?php
class A {
    function A($i) {
        $this->wartosc = $i;
        // domyśl się dlaczego nie potrzebujemy tutaj referencji
        $this->b = new B($this);
    }

    function stworzRef() {
        $this->c = new B($this);
    }

    function wyswietlWartosc() {
        echo "<br />","klasa ",get_class($this),': ',$this->value;
    }
}


class B {
    function B(&$a) {
        $this->a = &$a;
    }

    function wyswietlWartosc() {
        echo "<br />","klasa ",get_class($this),': ',$this->a->value;
    }
}
// spróbuj zrozumieć dlaczego użycie tu prostego kopiowania może powodować
// nieporządany efekt w linii uznaczonej znaczkiem '*'
$a =& new A(10);
$a->stworzRef();

$a->wyswietlWartosc();
$a->b->wyswietlWartosc();
$a->c->wyswietlWartosc();

$a->value = 11;

$a->wyswietlWartosc();
$a->b->wyswietlWartosc(); // *
$a->c->wyswietlWartosc();

?>

Powyższy przykład wyświetli:

klasa A: 10
klasa B: 10
klasa B: 10
klasa A: 11
klasa B: 11
klasa B: 11


Porównywanie obiektów

W PHP 4 obiekty są porównywane w bardzo prosty sposób, to znaczy dwie instancje obiektów są uważane za równe, jeśli posiadają te same atrybuty i ich wartości, a także są instancjami tej samej klasy. Podobne reguły są stosowane, jeśli dwa obiekty są porównywane za pomocą operatora identyczności (===).

Przykład 18-1. Przykład porównania obiektów w PHP 4

<?php
function bool2str($bool) {
    if ($bool === false) {
            return 'FALSE';
    } else {
            return 'TRUE';
    }
}

function porownajObiekty(&$o1, &$o2) {
    echo 'o1 == o2 : '.bool2str($o1 == $o2)."\n";
    echo 'o1 != o2 : '.bool2str($o1 != $o2)."\n";
    echo 'o1 === o2 : '.bool2str($o1 === $o2)."\n";
    echo 'o1 !== o2 : '.bool2str($o1 !== $o2)."\n";
}

class Flaga {
    var $flag;

    function Flaga($flag=true) {
            $this->flag = $flag;
    }
}

class przelaczalanaFlaga extends Flaga {

    function turnOn() {
        $this->flag = true;
    }

    function turnOff() {
        $this->flag = false;
    }
}

$o = new Flaga();
$p = new Flaga(false);
$q = new Flaga();

$r = new przelaczalnaFlaga();

echo "Porównaj instancje stworzone z tymi samymi argumentami\n";
porownajObiekty($o, $q);

echo "\nPorównaj instancje stworzone z różnymi argumentami\n";
porownajObiekty($o, $p);

echo "\nPorównaj instancję klasy nadrzędnej z instancją klasy podrzędnej\n";
porownajObiekty($o, $r);
?>

Powyższy przykład wyświetli:

Porównaj instancje stworzone z tymi samymi argumentami
o1 == o2 : TRUE
o1 != o2 : FALSE
o1 === o2 : TRUE
o1 !== o2 : FALSE

Porównaj instancje stworzone z różnymi argumentami
o1 == o2 : FALSE
o1 != o2 : TRUE
o1 === o2 : FALSE
o1 !== o2 : TRUE

Porównaj instancję klasy nadrzędnej z instancją klasy podrzędnej
o1 == o2 : FALSE
o1 != o2 : TRUE
o1 === o2 : FALSE
o1 !== o2 : TRUE

Wynik działania powyższego skryptu jest całkowicie przewidywalny na podstawie przedstawionych wyżej reguł. Tylko instancje o tych samych wartościach tych samych atrybutów, pochodzące z tej samej klasy, są uznawane za równe i identyczne.

Nawet w przypadku kompozycji obiektów stosowane są te same reguły porównywania. W poniższym przykładzie stworzona została klasa-pojemnik, która zawiera tablicę asocjacyjną obiektów klasy Flaga.

Przykład 18-2. Porównywanie obiektów złożonych w PHP 4

<?php
class ZbiorFlag {
    var $set;

    function ZbiorFlag($flagArr = array()) {
        $this->set = $flagArr;
    }

    function addFlag($name, $flag) {
        $this->set[$name] = $flag;
    }

    function removeFlag($name) {
        if (array_key_exists($name, $this->set)) {
            unset($this->set[$name]);
        }
    }
}


$u = new ZbiorFlag();
$u->addFlag('flag1', $o);
$u->addFlag('flag2', $p);
$v = new ZbiorFlag(array('flag1'=>$q, 'flag2'=>$p));
$w = new ZbiorFlag(array('flag1'=>$q));

echo "\nObiekty złożone u(o,p) i v(q,p)\n";
porownajObiekty($u, $v);

echo "\nu(o,p) i w(q)\n";
porownajObiekty($u, $w);
?>

Powyższy przykład wyświetli:

Obiekty złożone u(o,p) i v(q,p)
o1 == o2 : TRUE
o1 != o2 : FALSE
o1 === o2 : TRUE
o1 !== o2 : FALSE

u(o,p) i w(q)
o1 == o2 : FALSE
o1 != o2 : TRUE
o1 === o2 : FALSE
o1 !== o2 : TRUE


Rozdział 19. Classes and Objects (PHP 5)

Introduction

In PHP 5 there is a new Object Model. PHP's handling of objects has been completely rewritten, allowing for better performance and more features.


The Basics

class

Every class definition begins with the keyword class, followed by a class name, which can be any name that isn't a reserved word in PHP. Followed by a pair of curly braces, which contains the definition of the classes members and methods. A pseudo-variable, $this is available when a method is called from within an object context. $this is a reference to the calling object (usually the object to which the meth