Авторските права © 1997 - 2009 принадлежат на PHP Documentation Group. Този материал може да бъде разпространяван единствено според реда и условията определени по-нататък в Creative Commons Attribution 3.0 License или по-късен. Копие на лиценза Creative Commons Attribution 3.0 се разпространява с това ръководство, като последната версия се намира на » http://creativecommons.org/licenses/by/3.0/.
Ако се интересувате от разпространението или преиздаването на този документ - в цялост или на части от него, бил той променен или непроменен, или имате някакви въпроси, моля свържете се с притежателя на авторските права на » doc-license@lists.php.net. Забележете, че адресът е свързан с пощенски списък, който се съхранява публично.
PHP, което е съкращение от "PHP: Hypertext Preprocessor", е широко разпространен скриптов език с отворен код (Open Source), пригоден за различни цели, който е специално създаден за уеб разработване (Web development) и може да бъде вмъкван в HTML. Синтаксисът му се базира на C, Java и Perl, и е лесен за изучаване. Главната цел на езика е да позволи на уеб разработчиците да пишат динамични уеб страници бързо, но с PHP можете и много повече.
Това ръководство се състои предимно от справочник на функциите, но съдържа също и справочник на езика, обяснения на някои от основните възможности на PHP, както и друга допълнителна информация
Можете да свалите това ръководство в няколко формата от » http://www.php.net/download-docs.php. Повече информация относно начина, по който е разработено това ръководство може да бъде намерена в приложение 'Относно ръководството'. Ако се интересувате от историята на PHP, посетете съответното приложение.
На началната страница на ръководството, сме изтъкнали най-активните хора в момента, но има много хора, допринесли за ръководството, които помагат в работата ни, или в миналото са помогнали изключително много на проекта. Има много незнайни хора, които са помогнали с потребителски бележки, които постоянно се добавят на страниците на ръководството, и за чиято помощ ние сме много благодарни. Всички списъци по-долу са по азбучен ред.
Следните хора, са допринесли значително много за създаването и/или продължават да допринасят, като добавят съдържание към ръководството: Bill Abt, 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, Pierre-Alain Joye, Etienne Kneuss, Moriyoshi Koizumi, Rasmus Lerdorf, Andrew Lindeman, Stanislav Malyshev, Rafael Martinez, Rick McGuire, Yasuo Ohgaki, Derick Rethans, Rob Richards, Sander Roobol, Egon Schmid, Thomas Schoefbeck, Sascha Schumann, Dan Scott, Masahiro Takagi, Michael Wallner, Lars Torben Wilson, Jim Winstead, Jeroen van Wolffelaar и Andrei Zmievski.
Следните хора са допринесли, значително при редакцията на ръководството: Stig Bakken, Gabor Hojtsy, Hartmut Holzgraefe и Egon Schmid.
В момента най-активните отговорници са: Daniel Brown, Nuno Lopes, Felipe Pena, Thiago Pojda и Maciek Sokolewicz.
Тези хора също са положили доста усилия за поддръжката на потребителските бележки: Mehdi Achour, Daniel Beckham, Friedhelm Betz, Victor Boivie, Jesus M. Castagnetto, Nicolas Chaillan, Ron Chmara, Sean Coates, James Cox, Vincent Gevers, Sara Golemon, Zak Greant, Szabolcs Heilig, Oliver Hinckel, Hartmut Holzgraefe, Etienne Kneuss, Rasmus Lerdorf, Matthew Li, Andrew Lindeman, Aidan Lister, Hannes Magnusson, Maxim Maletsky, Bobby Matthis, James Moore, Philip Olson, Sebastian Picklum, Derick Rethans, Sander Roobol, Damien Seguy, Jason Sheets, Tom Sommer, Jani Taskinen, Yasuo Ohgaki, Jakub Vrana, Lars Torben Wilson, Jim Winstead, Jared Wyles и Jeroen van Wolffelaar.
PHP (рекурсивно съкращение от PHP: Hypertext Preprocessor) е широко използван скриптов език с отворен код, предназначен за обща употреба, който е изключително удобен за уеб разработки и може да се вгражда в HTML.
Добре, но какво означава това? Пример:
Example #1 Въвеждащ пример
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Пример</title>
</head>
<body>
<?php
echo "Здрасти, аз съм PHP-скрипт!";
?>
</body>
</html>
Вместо множество команди, които извеждат HTML (като при C и Perl),
PHP-страниците съдържат HTML с вграден код, който прави "нещо"
(в нашия случай извежда "Здрасти, аз съм PHP-скрипт!").
PHP-кодът се огражда със специални инструкции за начало и край
на обработката <?php и ?>,
които ви позволяват да преминавате и излизате от "PHP режима".
Това, което отличава PHP от примерно клиентски JavaScript, е че кодът се изпълнява на сървъра, генерира HTML, който се изпраща към клиента. Клиентът ще получи резултата от изпълнението на този скрипт, но няма да знае какъв код е генерирал този резултат. Дори можете да конфигурирате уеб сървъра си да обработва всички HTML-файлове с PHP и тогава няма как потребителите да знаят какво правите зад гърба им.
Най-хубавото нещо при използването на PHP е, че е изключително лесно за новаци, а разполага с много разширени възможности за професионалния програмист. Не се притеснявайте от четенето на дълги списъци с възможности. Много бързо можете да влезете в крачка и до няколко часа да започнете да пишете прости скриптове.
Въпреки че, програмирането на PHP е насочено основно към писането на скриптове от страна на сървъра, с него могат да се правят много други неща. Повече за това може да прочетете по-долу, в секцията Какво може да прави PHP?, или да прескочите направо към уводния урок, ако се интересувате само от уеб програмиране.
Всичко. PHP е насочено основно към писането на скриптове от страна на сървъра, така че, можете да правите всички, което може да се направи с която и да е CGI програма, като например приемане на данни от формуляр, генериране на динамично съдържание за страници или изпращане и получаване на бисквитки. А PHP може да върши и много други неща.
Има три основни области, в които се използват PHP-скриптове.
PHP може да се използва на всички по-известни операционни системи, в това число Линукс, много Юникс варианти (включително HP-UX, Solaris и OpenBSD), Microsoft Windows, Mac OS X, RISC OS, а вероятно и други. Също така PHP поддържа по-голяма част от съвременните уеб сървъри. Това включва Apache, Microsoft Internet Information Server, Personal Web Server, сървърите Netscape и iPlanet, Oreilly Website Pro server, Caudium, Xitami, OmniHTTPd, и много други. За по-голяма част от сървърите PHP разполага с модули, а за другите поддържайки CGI стандарта, PHP може да работи като CGI процесор.
Така с PHP имате свободата да изберете операционна система и уеб сървър. Освен това, ви е предоставена възможността да изберете да работите с процедурно програмиране, обектно-ориентирано програмиране, или смесица от двете. Въпреки че, не всяка стандартна възможност на ООП е реализирана в PHP 4, много библиотеки и големи приложения (включително и PEAR библиотеката) са написани единствено и само обектно-ориентиран код. С PHP 5 са коригирани някои слабости свързани с обектно-ориентираните възможности на PHP 4 и е въведен един завършен обектен модел.
С PHP вие не сте ограничени само в генерирането на HTML. Възможностите на PHP включват генериране на изображения, PDF файлове и дори Flash анимации (посредством libswf и Ming), които се генерират в реално време. Също така може да генерирате всякакъв текст, като например XHTML и всякакъв друг XML файл. PHP може автоматично да генерира тези файлове и да ги съхрани във файловата система, вместо да ги извежда на екрана, създавайки по този начин кеш от страна на сървъра за динамичното ви съдържание.
Една от най-сериозните и значителни възможности на PHP е поддръжката на широк набор от бази от данни. Създаването на уеб страници използващи бази от данни е изключително лесно. По настоящем се поддържат следните бази от данни:
Също така, разполагате и си разширение за абстракция на бази от данни (нарича се PDO), което ви предоставя прозрачно използване на всички бази от данни поддържани от това разширение. Освен това, PHP поддържа ODBC, Open Database Connection стандарта, така че, може да осъществявате връзки с други бази от данни, които поддържат този световен стандарт.
- Adabas D
- dBase
- Empress
- FilePro (само четене)
- Hyperwave
- IBM DB2
- Informix
- Ingres
- InterBase
- FrontBase
- mSQL
- Direct MS-SQL
- MySQL
- ODBC
- Oracle (OCI7 и OCI8)
- Ovrimos
- PostgreSQL
- SQLite
- Solid
- Sybase
- Velocis
- Unix dbm
PHP също така поддържа комуникация с други услуги посредством съответните протоколи, като LDAP, IMAP, SNMP, NNTP, POP3, HTTP, COM (при Windows) и още много други. Също така може директно да отваряте мрежови сокети и да осъществявате достъп посредством някой друг протокол. PHP също така има поддръжка на WDDX обмяна на данни, виртуално между всички езици за уеб програмиране. Говорейки за взаимосвързаност, трябва да се спомене, че PHP поддържа инстанцииране а Java обекти и възможността за прозрачното им използване като PHP обекти. Също така можете да използвате CORBA разширението, за осъществяване на достъп до отдалечени обекти.
PHP разполага с изключително удобни възможности за текстообработка, от разширени POSIX или Perl регулярни изрази, до разбор на XML документи. За осъществяване на достъп и извършване на разбор на XML документи, PHP 4 поддържа SAX и DOM стандартите, като също така може да използвате и XSLT разширението за преобразуване на на XML документи. При PHP 5 всички XML разширения са стандартизирани, на базата на libxml2, а с добавянето на SimpleXML и XMLReader поддръжката, значително е разширен набора от възможности.
Накрая, но не на последно място, разполагаме с други интересни разширения, като mnoGoSearch функциите за търсещата машина, функциите за ICQ Gateway, много помощни инструменти за компресия (gzip, bz2, zip), календарни преобразувания, преводи...
Както забелязвате, тази страница не е достатъчна, за да се опишат всички възможности и предимства на PHP. Прегледайте информацията за инсталиране на PHP и частта Справочник на функциите за повече информация относно споменатите по-горе разширения на PHP.
Here we would like to show the very basics of PHP in a short, simple tutorial. This text only deals with dynamic web page creation with PHP, though PHP is not only capable of creating web pages. See the section titled What can PHP do for more information.
PHP-enabled web pages are treated just like regular HTML pages and you can create and edit them the same way you normally create regular HTML pages.
In this tutorial we assume that your server has activated support for PHP and that all files ending in .php are handled by PHP. On most servers, this is the default extension for PHP files, but ask your server administrator to be sure. If your server supports PHP, then you do not need to do anything. Just create your .php files, put them in your web directory and the server will automatically parse them for you. There is no need to compile anything nor do you need to install any extra tools. Think of these PHP-enabled files as simple HTML files with a whole new family of magical tags that let you do all sorts of things. Most web hosts offer PHP support, but if your host does not, consider reading the » PHP Links section for resources on finding PHP enabled web hosts.
Let us say you want to save precious bandwidth and develop locally. In this case, you will want to install a web server, such as » Apache, and of course » PHP. You will most likely want to install a database as well, such as » MySQL.
You can either install these individually or choose a simpler way. Our manual has installation instructions for PHP (assuming you already have some web server set up). In case you have problems with installing PHP yourself, we would suggest you ask your questions on our » installation mailing list. If you choose to go on the simpler route, then » locate a pre-configured package for your operating system, which automatically installs all of these with just a few mouse clicks. It is easy to setup a web server with PHP support on any operating system, including MacOSX, Linux and Windows. On Linux, you may find » rpmfind and » PBone helpful for locating RPMs. You may also want to visit » apt-get to find packages for Debian.
Create a file named hello.php and put it in your web server's root directory (DOCUMENT_ROOT) with the following content:
Example #1 Our first PHP script: hello.php
<html>
<head>
<title>PHP Test</title>
</head>
<body>
<?php echo '<p>Hello World</p>'; ?>
</body>
</html>
Use your browser to access the file with your web server's URL, ending with the /hello.php file reference. When developing locally this URL will be something like http://localhost/hello.php or http://127.0.0.1/hello.php but this depends on the web server's configuration. If everything is configured correctly, this file will be parsed by PHP and the following output will be sent to your browser:
<html> <head> <title>PHP Test</title> </head> <body> <p>Hello World</p> </body> </html>
This program is extremely simple and you really did not need to use PHP to create a page like this. All it does is display: Hello World using the PHP echo() statement. Note that the file does not need to be executable or special in any way. The server finds out that this file needs to be interpreted by PHP because you used the ".php" extension, which the server is configured to pass on to PHP. Think of this as a normal HTML file which happens to have a set of special tags available to you that do a lot of interesting things.
If you tried this example and it did not output anything, it prompted for download, or you see the whole file as text, chances are that the server you are on does not have PHP enabled, or is not configured properly. Ask your administrator to enable it for you using the Installation chapter of the manual. If you are developing locally, also read the installation chapter to make sure everything is configured properly. Make sure that you access the file via http with the server providing you the output. If you just call up the file from your file system, then it will not be parsed by PHP. If the problems persist anyway, do not hesitate to use one of the many » PHP support options.
The point of the example is to show the special PHP tag format. In this example we used <?php to indicate the start of a PHP tag. Then we put the PHP statement and left PHP mode by adding the closing tag, ?>. You may jump in and out of PHP mode in an HTML file like this anywhere you want. For more details, read the manual section on the basic PHP syntax.
Забележка: A Note on Line Feeds
Line feeds have little meaning in HTML, however it is still a good idea to make your HTML look nice and clean by putting line feeds in. A linefeed that follows immediately after a closing ?> will be removed by PHP. This can be extremely useful when you are putting in many blocks of PHP or include files containing PHP that aren't supposed to output anything. At the same time it can be a bit confusing. You can put a space after the closing ?> to force a space and a line feed to be output, or you can put an explicit line feed in the last echo/print from within your PHP block.
Забележка: A Note on Text Editors
There are many text editors and Integrated Development Environments (IDEs) that you can use to create, edit and manage PHP files. A partial list of these tools is maintained at » PHP Editors List. If you wish to recommend an editor, please visit the above page and ask the page maintainer to add the editor to the list. Having an editor with syntax highlighting can be helpful.
Забележка: A Note on Word Processors
Word processors such as StarOffice Writer, Microsoft Word and Abiword are not optimal for editing PHP files. If you wish to use one for this test script, you must ensure that you save the file as plain text or PHP will not be able to read and execute the script.
Забележка: A Note on Windows Notepad
If you are writing your PHP scripts using Windows Notepad, you will need to ensure that your files are saved with the .php extension. (Notepad adds a .txt extension to files automatically unless you take one of the following steps to prevent it.) When you save the file and are prompted to provide a name for the file, place the filename in quotes (i.e. "hello.php"). Alternatively, you can click on the 'Text Documents' drop-down menu in the 'Save' dialog box and change the setting to "All Files". You can then enter your filename without quotes.
Now that you have successfully created a working PHP script, it is time to create the most famous PHP script! Make a call to the phpinfo() function and you will see a lot of useful information about your system and setup such as available predefined variables, loaded PHP modules, and configuration settings. Take some time and review this important information.
Example #2 Get system information from PHP
<?php phpinfo(); ?>
Let us do something more useful now. We are going to check what sort of browser the visitor is using. For that, we check the user agent string the browser sends as part of the HTTP request. This information is stored in a variable. Variables always start with a dollar-sign in PHP. The variable we are interested in right now is $_SERVER['HTTP_USER_AGENT'].
Забележка: $_SERVER is a special reserved PHP variable that contains all web server information. It is known as a superglobal. See the related manual page on superglobals for more information. These special variables were introduced in PHP » 4.1.0. Before this time, we used the older $HTTP_*_VARS arrays instead, such as $HTTP_SERVER_VARS. Although deprecated, these older variables still exist. (See also the note on old code.)
To display this variable, you can simply do:
Example #1 Printing a variable (Array element)
<?php
echo $_SERVER['HTTP_USER_AGENT'];
?>
A sample output of this script may be:
There are many types of variables available in PHP. In the above example we printed an Array element. Arrays can be very useful.
$_SERVER is just one variable that PHP automatically makes available to you. A list can be seen in the Reserved Variables section of the manual or you can get a complete list of them by looking at the output of the phpinfo() function used in the example in the previous section.
You can put multiple PHP statements inside a PHP tag and create little blocks of code that do more than just a single echo. For example, if you want to check for Internet Explorer you can do this:
Example #2 Example using control structures and functions
<?php
if (strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE') !== FALSE) {
echo 'You are using Internet Explorer.<br />';
}
?>
A sample output of this script may be:
You are using Internet Explorer.<br />
Here we introduce a couple of new concepts. We have an if statement. If you are familiar with the basic syntax used by the C language, this should look logical to you. Otherwise, you should probably pick up an introductory PHP book and read the first couple of chapters, or read the Language Reference part of the manual.
The second concept we introduced was the strpos() function call. strpos() is a function built into PHP which searches a string for another string. In this case we are looking for 'MSIE' (so-called needle) inside $_SERVER['HTTP_USER_AGENT'] (so-called haystack). If the needle is found inside the haystack, the function returns the position of the needle relative to the start of the haystack. Otherwise, it returns FALSE. If it does not return FALSE, the if expression evaluates to TRUE and the code within its {braces} is executed. Otherwise, the code is not run. Feel free to create similar examples, with if, else, and other functions such as strtoupper() and strlen(). Each related manual page contains examples too. If you are unsure how to use functions, you will want to read both the manual page on how to read a function definition and the section about PHP functions.
We can take this a step further and show how you can jump in and out of PHP mode even in the middle of a PHP block:
Example #3 Mixing both HTML and PHP modes
<?php
if (strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE') !== FALSE) {
?>
<h3>strpos() must have returned non-false</h3>
<p>You are using Internet Explorer</p>
<?php
} else {
?>
<h3>strpos() must have returned false</h3>
<p>You are not using Internet Explorer</p>
<?php
}
?>
A sample output of this script may be:
<h3>strpos() must have returned non-false</h3> <p>You are using Internet Explorer</p>
Instead of using a PHP echo statement to output something, we jumped out of PHP mode and just sent straight HTML. The important and powerful point to note here is that the logical flow of the script remains intact. Only one of the HTML blocks will end up getting sent to the viewer depending on the result of strpos(). In other words, it depends on whether the string MSIE was found or not.
One of the most powerful features of PHP is the way it handles HTML forms. The basic concept that is important to understand is that any form element will automatically be available to your PHP scripts. Please read the manual section on Variables from external sources for more information and examples on using forms with PHP. Here is an example HTML form:
Example #1 A simple HTML form
<form action="action.php" method="post"> <p>Your name: <input type="text" name="name" /></p> <p>Your age: <input type="text" name="age" /></p> <p><input type="submit" /></p> </form>
There is nothing special about this form. It is a straight HTML form with no special tags of any kind. When the user fills in this form and hits the submit button, the action.php page is called. In this file you would write something like this:
Example #2 Printing data from our form
Hi <?php echo htmlspecialchars($_POST['name']); ?>.
You are <?php echo (int)$_POST['age']; ?> years old.
A sample output of this script may be:
Hi Joe. You are 22 years old.
Apart from the htmlspecialchars() and (int) parts, it should be obvious what this does. htmlspecialchars() makes sure any characters that are special in html are properly encoded so people can't inject HTML tags or Javascript into your page. For the age field, since we know it is a number, we can just convert it to an integer which will automatically get rid of any stray characters. You can also have PHP do this for you automatically by using the filter extension. The $_POST['name'] and $_POST['age'] variables are automatically set for you by PHP. Earlier we used the $_SERVER superglobal; above we just introduced the $_POST superglobal which contains all POST data. Notice how the method of our form is POST. If we used the method GET then our form information would live in the $_GET superglobal instead. You may also use the $_REQUEST superglobal, if you do not care about the source of your request data. It contains the merged information of GET, POST and COOKIE data. Also see the import_request_variables() function.
You can also deal with XForms input in PHP, although you will find yourself comfortable with the well supported HTML forms for quite some time. While working with XForms is not for beginners, you might be interested in them. We also have a short introduction to handling data received from XForms in our features section.
Now that PHP has grown to be a popular scripting language, there are a lot of public repositories and libraries containing code you can reuse. The PHP developers have largely tried to preserve backwards compatibility, so a script written for an older version will run (ideally) without changes in a newer version of PHP. In practice, some changes will usually be needed.
Two of the most important recent changes that affect old code are:
For more details on these changes, see the section on predefined variables and links therein.
With your new knowledge you should be able to understand most of the manual and also the various example scripts available in the example archives. You can also find other examples on the php.net websites in the links section: » http://www.php.net/links.php.
To view various slide presentations that show more of what PHP can do, see the PHP Conference Material Site: » http://talks.php.net/
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:
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.
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 web server. 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:
The initial PHP setup and configuration process is controlled by the use of the command line 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.
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.
Example #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:
Example #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
Забележка: 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.
Example #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 » web page on DSO support.
Забележка: 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.
Забележка: 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.
This section contains notes and hints specific to Apache 2.0 installs of PHP on Unix systems.
Не препоръчваме използването на нишков MPM с Apache2 за масова употреба. Вместо това, използвайте MPM или Apache1. За разяснение относно този проблем, вижте FAQ информацията по въпроса за Apache2 с нишков 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:
- PHP 4.3.0 or later available at » http://www.php.net/downloads.php.
- the latest stable development version. Get the source code » http://snaps.php.net/php5-latest.tar.gz or download binaries for Windows » http://snaps.php.net/win32/php5-win32-latest.zip.
- a prerelease version downloadable from » http://qa.php.net/.
- you have always the option to obtain PHP through » anonymous SVN.
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.
Example #1 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 .php files as PHP. Instead of only using the Apache AddType
directive, we want to avoid potentially dangerous uploads and created
files such as exploit.php.jpg from being executed as PHP. Using this
example, you could have any extension(s) parse as PHP by simply adding
them. We'll add .phtml to demonstrate.
<FilesMatch \.php$>
SetHandler application/x-httpd-php
</FilesMatch>
Or, if we wanted to allow .php, .php2, .php3, .php4, .php5, .php6, and
.phtml files to be executed as PHP, but nothing else, we'd use this:
<FilesMatch "\.ph(p[2-6]?|tml)$">
SetHandler application/x-httpd-php
</FilesMatch>
And to allow .phps files to be executed as PHP source files, add this:
<FilesMatch "\.phps$">
SetHandler application/x-httpd-php-source
</FilesMatch>
16. Use your normal procedure for starting the Apache server, e.g.:
/usr/local/apache2/bin/apachectl start
- OR -
service httpd restart
Following the steps above you will have a running Apache2 web server with support for PHP as a SAPI module. Of course there are many more configuration options available Apache and PHP. For more information type ./configure --help in the corresponding source tree. If you wish to build a multithreaded version of Apache2, 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. Before doing so, please beware the consequences and have at least a fair understand of what the implications. For more information, read the Apache documentation regarding » MPM-Modules.
Забележка: If you want to use content negotiation, read the Apache MultiViews FAQ.
Забележка: 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.
This section contains notes and hints specific to Lighttpd 1.4 installs of PHP on Unix systems.
Please use the » Lighttpd trac to learn how to install Lighttpd properly before continuing.
Fastcgi is the preferred SAPI to connect PHP and Lighttpd. Fastcgi is automagically enabled in php-cgi in PHP 5.3, but for older versions configure PHP with --enable-fastcgi. To confirm that PHP has fastcgi enabled, php -v should contain PHP 5.2.5 (cgi-fcgi) Before PHP 5.2.3, fastcgi was enabled on the php binary (there was no php-cgi).
To configure Lighttpd to connect to php and spawn fastcgi processes, edit lighttpd.conf. Sockets are preferred to connect to fastcgi processes on the local system.
Example #1 Partial lighttpd.conf
server.modules += ( "mod_fastcgi" )
fastcgi.server = ( ".php" =>
((
"socket" => "/tmp/php.socket",
"bin-path" => "/usr/local/bin/php-cgi",
"bin-environment" => (
"PHP_FCGI_CHILDREN" => "16",
"PHP_FCGI_MAX_REQUESTS" => "10000"
),
"min-procs" => 1,
"max-procs" => 1,
"idle-timeout" => 20
))
)
The bin-path directive allows lighttpd to spawn fastcgi processes dynamically. PHP will spawn children according to the PHP_FCGI_CHILDREN environment variable. The "bin-environment" directive sets the environment for the spawned processes. PHP will kill a child process after the number of requests specified by PHP_FCGI_MAX_REQUESTS is reached. The directives "min-procs" and "max-procs" should generally be avoided with PHP. PHP manages its own children and opcode caches like APC will only share among children managed by PHP. If "min-procs" is set to something greater than 1, the total number of php responders will be multiplied PHP_FCGI_CHILDREN (2 min-procs * 16 children gives 32 responders).
Lighttpd provides a program called spawn-fcgi to ease the process of spawning fastcgi processes easier.
It is possible to spawn processes without spawn-fcgi, though a bit of heavy-lifting is required. Setting the PHP_FCGI_CHILDREN environment var controls how many children PHP will spawn to handle incoming requests. Setting PHP_FCGI_MAX_REQUESTS will determine how long (in requests) each child will live. Here's a simple bash script to help spawn php responders.
Example #2 Spawning FastCGI Responders
#!/bin/sh
# Location of the php-cgi binary
PHP=/usr/local/bin/php-cgi
# PID File location
PHP_PID=/tmp/php.pid
# Binding to an address
#FCGI_BIND_ADDRESS=10.0.1.1:10000
# Binding to a domain socket
FCGI_BIND_ADDRESS=/tmp/php.sock
PHP_FCGI_CHILDREN=16
PHP_FCGI_MAX_REQUESTS=10000
env -i PHP_FCGI_CHILDREN=$PHP_FCGI_CHILDREN \
PHP_FCGI_MAX_REQUESTS=$PHP_FCGI_MAX_REQUESTS \
$PHP -b $FCGI_BIND_ADDRESS &
echo $! > "$PHP_PID"
Fastcgi instances can be spawned on multiple remote machines in order to scale applications.
Example #3 Connecting to remote php-fastcgi instances
fastcgi.server = ( ".php" =>
(( "host" => "10.0.0.2", "port" => 1030 ),
( "host" => "10.0.0.3", "port" => 1030 ))
)
PHP can be built as a Pike module for the » Caudium webserver. Follow the simple instructions below to install PHP for Caudium.
Example #1 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
PHP4.so. Also make sure that
caudium/server/lib/[pike-version]/PHP4.so
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.
Забележка: 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.
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.
Забележка: Support for fhttpd is no longer available as of PHP 4.3.0.
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 web servers 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 web servers, 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.
Install the following packages from » http://www.sunfreeware.com/ or another download site:
export PATH
.
gunzip php-x.x.x.tar.gz
(if you have a .gz dist,
otherwise go to 4).
tar xvf php-x.x.x.tar
cd ../php-x.x.x
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
After performing the base install and reading the appropriate readme file, you may need to perform some additional configuration steps.
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 web server. 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/.
Add the following line to mime.types (you can do that by the administration server):
type=magnus-internal/x-httpd-php exts=php
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 web server config directory.
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"
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.
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>
To use PHP Authentication on a single directory, add the following:
<Object ppath="d:\path\to\authenticated\dir\*"> AuthTrans fn=php4_auth_trans </Object>
Забележка: The stacksize that PHP uses depends on the configuration of the web server. If you get crashes with very large PHP scripts, it is recommended to raise it with the Admin Server (in the section "MAGNUS EDITOR").
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 web server 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 way with getenv() or a similar way (register globals to environment, $_ENV). You would only get the environment of the running web server without any valid CGI variables!
Забележка: Why are there (invalid) CGI variables in the environment?
Answer: This is because you started the web server process from the admin server which runs the startup script of the web server, you wanted to start, as a CGI script (a CGI script inside of the admin server!). This is why the environment of the started web server has some CGI environment variables in it. You can test this by starting the web server 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
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'].
The NSAPI module now supports the nsapi_virtual() function (alias: virtual()) to make subrequests on the web server and insert the result in the web page. 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.
Забележка: But be warned: Support for nsapi_virtual() is EXPERIMENTAL!!!
The default is to build PHP as a CGI program. This creates a command line 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.
Сървър, инсталиран в режим CGI, е открит за множество възможни уязвимости. Моля, прочетете раздела за сигурност на 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.
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.
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'.
This section contains notes and hints specific to installing PHP on HP-UX systems.
There are two main options for installing PHP on HP-UX systems. Either compile it, or install a pre-compiled binary.
Official pre-compiled packages are located here: » http://software.hp.com/
Until this manual section is rewritten, the documentation about compiling PHP (and related extensions) on HP-UX systems has been removed. For now, consider reading the following external resource: » Building Apache and PHP on HP-UX 11.11
This section contains notes and hints specific to installing PHP on » OpenBSD 3.6.
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.
Example #1 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.
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.
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).
This section contains notes and hints specific to installing PHP on Solaris systems.
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:
In addition, you will need to install (and possibly compile) any additional software specific to your configuration, such as Oracle or MySQL.
You can simplify the Solaris install process by using pkgadd to install most of your needed components.
This section contains notes and hints specific to installing PHP on » Debian GNU/Linux.
While the instructions for building PHP on Unix apply to Debian as well, this manual page contains specific information for other options, such as using either the apt-get or aptitude commands. This manual page uses these two commands interchangeably.
First, note that other related packages may be desired like libapache2-mod-php5 to integrate with Apache 2, and php-pear for PEAR.
Second, before installing a package, it's wise to ensure the package list is up to date. Typically, this is done by running the command apt-get update.
Example #1 Debian Install Example with Apache 2
# apt-get install php5-common libapache2-mod-php5 php5-cli
APT will automatically install the PHP 5 module for Apache 2 and all of its dependencies, and then activate it. Apache should be restarted in order for the changes take place. For example:
Example #2 Stopping and starting Apache once PHP is installed
# /etc/init.d/apache2 stop # /etc/init.d/apache2 start
In the last section, PHP was installed with only core modules. It's very likely that additional modules will be desired, such as MySQL, cURL, GD, etc. These may also be installed via the apt-get command.
Example #3 Methods for listing additional PHP 5 packages
# apt-cache search php5 # aptitude search php5 # aptitude search php5 |grep -i mysql
The examples will show a lot of packages including several PHP specific ones like php5-cgi, php5-cli and php5-dev. Determine which are needed and install them like any other with either apt-get or aptitude. And because Debian performs dependency checks, it'll prompt for those so for example to install MySQL and cURL:
Example #4 Install PHP with MySQL, cURL
# apt-get install php5-mysql php5-curl
APT will automatically add the appropriate lines to the different php.ini related files like /etc/php5/apache2/php.ini, /etc/php5/conf.d/pdo.ini, etc. and depending on the extension will add entries similar to extension=foo.so. However, restarting the web server (like Apache) is required before these changes take affect.
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.
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.
The following resources offer easy to install packages and precompiled binaries for PHP on Mac OS:
PHP has come standard with Macs since OS X version 10.0.0. Enabling PHP with the default web server requires uncommenting a few lines in the Apache configuration file httpd.conf whereas the CGI and/or CLI are enabled by default (easily accessible via the Terminal program).
Enabling PHP using the instructions below is meant for quickly setting up a local development environment. It's highly recommended to always upgrade PHP to the newest version. Like most live software, newer versions are created to fix bugs and add features and PHP being is no different. See the appropriate MAC OS X installation documentation for further details. The following instructions are geared towards a beginner with details provided for getting a default setup to work. All users are encouraged to compile, or install a new packaged version.
The standard installation type is using mod_php, and enabling the bundled mod_php on Mac OS X for the Apache web server (the default web server, that is accessible via System Preferences) involves the following steps:
Забележка: One way to open this is by using a Unix based text editor in the Terminal, for example nano, and because the file is owned by root we'll use the sudo command to open it (as root) so for example type the following into the Terminal Application (after, it will prompt for a password): sudo nano /private/etc/apache2/httpd.conf Noteworthy nano commands: ^w (search), ^o (save), and ^x (exit) where ^ represents the Ctrl key.
Забележка: Versions of Mac OS X prior to 10.5 were bundled with older versions of PHP and Apache. As such, the Apache configuration file on legacy machines may be /etc/httpd/httpd.conf.
With a text editor, uncomment the lines (by removing the #) that look similar to the following (these two lines are often not together, locate them both in the file):
# LoadModule php5_module libexec/httpd/libphp5.so # AddModule mod_php5.c
Be sure the desired extensions will parse as PHP (examples: .php .html and .inc)
Due to the following statement already existing in httpd.conf (as of Mac Panther), once PHP is enabled the .php files will automatically parse as PHP.
<IfModule mod_php5.c>
# If php is turned on, we respect .php and .phps files.
AddType application/x-httpd-php .php
AddType application/x-httpd-php-source .phps
# Since most users will want index.php to work we
# also automatically enable index.php
<IfModule mod_dir.c>
DirectoryIndex index.html index.php
</IfModule>
</IfModule>
Забележка: Before OS X 10.5 (Leopard), PHP 4 was bundled instead of PHP 5 in which case the above instructions will differ slightly by changing 5's to 4's.
The phpinfo() function will display information about PHP. Consider creating a file in the DocumentRoot with the following PHP code:
<?php phpinfo(); ?>
The CLI (or CGI in older versions) is appropriately named php and likely exists as /usr/bin/php. Open up the terminal, read the command line section of the PHP manual, and execute php -v to check the PHP version of this PHP binary. A call to phpinfo() will also reveal this information.
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
If you want the compiler to do some optimization, you may also want to add this line:
setenv OPTIM=-O2
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.
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.
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
.
The following instructions will help you install a PHP module for the Apache web server included in MacOS X using the MacOS GUI. This version includes MySQL, PostgreSQL, and iODBC database support, cURL, GD, PDFLib, LDAP, and more. These instructions are graciously provided by » Marc Liyanage.
Be sure you know what you're doing before advancing beyond this point! You can cause irreparable harm to your Apache installation otherwise.
Забележка: These instructions will only work with the original Apache web server as shipped by Apple. If you re-built or upgraded your Apache, you will have to build your own PHP module.
To install:
http://www2.entropy.ch/download/entropy-php-5.2.4-1.tar.gz
wget
http://www2.entropy.ch/download/entropy-php-5.2.4-1-apache2.tar.gz
That's all! PHP should now be up and running. You can test it by dropping a file named test.php into your Sites folder in your home directory. 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.
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.
Забележка: Windows 98/ME/NT4 is no longer supported as of PHP 5.3.0.
Забележка: 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.
There are several all-in-one installers over the Internet, but none of those are endorsed by PHP.net, as we believe that using one of the official windows packages from » http://www.php.net/downloads.php is the best choice to have your system secure and optimized.
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.
Забележка: 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.
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.
The Windows PHP installer for later versions of PHP is built using MSI technology using the Wix Toolkit (» http://wix.sourceforge.net/). It will install and configure PHP and all the built-in and PECL extensions, as well as configure many of the popular web servers such as IIS, Apache, and Xitami.
First, install your selected HTTP (web) server on your system, and make sure that it works. Then proceed with one of the following install types.
Run the MSI installer and follow the instructions provided by the installation wizard. You will be prompted to select the Web Server you wish to configure first, along with any configuration details needed.
You will then be prompted to select which features and extensions you wish to install and enable. By selecting "Will be installed on local hard drive" in the drop-down menu for each item you can trigger whether to install the feature or not. By selecting "Entire feature will be installed on local hard drive", you will be able to install all sub-features of the included feature ( for example by selecting this options for the feature "PDO" you will install all PDO Drivers ).
It is not recommended to install all extensions by default, since many other them require dependencies from outside PHP in order to function properly. Instead, use the Installation Repair Mode that can be triggered thru the 'Add/Remove Programs' control panel to enable or disable extensions and features after installation.
The installer then sets up PHP to be used in Windows and the php.ini file, and configures certain web servers to use PHP. The installer will currently configure IIS, Apache, Xitami, and Sambar Server; if you are using a different web server you'll need to configure it manually.
The installer also supports a silent mode, which is helpful for Systems Administrators to deploy PHP easily. To use silent mode:
msiexec.exe /i php-VERSION-win32-install.msi /q
You can control the install directory by passing it as a parameter to the install. For example, to install to e:\php:
msiexec.exe /i php-VERSION-win32-install.msi /q INSTALLDIR=e:\php
You can also specify what features to install. For example, to install the mysqli extension and the CGI executable:
msiexec.exe /i php-VERSION-win32-install.msi /q ADDLOCAL=cgi,ext_php_mysqli
The current list of Features to install is as follows:
MainExecutable - php.exe executable ( no longer available as of PHP 5.2.10/5.3.0; it is now included by default ) ScriptExecutable - php-win.exe executable ext_php_* - the various extensions ( for example: ext_php_mysql for MySQL ) apache13 - Apache 1.3 module apache20 - Apache 2.0 module apache22 - Apache 2,2 module apacheCGI - Apache CGI executable iis4ISAPI - IIS ISAPI module iis4CGI - IIS CGI executable iis4FastCGI - IIS CGI executable NSAPI - Sun/iPlanet/Netscape server module netserve - NetServe Web Server CGI executable Xitami - Xitami CGI executable Sambar - Sambar Server ISAPI module CGI - php-cgi.exe executable PEAR - PEAR installer Manual - PHP Manual in CHM Format
For more information on installing MSI installers from the command line, visit » http://msdn.microsoft.com/en-us/library/aa367988.aspx
To upgrade, run the installer either graphically or from the command line as normal. The installer will read your current install options, remove your old installation, and reinstall PHP with the same options as before. It is recommended that you use this method of keeping PHP updated instead of manually replacing the files in the installation directory.
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:
Example #1 PHP 4 package structure
c:\php | +--cli | | | |-php.exe -- CLI executable - ONLY for command line 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:
Example #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.
Забележка: 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/php5apache2_2.dll - Apache 2.2.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.
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 The configuration file 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.
Забележка: 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
PHP is now setup on your system. The next step is to choose a web server, and enable it to run PHP. Choose a web server from the table of contents.
In addition to running PHP via a web server, PHP can run from the command line just like a .BAT script. See Command Line PHP on Microsoft Windows for further details.
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 файла на това разширение може да бъде изтеглен или от страницата за » изтегляне на PHP или от » http://pecl4win.php.net/
Забележка: 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.
Забележка: 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.
Забележка: 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.
This section contains notes and hints specific to IIS (Microsoft Internet Information Server).
Сървър, инсталиран в режим CGI, е открит за множество възможни уязвимости. Моля, прочетете раздела за сигурност на CGI, за да научите как да се защитавате от подобни атаки.
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:
To use the ISAPI module, do the following:
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.
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.
Забележка: 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.
Забележка: Запомнете, че при добавяне на стойности за пътя в конфигурацията на Apache при Windows, всички обратно наклонени черти, като c:\directory\file.ext, трява да бъдат преобразувани до наклонени черти: c:/directory/file.ext. Наклонена черта в края също може да бъде необходима за директории.
You should add the following lines to your Apache httpd.conf file:
Example #1 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
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:
Example #2 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.
Сървър, инсталиран в режим CGI, е открит за множество възможни уязвимости. Моля, прочетете раздела за сигурност на 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'); ?>.
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.
Забележка: You should read the manual installation steps first!
Забележка: Apache 2.2.x Support
Users of Apache 2.2.x may use the documentation below except the appropriate DLL file is named php5apache2_2.dll and it only exists as of PHP 5.2.0. See also » http://snaps.php.net/
Не препоръчваме използването на нишков MPM с Apache2 за масова употреба. Вместо това, използвайте MPM или Apache1. За разяснение относно този проблем, вижте FAQ информацията по въпроса за Apache2 с нишков 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:
- PHP 4.3.0 or later available at » http://www.php.net/downloads.php.
- the latest stable development version. Get the source code » http://snaps.php.net/php5-latest.tar.gz or download binaries for Windows » http://snaps.php.net/win32/php5-win32-latest.zip.
- a prerelease version downloadable from » http://qa.php.net/.
- you have always the option to obtain PHP through » anonymous SVN.
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.
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.
Забележка: Запомнете, че при добавяне на стойности за пътя в конфигурацията на Apache при Windows, всички обратно наклонени черти, като c:\directory\file.ext, трява да бъдат преобразувани до наклонени черти: c:/directory/file.ext. Наклонена черта в края също може да бъде необходима за директории.
You need to insert these three lines to your Apache httpd.conf configuration file to set up the CGI binary:
Example #1 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"
Сървър, инсталиран в режим CGI, е открит за множество възможни уязвимости. Моля, прочетете раздела за сигурност на CGI, за да научите как да се защитавате от подобни атаки.
You need to insert these two lines to your Apache httpd.conf configuration file to set up the PHP module for Apache 2.0:
Example #2 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"
Забележка: 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.
Забележка: If you want to use content negotiation, read related FAQ.
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.
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 web servers read the note about subrequests.
To install PHP as a CGI handler, do the following:
Make a file association from the command line. Type the following two lines:
assoc .php=PHPScript ftype PHPScript=c:\php\php.exe %1 %*
More details about setting up PHP as a CGI executable can be found here: » http://benoit.noss.free.fr/php/install-php.html
To install PHP with NSAPI, do the following:
Make a file association from the command line. Type the following two lines:
assoc .php=PHPScript ftype PHPScript=c:\php\php.exe %1 %*
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 web server configuration 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.
Забележка: More details about setting up PHP as an NSAPI filter can be found here: » http://benoit.noss.free.fr/php/install-php4.html
Забележка: The stacksize that PHP uses depends on the configuration of the web server. If you get crashes with very large PHP scripts, it is recommended to raise it with the Admin Server (in the section "MAGNUS EDITOR").
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 web server 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 way with getenv() or a similar way (register globals to environment, $_ENV). You would only get the environment of the running web server without any valid CGI variables!
Забележка: Why are there (invalid) CGI variables in the environment?
Answer: This is because you started the web server process from the admin server which runs the startup script of the web server, you wanted to start, as a CGI script (a CGI script inside of the admin server!). This is why the environment of the started web server has some CGI environment variables in it. You can test this by starting the web server 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
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'].
The NSAPI module now supports the nsapi_virtual() function (alias: virtual()) to make subrequests on the web server and insert the result in the web page. 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.
Забележка: But be warned: Support for nsapi_virtual() is EXPERIMENTAL!!!
This section contains notes and hints specific to » OmniHTTPd on Windows.
Забележка: You should read the manual installation steps first!
Сървър, инсталиран в режим CGI, е открит за множество възможни уязвимости. Моля, прочетете раздела за сигурност на 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.
Install OmniHTTPd server.
Right click on the blue OmniHTTPd icon in the system tray and select Properties
Click on Web Server Global Settings
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.
On the Mime tab, enter: virtual = wwwserver/stdcgi | actual = .php, and use the Add button.
Click OK
Repeat steps 2 - 6 for each extension you want to associate with PHP.
Забележка: 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.
This section contains notes and hints specific to the » Sambar Server for Windows.
Забележка: 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]:
Example #1 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.
Забележка: If you intend to use PHP to communicate with resources which are held on a different computer on your network, then you will need to alter the account used by the Sambar Server Service. The default account used for the Sambar Server Service is LocalSystem which will not have access to remote resources. The account can be amended by using the Services option from within the Windows Control Panel Administation Tools.
This section contains notes and hints specific to » Xitami on Windows.
Забележка: 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.
Сървър, инсталиран в режим CGI, е открит за множество възможни уязвимости. Моля, прочетете раздела за сигурност на CGI, за да научите как да се защитавате от подобни атаки.
Make sure the web server 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.
This chapter teaches how to compile PHP from sources on windows, using Microsoft's tools. To compile PHP with cygwin, please refer to Installation on Unix systems.
This chapter is outdated therefore it's temporarily been removed from the manual. For now, consider the following:
After installing PHP and a web server 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 и Zlib
In PHP 5 (updated PHP 5.0.4), the following changes exist. Built in: DOM, LibXML, Iconv, SimpleXML, SPL и 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.
Example #1 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.
Забележка: If you are running a server module version of PHP remember to restart your web server to reflect your changes to php.ini.
The following table describes some of the extensions available and required additional dlls.
| Extension | Description | Notes |
|---|---|---|
| php_bz2.dll | bzip2 compression functions | None |
| php_calendar.dll | Calendar conversion functions | Built in since PHP 4.0.3 |
| php_crack.dll | Crack functions | None |
| php_ctype.dll | ctype family functions | Built in since PHP 4.3.0 |
| php_curl.dll | CURL, Client URL library functions | Requires: libeay32.dll, ssleay32.dll (bundled) |
| php_dba.dll | DBA: DataBase (dbm-style) Abstraction layer functions | None |
| php_dbase.dll | dBase functions | None |
| php_dbx.dll | dbx functions | |
| php_domxml.dll | DOM XML functions | PHP <= 4.2.0 requires: libxml2.dll (bundled) PHP >= 4.3.0 requires: iconv.dll (bundled) |
| php_dotnet.dll | .NET functions | PHP <= 4.1.1 |
| php_exif.dll | EXIF functions | php_mbstring.dll. And, php_exif.dll must be loaded after php_mbstring.dll in php.ini. |
| php_fbsql.dll | FrontBase functions | PHP <= 4.2.0 |
| php_fdf.dll | FDF: Forms Data Format functions. | Requires: fdftk.dll (bundled) |
| php_filepro.dll | filePro functions | Read-only access |
| php_ftp.dll | FTP functions | Built-in since PHP 4.0.3 |
| php_gd.dll | GD 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.dll | GD library image functions | GD2 |
| php_gettext.dll | Gettext functions | PHP <= 4.2.0 requires gnu_gettext.dll (bundled), PHP >= 4.2.3 requires libintl-1.dll, iconv.dll (bundled). |
| php_hyperwave.dll | HyperWave functions | None |
| php_iconv.dll | ICONV characterset conversion | Requires: iconv-1.3.dll (bundled), PHP >=4.2.1 iconv.dll |
| php_ifx.dll | Informix functions | Requires: Informix libraries |
| php_iisfunc.dll | IIS management functions | None |
| php_imap.dll | IMAP POP3 and NNTP functions | None |
| php_ingres.dll | Ingres functions | Requires: Ingres libraries |
| php_interbase.dll | InterBase functions | Requires: gds32.dll (bundled) |
| php_java.dll | Java functions | PHP <= 4.0.6 requires: jvm.dll (bundled) |
| php_ldap.dll | LDAP functions | PHP <= 4.2.0 requires libsasl.dll (bundled), PHP >= 4.3.0 requires libeay32.dll, ssleay32.dll (bundled) |
| php_mbstring.dll | Multi-Byte String functions | None |
| php_mcrypt.dll | Mcrypt Encryption functions | Requires: libmcrypt.dll |
| php_mhash.dll | Mhash functions | PHP >= 4.3.0 requires: libmhash.dll (bundled) |
| php_mime_magic.dll | Mimetype functions | Requires: magic.mime (bundled) |
| php_ming.dll | Ming functions for Flash | None |
| php_msql.dll | mSQL functions | Requires: msql.dll (bundled) |
| php_mssql.dll | MSSQL functions | Requires: ntwdblib.dll (bundled) |
| php_mysql.dll | MySQL functions | PHP >= 5.0.0, requires libmysql.dll (bundled) |
| php_mysqli.dll | MySQLi functions | PHP >= 5.0.0, requires libmysql.dll (libmysqli.dll in PHP <= 5.0.2) (bundled) |
| php_oci8.dll | Oracle 8 functions | Requires: Oracle 8.1+ client libraries |
| php_openssl.dll | OpenSSL functions | Requires: libeay32.dll (bundled) |
| php_overload.dll | Object overloading functions | Built in since PHP 4.3.0 |
| php_pdf.dll | PDF functions | None |
| php_pgsql.dll | PostgreSQL functions | None |
| php_printer.dll | Printer functions | None |
| php_shmop.dll | Shared Memory functions | None |
| php_snmp.dll | SNMP get and walk functions | NT only! |
| php_soap.dll | SOAP functions | PHP >= 5.0.0 |
| php_sockets.dll | Socket functions | None |
| php_sybase_ct.dll | Sybase functions | Requires: Sybase client libraries |
| php_tidy.dll | Tidy functions | PHP >= 5.0.0 |
| php_tokenizer.dll | Tokenizer functions | Built in since PHP 4.3.0 |
| php_w32api.dll | W32api functions | None |
| php_xmlrpc.dll | XML-RPC functions | PHP >= 4.2.1 requires: iconv.dll (bundled) |
| php_xslt.dll | XSLT 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.dll | YAZ functions | Requires: yaz.dll (bundled) |
| php_zip.dll | Zip File functions | Read only access |
| php_zlib.dll | ZLib compression functions | Built in since PHP 4.3.0 |
This section contains notes and hints specific to getting PHP running from the command line for Windows.
Забележка: You should read the manual installation steps first!
Getting PHP to run from the command line can be performed without making any changes to Windows.
C:\PHP5\php.exe "C:\PHP Scripts\script.php" -- -arg1 -arg2 -arg3
But there are some easy steps that can be followed to make this simpler. Some of these steps should already have been taken, but are repeated here to be able to provide a complete step-by-step sequence.
Add the location of the PHP executable (php.exe, php-win.exe or php-cli.exe depending upon your PHP version and display preferences) to the PATH environment variable. Read more about how to add your PHP directory to PATH in the corresponding FAQ entry.
Add the .PHP extension to the PATHEXT environment variable. This can be done at the same time as amending the PATH environment variable. Follow the same steps as described in the FAQ but amend the PATHEXT environment variable rather than the PATH environment variable.
Забележка: The position in which you place the .PHP will determine which script or program is executed when there are matching filenames. For example, placing .PHP before .BAT will cause your script to run, rather than the batch file, if there is a batch file with the same name.
Associate the .PHP extension with a file type. This is done by typing the running the following command:
assoc .php=phpfile
Associate the phpfile file type with the appropriate PHP executable. This is done by typing the running the following command:
ftype phpfile=php.exe "%1" -- %*
Following these steps will allow PHP scripts to be run from any directory without the need to type the PHP executable or the .PHP extension and all parameters will be supplied to the script for processing.
The example below details some of the registry changes that can be made manually.
Example #1 Registry changes
Windows Registry Editor Version 5.00 [HKEY_LOCAL_MACHINE\SOFTWARE\Classes\.php] @="phpfile" "Content Type"="application/php" [HKEY_LOCAL_MACHINE\SOFTWARE\Classes\phpfile] @="PHP Script" "EditFlags"=dword:00000000 "BrowserFlags"=dword:00000008 "AlwaysShowExt"="" [HKEY_LOCAL_MACHINE\SOFTWARE\Classes\phpfile\DefaultIcon] @="C:\\PHP5\\php-win.exe,0" [HKEY_LOCAL_MACHINE\SOFTWARE\Classes\phpfile\shell] @="Run" [HKEY_LOCAL_MACHINE\SOFTWARE\Classes\phpfile\shell\Open] @="&Open" [HKEY_LOCAL_MACHINE\SOFTWARE\Classes\phpfile\shell\Open\command] @="\"C:\\PHP5\\PHP.EXE\" \"%1\" -- %*"
With these changes the same command can be written as:
"C:\PHP Scripts\script" -arg1 -arg2 -arg3
script -arg1 -arg2 -arg3
Забележка: There is a small problem if you intend to use this techique and use your PHP scripts as commandline filters, like the example below:
ordir | "C:\PHP Scripts\script" -arg1 -arg2 -arg3You may find that the script simply hangs and nothing is output. To get this operational, you need to make another registry change.dir | script -arg1 -arg2 -arg3Further information regarding this issue can be found in this » Microsoft Knowledgebase Article : 321788.Windows Registry Editor Version 5.00 [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\policies\Explorer] "InheritConsoleHandles"=dword:00000001
» 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. The information in the PEAR manual for the pear command also applies to the pecl 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 SVN Instructions for details on the required tools, and required versions.
There are several options for downloading PECL extensions, such as:
On Windows, you have two ways to load a PHP extension: either compile it into PHP, or load the DLL. Loading a pre-compiled extension is the easiest and preferred way.
To load an extension, you need to have it available as a ".dll" file on your system. All the extensions are automatically and periodically compiled by the PHP Group (see next section for the download).
To compile an extension into PHP, please refer to building from source documentation.
To compile a standalone extension (aka a DLL file), please refer to building from source documentation. If the DLL file is available neither with your PHP distribution nor in PECL, you may have to compile it before you can start using the extension.
PHP extensions are usually called "php_*.dll" (where the star represents the name of the extension) and they are located under the "PHP\ext" ("PHP\extensions" in PHP4) folder.
PHP ships with the extensions most useful to the majority of developers. They are called "core" extensions.
However, if you need functionality not provided by any core extension, you may still be able to find one in PECL. The PHP Extension Community Library (PECL) is a repository for PHP Extensions, providing a directory of all known extensions and hosting facilities for downloading and development of PHP extensions.
If you have developed an extension for your own uses, you might want to think about hosting it on PECL so that others with the same needs can benefit from your time. A nice side effect is that you give them a good chance to give you feedback, (hopefully) thanks, bug reports and even fixes/patches. Before you submit your extension for hosting on PECL, please read http://pecl.php.net/package-new.php.
Many times, you will find several versions of each DLL:
You should keep in mind that your extension settings should match all the settings of the PHP executable you are using. The following PHP script will tell you all about your PHP settings:
Example #1 phpinfo() call
<?php
phpinfo();
?>
Or from the command line, run:
drive:\\path\to\php\executable\php.exe -i
The most common way to load a PHP extension is to include it in your php.ini configuration file. Please note that many extensions are already present in your php.ini and that you only need to remove the semicolon to activate them.
;extension=php_extname.dll
extension=php_extname.dll
However, some web servers are confusing because they do not use the php.ini located alongside your PHP executable. To find out where your actual php.ini resides, look for its path in phpinfo():
Configuration File (php.ini) Path C:\WINDOWS
Loaded Configuration File C:\Program Files\PHP\5.2\php.ini
After activating an extension, save php.ini, restart the web server and check phpinfo() again. The new extension should now have its own section.
If the extension does not appear in phpinfo(), you should check your logs to learn where the problem comes from.
If you are using PHP from the command line (CLI), the extension loading error can be read directly on screen.
If you are using PHP with a web server, the location and format of the logs vary depending on your software. Please read your web server documentation to locate the logs, as it does not have anything to do with PHP itself.
Common problems are the location of the DLL, the value of the " extension_dir" setting inside php.ini and compile-time setting mismatches.
If the problem lies in a compile-time setting mismatch, you probably didn't download the right DLL. Try downloading again the extension with the right settings. Again, phpinfo() can be of great help.
PECL makes it easy to create shared PHP extensions. Using the » pecl command, do the following:
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 pecl 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:
You may also install a specific version using this variant:
Забележка: After enabling the extension in php.ini, restarting the web service is required for the changes to be picked up.
Sometimes, using the pecl 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 PECL compatible package, such as unreleased extensions from SVN. 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 --helpto display additional usage information.
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 $ pecl download extname $ gzip -d < extname.tgz | tar -xvf - $ mv extname-x.x.x extname
This will result in the following directory:
From here, force PHP to rebuild the configure script, and then build PHP as normal:
Забележка: 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:
Some problems are more common than others. The most common ones are listed in the PHP FAQ, part of this manual.
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, защитен режим, etc.), and preferably enough code to make others able to reproduce and test your problem.
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!
The configuration file (php.ini) 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)
The PHPRC environment variable. Before PHP 5.2.0 this was checked after the registry key mentioned below.
As of PHP 5.2.0, the location of the php.ini file can be set for different versions of PHP. The following registry keys are examined in order: [HKEY_LOCAL_MACHINE\SOFTWARE\PHP\x.y.z], [HKEY_LOCAL_MACHINE\SOFTWARE\PHP\x.y] and [HKEY_LOCAL_MACHINE\SOFTWARE\PHP\x], where x, y and z mean the PHP major, minor and release versions. If there is a value for IniFilePath in these keys, then the first one found will be used as the location of the php.ini (Windows only).
[HKEY_LOCAL_MACHINE\SOFTWARE\PHP], value of IniFilePath (Windows only).
Current working directory (except 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().
Забележка: 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 SVN helpful too.
Example #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".
Since PHP 5.3.0, PHP includes support for .htaccess-style INI files on a per-directory basis. These files are processed only by the CGI/FastCGI SAPI. This functionality obsoletes the PECL htscanner extension. If you are using Apache, use .htaccess files for the same effect.
In addition to the main php.ini file, PHP scans for INI files in each directory, starting with the directory of the requested PHP file, and working its way up to the current document root (as set in $_SERVER['DOCUMENT_ROOT']). Only INI settings with the modes PHP_INI_PERDIR and PHP_INI_USER will be recognized in .user.ini-style INI files.
Two new INI directives, user_ini.filename and user_ini.cache_ttl control the use of user INI files.
user_ini.filename sets the name of the file PHP looks for in each directory; if set to an empty string, PHP doesn't scan at all. The default is .user.ini.
user_ini.cache_ttl controls how often user INI files are re-read. The default is 300 seconds (5 minutes).
These modes determine when and where a PHP directive may or may not be set, and each directive within the manual refers to one of these modes. For example, some settings may be set within a PHP script using ini_set(), whereas others may require php.ini or httpd.conf.
For example, the output_buffering setting is PHP_INI_PERDIR therefore it may not be set using ini_set(). However, the display_errors directive is PHP_INI_ALL therefore it may be set anywhere, including with ini_set().
| Mode | Meaning |
|---|---|
| PHP_INI_USER | Entry can be set in user scripts (like with ini_set()) or in the Windows registry |
| PHP_INI_PERDIR | Entry can be set in php.ini, .htaccess or httpd.conf |
| PHP_INI_SYSTEM | Entry can be set in php.ini or httpd.conf |
| PHP_INI_ALL | Entry can be set anywhere |
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.
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.
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.
Забележка: Don't use
php_valueto 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 ini_set().
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.
Example #1 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>
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
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.
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().
Когато PHP прави разбор на файл, той гледа за отварящи и затварящи тагове, които да укажат започването и спирането на интерпретацията на кода между тях. Този вид разбор позволява php да бъде поставян в най-различни документи като всичко извън двойката отварящи и затварящи тагове се игнорира от синтактичния анализатор на PHP. В повечето случаи ще видите php, поставен в документи от тип HTML, както в следния пример.
<p>Това ще бъде игнорирано.</p>
<?php echo 'Докато това ще бъде анализирано.'; ?>
<p>Това също ще бъде игнорирано.</p>
Можете да използвате и по-сложни структури:
Example #1 Излизане за напреднали
<?php
if ($expression) {
?>
<strong>Това е истина.</strong>
<?php
} else {
?>
<strong>Това е неистина.</strong>
<?php
}
?>
Това работи както се очаква, защото когато PHP се натъкне на затварящия таг ?>, той просто започва да извежда всичко, което намери (с изключение на първия знак за нов ред - вж. разделяне на инструкции ), докато не намери друг отварящ таг. Даденият пример е скалъпен, разбира се, но за извеждането на големи блокове от текст излизането от синтактичния режим на PHP като цяло е по-ефикасно, отколкото изпращането на целия текст през echo() или print().
Има четири различни двойки отварящи и затварящи тагове, които могат да бъдат използвани в PHP. Две от тях (<?php. . .?> и <script language="php">. . .</script>) са налични винаги. Другите две са късите тагове и тези в стил ASP и могат да бъдат включвани или изключвани в конфигурационния файл php.ini. Като такива, въпреки че някои хора считат късите тагове и тези в стил ASP за удобни, те не са толкова преносими и като цяло не са препоръчителни.
Забележка: Също така, ако възнамерявате да вмъквате PHP код в XML или XHTML, ще трябва да използвате <?php. . .?> формата, за дa бъде съобразен със стандартите.
Example #2 Отварящи и затварящи тагове в PHP
1. <?php echo 'правете така, ако искате да работите с документи от тип XHTML или XML'; ?>
2. <script language="php">
echo 'някои редактори (като FrontPage) не
харесват ходовите инструкции';
</script>
3. <? echo 'това е най-простата, SGML-ходова инструкция'; ?>
<?= expression ?> Това е съкращение на "<? echo expression ?>"
4. <% echo 'По избор, можете да използвате тагове в стил ASP'; %>
<%= $variable; # Това е съкращение на "<% echo . . ." %>
Въпреки че таговете в примери едно и две са налични винаги, първият пример е най-използван и е препоръчителен.
Късите тагове (пример три) са налични единствено ако са били позволени посредством конфигурационната директива short_open_tag в php.ini или ако php е конфигуриран с --enable-short-tags.
Таговете в стил ASP (пример четири) са налични единствено ако са били позволени посредством конфигурационната директива asp_tags в php.ini.
Забележка: Употребата на къси тагове трябва да бъде избягвана при разработването на приложения или библиотеки, предназначени за повторно разпространение или инсталиране на сървъри с PHP, които не са под ваш контрол, тъй като е възможно късите тагове да не се поддържат на сървъра. За преносим, разпространим код, се осигурете, че не използвате къси тагове.
Също както в C и Perl, PHP изисква инструкциите да бъдат завършвани с точка и запетая на края на всеки израз. Затварящият таг на блок от PHP код автоматично заключва в себе си и точка и запетая; не е необходимо да завършвате с точка и запетая последния ред от PHP блок. Затварящият таг на блока ще включи и непосредствено последващия знак за нов ред, ако има такъв.
<?php
echo 'Това е проба';
?>
<?php echo 'Това е проба' ?>
<?php echo 'Пропуснахме последния затварящ таг';
Забележка: Затварящият таг на PHP блок в края на файл е незадължителен и в някои случаи пропускането му е полезно, в случай че се използва include() или require(), така че да не се появят нежелани празнини в краищата на файловете и да можете да добавяте заглавки към отговора по-късно. Това е удобно и когато използвате буфериране на изхода и не искате да се появява нежелана празнина в края на частите, генерирани от включваните файлове.
PHP поддържа коментари в 'C', 'C++' или Unix shell стил. Например:
<?php
echo 'Това е проба'; // Това е едноредов коментар в стил c++
/* Това е многоредов коментар
още един ред коментар */
echo 'Това е друга проба';
echo 'Последна проба'; # Това е едноредов коментар в стил обвивка (shell)
?>
Едноредовият коментар коментира до края на реда или до края на текущия блок PHP код, което от двете дойде първо. Това означава, че кодът HTML след // ... ?> или # ... ?> ЩЕ БЪДЕ отпечатан: ?> излиза от режим PHP и се връща в режим HTML и // или # не могат да повлияят на това. Поведението е същото с // %> и # %> ако конфигурационната директива asp_tags е включена. Все пак, тагът </script> не излиза от режим PHP при едноредов коментар.
<h1>Това е <?php # echo 'прост';?> пример.</h1>
<p>Заглавието горе ще бъде 'Това е пример'.
Коментарите в стил 'C' завършват при първото срещане на */. Осигурете се, че не влагате коментари в стил 'C' един в друг. Това е лесно допустима грешка при коментиране на голям блок от код.
<?php
/*
echo 'Това е проба'; /* Този коментар ще създаде проблем */
*/
?>
PHP поддържа осем примитивни типа.
Четири скаларни типа:
Два съставни типа:
И накрая, два специални типа:
Това ръководство въвежда също и някои псевдо-типове с цел - по-добра четимост:
И псевдо-променливата $... .
Възможно е да се натъкнете също и на препратки към типа "double" (двоен). Разглеждайте го като число с плаваща запетая (float), двете имена съществуват единствено по исторически причини.
Типът на променливата обикновено не се указва от програмиста; по-често, той се решава по време на изпълнение от PHP в зависимост от контекста, в който е използвана тази променлива.
Забележка: Ако искате да разберете типа и стойността на даден израз, използвайте var_dump(). Ако желаете човешко представяне на типа, с цел откриване на грешки, използвайте gettype(). За да проверите даден тип, не използвайте gettype(), а функциите is_type. Няколко примера:
<?php
$a_bool = TRUE; // булев
$a_str = "foo"; // низ
$an_int = 12; // цяло число
echo gettype($a_bool); // отпечатва "boolean"
echo gettype($a_str); // отпечатва "string"
// Ако това е цяло число, увеличи го с четири
if (is_int($an_int)) {
$int += 4;
}
// Ако $a_bool е низ го отпечатай на екрана
// (does not print out anything)
if (is_string($a_bool)) {
echo "Низ: $a_bool";
}
?>
Ако искате изрично да превърнете променлива в даден тип, можете или да я преобразувате, или да използвате функцията settype() върху нея.
Забележете, че в някои случаи променливата може да бъде изчислена по различен начин, в зависимост от това какъв е типът й в момента. За повече информация, вижте раздела за Манипулации с типове. Също, би представлявало интерес за вас да разгледате таблицата за сравнение на типовете, тъй като там има примери за най-различни сравнения, свързани с типовете.
Това е най-лесния тип. Булевият тип изразява стойност за истинност. Той може да бъде или TRUE (истина), или FALSE (неистина).
Забележка: Булевият тип беше въведен в PHP 4.
За да укажете булев литерал, използвайте една от двете ключови думи: TRUE или FALSE. И двете са нечувствителни към регистъра.
<?php
$foo = True; // присвояване на стойността TRUE на $foo
?>
В повечето случаи се използва някакъв вид оператор, който връща булева стойност, която след това се предава на контролна структура.
<?php
// == е оператор, който проверява
// равенство и връща булев
if ($action == "show_version") {
echo "The version is 1.23";
}
// това не е необходимо...
if ($show_separators == TRUE) {
echo "<hr>\n";
}
// ...защото може просто да напишете
if ($show_separators) {
echo "<hr>\n";
}
?>
За да превърнете изрично стойност в булев тип, използвайте преобразуването (bool) или (boolean). В повечето случаи обаче няма нужда да се използва преобразуване, понеже стойността ще бъде преобразувана автоматично, когато даден оператор, функция или контролна структура изискват булев аргумент.
Вж. също Манипулации с типове.
При преобразуване в булев тип, следните стойности се считат за FALSE:
Всяка друга стойност се смята за TRUE (включително който и да е ресурс).
-1 се смята за TRUE, като всяко друго не-нулево (отрицателно или положително) число!
<?php
var_dump((bool) ""); // bool(false)
var_dump((bool) 1); // bool(true)
var_dump((bool) -2); // bool(true)
var_dump((bool) "foo"); // bool(true)
var_dump((bool) 2.3e5); // bool(true)
var_dump((bool) array(12)); // bool(true)
var_dump((bool) array()); // bool(false)
var_dump((bool) "false"); // bool(true)
?>
Целочислено е всяко число от множеството Z = {..., -2, -1, 0, 1, 2, ...}.
Вж. също: Цели числа с произволна дължина / GMP, Числа с плаваща запетая и Произволна точност / BCMath
Целите числа могат да бъдат дефинирани в десетична (с основа 10), шестнайсетична (с основа 16) или осмична (с основа 8) бройна система, незадължително предшествани от знак (- или +).
Ако използвате осмична бройна система, трябва да предшествате числото с 0 (нула), а за да използвате шестнайсетична система, трябва да го предшествате с 0x.
Example #1 Целочислени литерали
<?php
$a = 1234; // десетично число
$a = -123; // отрицателно число
$a = 0123; // осмично число (еквивалентно на десетично 83)
$a = 0x1A; // шестнайсетично число (еквивалентно на десетично 26)
?>
Възможните шаблони за цели числа са:
десетично : [1-9][0-9]*
| 0
шестнадесетично : 0[xX][0-9a-fA-F]+
осмично : 0[0-7]+
цяло число : [+-]?decimal
| [+-]?hexadecimal
| [+-]?octal
Размерът на целите числа е платформено-зависим, макар че обикновено максималната стойност е около два милиарда (т.е. 32 бита със знак). PHP не поддържа беззнакови цели числа. Текущият размер на целите числа може да бъде установен посредством PHP_INT_SIZE, а максималната стойност - от PHP_INT_MAX, след PHP 4.4.0 и PHP 5.0.5.
Ако на осмично число бъде подадена невалидна цифра (т.е. 8 или 9), остатъкът от числото ще бъде пренебрегнат.
Example #2 Осмична особеност
<?php
var_dump(01090); // осмично 010 = десетично 8
?>
Ако укажете число извън обхвата на целочисления тип, то ще бъде интерпретирано като число с плаваща запетая. Също така, ако извършите операция, чийто резултат е число извън обхвата на целочисления тип, то също ще бъде върнато в плаващ тип.
<?php
$large_number = 2147483647;
var_dump($large_number);
// изход: int(2147483647)
$large_number = 2147483648;
var_dump($large_number);
// изход: float(2147483648)
// работи също за цели числа, указани в шестнадесетична система, в интервала от 2^31 до 2^32-1:
var_dump( 0xffffffff );
// output: float(4294967295)
// не работи за цели числа, указани в шестнадесетична система, за стойности над 2^32-1:
var_dump( 0x100000000 );
// изход: int(2147483647)
$million = 1000000;
$large_number = 50000 * $million;
var_dump($large_number);
// изход: float(50000000000)
?>
За нещастие, в PHP съществуваше грешка, така че това не работи винаги както трябва, когато са намесени отрицателни числа. Например: когато правите -50000 * $million, резултатът ще бъде -429496728. Все пак, когато и двата операнда са положителни, няма проблем.
Грешката е поправена в PHP 4.1.0.
В PHP няма оператор за целочислено деление. 1/2 дава плаващо 0.5. Можете да преобразувате стойността до цяло число, така че тя винаги да се закръгля надолу, или пък да използвате функцията round().
<?php
var_dump(25/7); // float(3.5714285714286)
var_dump((int) (25/7)); // int(3)
var_dump(round(25/7)); // float(4)
?>
За да превърнете изрично стойност в цяло число, използвайте преобразуването (int) или (integer). В повечето случаи обаче няма нужда да се използва преобразуване, понеже стойността ще бъде преобразувана автоматично, когато даден оператор, функция или контролна структура изискват целочислен аргумент. Можете също да превърнете стойност в цяло число посредством функцията intval().
Вж. също Манипулации с типове.
FALSE ще даде 0 (нула), а TRUE ще даде 1 (едно).
При превръщане от плаващо в цяло, числото ще бъде закръглено към нулата (надолу).
Ако плаващото е извън обхвата на цяло число (обикновено +/- 2.15e+9 = 2^31), резултатът е недефиниран, тъй като плаващото не е имало достатъчно точност, за да даде правилен целочислен резултат. В този случай няма да бъде изведено нито предупреждение, нито дори и съобщение!
Никога не преобразувайте неизвестна дроб в цяло число, защото понякога това може да доведе до неочаквани резултати.
<?php
echo (int) ( (0.1+0.7) * 10 ); // извежда 7!
?>
За повече информация, вижте предупреждението за плаваща точност.
Поведението при превръщане от други типове в цяло число е недефинирано. В момента, поведението е същото, както ако стойността първо е била превърната в булев. Все пак, не разчитайте на това поведение, тъй като в бъдеще то може да се промени без предупреждение.
Числата с плаваща запетая (също познати като "плаващи", "двойни" или "реални числа") могат да бъдат дефинирани посредством кой да е от следните синтаксиси:
<?php
$a = 1.234;
$b = 1.2e3;
$c = 7E-10;
?>
Формално:
LNUM [0-9]+
DNUM ([0-9]*[\.]{LNUM}) | ({LNUM}[\.][0-9]*)
EXPONENT_DNUM ( ({LNUM} | {DNUM}) [eE][+-]? {LNUM})
Размерът на плаващите числа е платформено-зависим, макар че обикновено максималната стойност е около ~1.8e308, с 14-цифрена точност (64-битов IEEE формат).
В много случаи, прости десетични дроби като 0.1 или 0.7 не могат да бъдат превърнати във вътрешните им двоични еквиваленти без да претърпят малка загуба в точността. Това може да доведе до объркващи резултати: например floor((0.1+0.7)*10) в повечето случаи ще върне 7, вместо очакваното 8, тъй като вътрешното представяне в действителност е нещо подобно на 7.9999999999....
Това е свързано с факта, че някои дроби не могат да бъдат представени в десетичен вид с краен брой цифри. Например 1/3 в десетичен вид става 0.3333333. . ..
Така че, никога не се доверявайте на последните цифри в резултати от плаващи числа и никога не сравнявайте числа с плаваща запетая за равенство. Ако наистина се нуждаете от по-висока точност, трябва да използвате математическите функции за произволна точност или пък функциите gmp.
За информация кога и как низовете биват преобразувани в плаващи, вижте раздела, озаглавен Превръщане на низ в число. За стойности от други типове, преобразуването е същото, както ако стойността първо е била превърната в цяло число и после в плаващо. Вижте раздел Преобразуване в цяло число за повече информация. След PHP 5, ще бъде хвърлено съобщение (notice) ако опитате да превърнете обект в плаващо число.
Низът представлява поредица от знаци. В PHP, знакът е същото като байт, т.е., съществуват точно 256 възможни знака. Това също означава, че PHP няма естествена поддръжка за Unicode. Вж. utf8_encode() и utf8_decode() за Unicode поддръжка.
Забележка: За даден низ не е проблем да стане много дълъг. Няма практическо ограничение в размера на низовете, наложено от PHP, така че не трябва да се безпокоите за дългите низове.
Низов литерал може да бъде дефиниран по три различни начина.
Най-лесният начин да се дефинира обикновен низ е да се загради с апострофи (знакът ').
За да укажете знака апостроф, трябва да го екранирате с обратно-наклонена черта (\), както това се прави и в редица други езици. Ако все пак се налага преди апострофа да се появи обратно-наклонена черта, ще трябва да я дублирате. Отбележете, че ако се опитате да екранирате който и да е друг знак, обратно-наклонената черта също ще бъде отпечатана! Така че обикновено тя няма нужда да бъде екранирана.
Забележка: В PHP 3 ще бъде изведено предупреждение от ниво E_NOTICE, когато това се случи.
Забележка: За разлика от другите два синтаксиса, тук променливите и екраниращите последователности за специални знаци няма да бъдат обработени.
<?php
echo 'това е обикновен низ';
echo 'Можете също да поставяте и
нови редове по този
начин';
// Извежда: Арнолд веднъж каза: "I'll be back"
echo 'Арнолд веднъж каза: "I\'ll be back"';
// Извежда: Вие изтрихте C:\*.*?
echo 'Вие изтрихте C:\\*.*?';
// Извежда: Вие изтрихте C:\*.*?
echo 'Вие изтрихте C:\*.*?';
// Извежда: Това няма да се изведе: \n - нов ред
echo 'Това няма да се изведе: \n - нов ред';
// Извежда: Променливите също: $alpha $beta
echo 'Променливите също: $alpha $beta';
?>
Ако низът е заграден в кавички ("), PHP разбира повече екраниращи последователности за специални знаци:
| последователност | значение |
|---|---|
| \n | нов ред (LF или 0x0A (10) в ASCII) |
| \r | връщане на каретката (CR или 0x0D (13) в ASCII) |
| \t | табулация (HT или 0x09 (9) в ASCII) |
| \v | вертикална табулация (VT или 0x0B (11) в ASCII) (от PHP 5.2.5) |
| \f | form feed (FF или 0x0C (12) в ASCII) (от PHP 5.2.5) |
| \\ | обратно-наклонена черта |
| \$ | знак за долар |
| \" | кавичка |
| \[0-7]{1,3} | последователността от знаци, съвпадаща с регулярния израз, е знак в осмична бройна система |
| \x[0-9A-Fa-f]{1,2} | последователността от знаци, съвпадаща с регулярния израз, е знак в шестнайсетична бройна система |
И тук ако се опитате да екранирате който и да е друг знак, обратно-наклонената черта също ще бъде отпечатана! Преди PHP 5.1.1, обратно-наклонената черта в \{$var} не се отпечатваше.
Най-важната особеност на кавичките, обаче, е че променливите ще бъдат обработени. За повече информация вижте разбор на низ.
Друг начин да се дефинира низ е да се използва синтаксис от тип heredoc ("<<<"). След <<< трябва да се укаже идентификатор (последван от нов ред), след това низа и накрая самия идентификатор, който да затвори цитата.
Затварящият идентификатор трябва да започне в първата колона на реда. Освен това, използваният идентификатор трябва да следва същите правила за именуване като всеки друг етикет в PHP: трябва да се състои единствено от буквено-цифрови знаци или подчертавки и трябва да започва със знак, който не е цифра.
Много важно е да се отбележи, че на реда със затварящия идентификатор няма никакви други знаци, освен по възможност точка и запетая (;). Това преди всичко означава, че идентификаторът не може да бъде отместван като абзац и не може да има никакви интервали или табулации преди или след точката и запетаята. Важно е също да се разбере, че първият знак преди затварящия идентификатор трябва да бъде знака за нов ред, както е дефиниран от съответната операционна система. Например на Macintosh това е \r. Освен това, затварящият идентификатор (по желание последван от точка и запетая) трябва да бъде последван и от знак за нов ред.
Ако това правило не се спази и затварящият идентификатор не е "чист", тогава той няма да бъде възприет като такъв и PHP ще продължи да го търси. Ако в този случай не бъде намерен правилен затварящ идентификатор, това ще доведе до синтактична грешка с номер на реда в края на скрипта.
Не е разрешена употребата на синтаксис от тип heredoc в инициализиране на членове на клас. В този случай използвайте другите низови синтаксиси.
Example #1 Невалиден пример
<?php
class foo {
public $bar = <<<EOT
bar
EOT;
}
?>
Heredoc текстът работи по същия начин както и низът в кавички, само че без кавичките. Това означава, че няма нужда да екранирате кавичките, но че можете да използвате екраниращите кодове изброени по-горе. Променливите биват обработени, но трябва да се внимава при изразяване на сложни променливи вътре в heredoc, какъвто е и случаят с низовете.
Example #2 Пример за цитат от тип heredoc
<?php
$str = <<<EOD
Пример за низ,
който преминава на няколко
реда със синтаксис heredoc.
EOD;
/* По-сложен пример, с променливи. */
class foo
{
var $foo;
var $bar;
function foo()
{
$this->foo = 'Foo';
$this->bar = array('Bar1', 'Bar2', 'Bar3');
}
}
$foo = new foo();
$name = 'MyName';
echo <<<EOT
Казвам се "$name". Отпечатвам някое $foo->foo.
Сега, отпечатвам някое {$foo->bar[1]}.
Това трябва да отпечата главно 'A': \x41
EOT;
?>
Забележка: Поддръжката на heredoc беше добавена в PHP 4.
Nowdocs are to single-quoted strings what heredocs are to double-quoted strings. A nowdoc is specified similarly to a heredoc, but no parsing is done inside a nowdoc. The construct is ideal for embedding PHP code or other large blocks of text without the need for escaping. It shares some features in common with the SGML <![CDATA[ ]]> construct, in that it declares a block of text which is not for parsing.
A nowdoc is identified with the same <<< seqeuence used for heredocs, but the identifier which follows is enclosed in single quotes, e.g. <<<'EOT'. All the rules for heredoc identifiers also apply to nowdoc identifiers, especially those regarding the appearance of the closing identifier.
Example #3 Nowdoc string quoting example
<?php
$str = <<<'EOD'
Example of string
spanning multiple lines
using nowdoc syntax.
EOD;
/* More complex example, with variables. */
class foo
{
public $foo;
public $bar;
function foo()
{
$this->foo = 'Foo';
$this->bar = array('Bar1', 'Bar2', 'Bar3');
}
}
$foo = new foo();
$name = 'MyName';
echo <<<'EOT'
My name is "$name". I am printing some $foo->foo.
Now, I am printing some {$foo->bar[1]}.
This should not print a capital 'A': \x41
EOT;
?>
Примерът по-горе ще изведе:
My name is "$name". I am printing some $foo->foo.
Now, I am printing some {$foo->bar[1]}.
This should not print a capital 'A': \x41Забележка: Unlike heredocs, nowdocs can be used in any static data context. The typical example is initializing class members or constants:
Example #4 Static data example
<?php
class foo {
public $bar = <<<'EOT'
bar
EOT;
}
?>
Забележка: Nowdoc support was added in PHP 5.3.0.
Когато даден низ се дефинира в кавички или с heredoc, променливите в него биват анализирани.
Съществуват два типа синтаксис: прост и сложен. Простият синтаксис е най-разпространен и удобен. Той предлага начин да се анализира променлива, стойност от масив, или свойство на обект.
Сложният синтаксис беше въведен в PHP 4 и може да бъде разпознат по фигурните скоби, заграждащи израза.
Ако срещне знака за долар ($), синтактичният анализатор ще се опита да поеме лакомо колкото се може повече знаци, за да образува валидно име на променлива. Заградете името на променливата във фигурни скоби, ако искате изрично да укажете края на името.
<?php
$beer = 'Kamenitza';
echo "$beer's taste is great"; // работи, "'" е невалиден знак за име на променлива
echo "He drank some $beers"; // няма да работи, 's' е валиден знак за име на променлива
echo "He drank some ${beer}s"; // работи
echo "He drank some {$beer}s"; // работи
?>
По същия начин се прави разбор и на елемент от масив или свойство на обект. При индексите на масиви, затварящата квадратна скоба (]) обозначава края на индекса. За свойствата на обекти важат същите правила както за обикновените променливи, макар че при обектните свойства не съществува трик като този при променливите.
<?php
// Тези примери са специфични за употребата на масиви в низове.
// Извън низ, винаги заграждайте с апострофи низовите ключове на масиви
// и съответно - не използвайте {фигурни скоби}.
// Нека се показват всички грешки
error_reporting(E_ALL);
$fruits = array('strawberry' => 'red', 'banana' => 'yellow');
// Работи, но отбележете, че това работи по друг начин извън низовите кавички
echo "A banana is $fruits[banana].";
// Работи
echo "A banana is {$fruits['banana']}.";
// Работи, но PHP първо търси константа с името "banana",
// както е обяснено по-долу.
echo "A banana is {$fruits[banana]}.";
// Няма да работи, използвайте фигурни скоби. Това ще предизвика синтактична грешка.
echo "A banana is $fruits['banana'].";
// Работи
echo "A banana is " . $fruits['banana'] . ".";
// Работи
echo "This square is $square->width meters broad.";
// Няма да работи. За решение, вижте сложния синтаксис.
echo "This square is $square->width00 centimeters broad.";
?>
За всичко по-сложно трябва да използвате сложния синтаксис.
Името "сложен" не е защото синтаксисът е сложен, а защото чрез него можете да включвате сложни изрази.
На практика, с този синтаксис можете да включите в низ коя да е стойност, която е налична в пространството от имена. Просто пишете израза по същия начин както бихте го направили извън низа, след което го поставете между { и }. Тъй като не можете да екранирате '{', този синтаксис ще бъде разпознат единствено, когато $ следва непосредствено {. (Използвайте "{\$", за да получите литерала "{$"). Няколко разяснителни примера:
<?php
// Нека се показват всички грешки
error_reporting(E_ALL);
$great = 'fantastic';
// Няма да работи, извежда: This is { fantastic}
echo "This is { $great}";
// Работи, извежда: This is fantastic
echo "This is {$great}";
echo "This is ${great}";
// Работи
echo "This square is {$square->width}00 centimeters broad.";
// Работи
echo "This works: {$arr[4][3]}";
// Това е грешно по същата причина, поради която и $foo[bar] е грешно
// извън низ. С други думи, ще работи, но понеже PHP първо
// ще потърси константата foo, ще хвърли грешка от ниво
// E_NOTICE (недефинирана константа).
echo "This is wrong: {$arr[foo][3]}";
// Работи. При многомерни масиви, винаги поставяйте
// фигурни скоби около масивите, когато са в низове.
echo "This works: {$arr['foo'][3]}";
// Работи.
echo "This works: " . $arr['foo'][3];
echo "You can even write {$obj->values[3]->name}";
echo "This is the value of the var named $name: {${$name}}";
echo "This is the value of the var named by the return value of getName(): {${getName()}}";
echo "This is the value of the var named by the return value of \$object->getName(): {${$object->getName()}}";
?>
Забележка: Извикването на функции и методи в рамките на {$ } работи от PHP 5.
Забележка: Разборът на променливи в рамките на низове използва повече памет отколкото свързването на низове. Когато пишете PHP скрипт, в който паметта е фактор, обмислете възможността да използвате оператора за свързване (.), а не разбор на променливи.
Знаците в даден низ могат да бъдат достъпвани и изменяни чрез указване на отместване от нулата за желания знак след низа посредством квадратни скоби, например $str[42], така че бихте могли да мислите за даден низ като за масив от знаци.
Забележка: Те също могат да бъдат достъпвани и с фигурни скоби - $str{42}, със същата цел. Все пак, употребата на квадратни скоби е за предпочитане, тъй като {фигурният} стил става непрепоръчителен от PHP 6.
Example #5 Някои низови примери
<?php
// Вземане на първия знак от низ.
$str = 'Това е тест.';
$first = $str[0];
// Вземане на третия знак от низ.
$third = $str[2];
// Вземане на последния знак от низ.
$str = 'Това продължава да бъде тест.';
$last = $str[strlen($str)-1];
// Промяна на последния знак от низ.
$str = 'На масата има ябълка';
$str[strlen($str)-1] = 'и';
// Алтернативният метод с {} е непрепоръчителен от PHP 6
$third = $str{2};
?>
Забележка: Достъпването до променливи от друг тип с [] или {} мълчаливо връща NULL.
Низовете могат да бъдат съединявани посредством оператора '.' (точка). Забележете, че операторът '+' (събиране) няма да направи това. За повече информация вижте Низови оператори.
Съществуват доста на брой полезни функции за изменение на низове.
За основните функции вижте раздел низови функции, а за по-сложно търсене и заместване - функциите за регулярни изрази (в две разновидности: Perl и POSIX разширения).
Има също функции за URL низове и функции за криптиране и декриптиране на низове (mcrypt и mhash).
Накрая, ако все още не сте намерили това, което търсите, вижте също и функциите за типове знаци.
Можете да превърнете стойност в низ посредством преобразуването (string) или функцията strval(). Низовото преобразуване се извършва автоматично в обхвата на израз, който се нуждае от низ. Това се случва, когато използвате функциите echo() и print(), или когато сравнявате стойността на променлива с низ. Прочитането на разделите за Типове и Манипулации с типове ще направи нещата още по-ясни. Вж. също settype().
Булевата стойност TRUE се преобразува в низа "1", а стойността FALSE се представя като "" (празен низ). По този начин можете да преобразувате двупосочно между булеви и низови стойности.
Цяло число (integer) или число с плаваща запетая (float) се преобразува в низ, който се състои от цифрите на числото (включително и експонентата - за числата с плаваща запетая). Числата с плаваща запетая може да бъдат преобразувани посредством експоненциалната система за означаване (4.1E+6).
Забележка: Знакът за десетична запетая се дефинира в локалните настройки на скрипта (категория LC_NUMERIC). Вж. setlocale().
Масивите винаги се преобразуват в низа "Array", така че не можете да покажете съдържанието на даден масив с echo() или print(). За да видите един елемент, трябва да направите нещо от рода на echo $arr['foo']. Погледнете по-долу за начини за показване на цялото съдържание.
Обектите в PHP 4 винаги се преобразуват в низа "Object". Ако искате да покажете стойностите на член-променливите на даден обект, с цел отстраняване на програмни грешки, прочетете следващите абзаци. За да видите името на класа, на който е инстанция обектът, използвайте get_class(). От PHP 5 се използва метода __toString(), ако е приложим.
Ресурсите винаги се преобразуват в низове със структура "Resource id #1", където 1 е уникалното число на ресурса, присвоено от PHP по време на изпълнение. Ако искате да вземете типа на ресурса, използвайте get_resource_type().
NULL винаги се преобразува в празен низ.
Както можете да видите по-горе, отпечатването на масиви, обекти или ресурси не ви предоставя никаква полезна информация за самите стойности. Разгледайте функциите print_r() и var_dump() за по-добри начини за показване на стойностите, в процеса на отстраняване на грешки.
Можете също да превърнете стойности от PHP в низове за постоянно съхранение. Този метод се нарича сериализация и може да се осъществи посредством функцията serialize(). Можете също да сериализирате стойности от PHP в XML структури, стига във вашата инсталация на PHP да имате поддръжка за WDDX.
Когато даден низ бъде разпознат като число, резултантната стойност и типът се определят както следва.
Низът ще се изчисли като плаващо ако съдържа който и да е от знаците '.', 'e' или 'E'. В противен случай, ще се изчисли като цяло число.
Стойността се взима от първата част на низа. Ако низът започва с валидни числови данни, това ще бъде и използваната стойност. В противен случай стойността ще бъде 0 (нула). Валидните числови данни са незадължителен знак, последван от една или повече цифри (по желание съдържащи и плаваща запетая), последвани от незадължителна експонента. Експонентата се изразява с латинската буква 'e' или 'E', последвана от една или повече цифри.
<?php
$foo = 1 + "10.5"; // $foo е плаващо (11.5)
$foo = 1 + "-1.3e3"; // $foo е плаващо (-1299)
$foo = 1 + "bob-1.3e3"; // $foo е цяло число (1)
$foo = 1 + "bob3"; // $foo е цяло число (1)
$foo = 1 + "10 малки прасета"; // $foo е цяло число (11)
$foo = 4 + "10.2 малки прасенца"; // $foo е плаващо (14.2)
$foo = "10.0 прасета " + 1; // $foo е плаващо (11)
$foo = "10.0 прасета " + 1.0; // $foo е плаващо (11)
?>
За повече информация относно това преобразуване вижте страницата от ръководството на Unix за strtod(3).
В случай, че искате да проверите някой от примерите в този раздел, можете да ги препишете и да сложите следния ред, за да се уверите сами какво се случва:
<?php
echo "\$foo==$foo; типът е " . gettype ($foo) . "<br />\n";
?>
Не разчитайте да получите кода на даден низ като го преобразувате в цяло число (както бихте направили в C например). Използвайте функциите ord() и chr(), за да правите преобразувания между знаци и съответните им кодове.
Масивът в PHP всъщност представлява подредена асоциация (ordered map). Асоциацията е тип, който асоциира стойности към ключове. Този тип е оптимизиран по няколко направления, така че можете да го използвате като реален масив, като списък (вектор), хеш-таблица (което е реализация на асоциация), речник, колекция, стек, опашка и др. Тъй като за стойност може да имате друг масив, много лесно можете да симулирате и дървета.
Описанието на тези структури от данни е извън обхвата на това ръководство, но ще намерите поне един пример за всяка от тях. За повече информация по тази обширна тема ви препоръчваме да се насочите към външна литература.
Масив може да бъде създаден посредством езиковата конструкция array(). Тя приема определено количество двойки ключ => стойност , разделени със запетаи.
array( ключ => стойност , ... ) // ключът може да бъде цяло число или низ // стойността може да бъде всякаква
<?php
$arr = array("foo" => "bar", 12 => true);
echo $arr["foo"]; // bar
echo $arr[12]; // 1
?>
Ключът може да бъде или цяло число, или низ. Ако ключът е представен като обикновено цяло число, той ще бъде интерпретиран като такова (т.е. "8" ще се интерпретира като 8, докато "08" - като "08"). Плаващите числа в ключовете се съкращават до цели. В PHP не съществуват различни типове за индексирани и асоциативни масиви; има само един тип масив, който може да съдържа едновременно целочислени и низови индекси.
Стойността може да бъде от всякакъв тип.
<?php
$arr = array("somearray" => array(6 => 5, 13 => 9, "a" => 42));
echo $arr["somearray"][6]; // 5
echo $arr["somearray"][13]; // 9
echo $arr["somearray"]["a"]; // 42
?>
Ако не укажете изрично ключ за дадена стойност, то ще се вземе най-голямата стойност от целочислените индекси и новият ключ ще бъде тази стойност + 1. Ако укажете ключ, който вече има присвоена стойност, то тази стойност ще бъде презаписана.
<?php
// Този масив е същият като ...
array(5 => 43, 32, 56, "b" => 12);
// ...този.
array(5 => 43, 6 => 32, 7 => 56, "b" => 12);
?>
От PHP 4.3.0 насам поведението за генериране на индекси се промени. Сега ако добавяте към масив, в който текущият максимален ключ е отрицателен, следващият създаден ключ ще бъде нула (0). А преди, новият индекс щеше да бъде установен в най-големия съществуващ ключ + 1, както е случая с положителните индекси.
Използването на TRUE като ключ ще се изчисли като целочислено 1. Употребата на FALSE като ключ ще се изчисли като целочислено 0. Използването на NULL като ключ ще се изчисли като празнен низ. Употребата на празен низ като ключ ще създаде (или презапише) ключ с празен низ и съответната му стойност; това не е същото като използването на празни квадратни скоби.
Не можете да използвате масиви или обекти като ключове. Ако се опитате да го направите ще предизвикате предупреждение: Illegal offset type (невалиден тип отместване).
Можете също да променяте съществуващ масив чрез изрично установяване на стойностите в него.
Това се осъществява чрез присвояване на стойностите в масива, като ключовете се указват в квадратни скоби. Можете също да пропуснете ключа като добавите празна двойка квадратни скоби ("[]") към името на променливата.
$arr[key] = value; $arr[] = value; // key може да бъде цяло число или низ // value може да бъде каква да е стойностАко масивът $arr все още не съществува, той ще бъде създаден. Така че това също е и алтернативен начин за указване на масив. За да промените дадена стойност, просто присвоете нова стойност на елемента, указан чрез ключа му. Ако искате да премахнете някоя двойка ключ/стойност, трябва да я унищожите посредством unset().
<?php
$arr = array(5 => 1, 12 => 2);
$arr[] = 56; // Това е същото като $arr[13] = 56;
// в този момент на скрипта
$arr["x"] = 42; // Това добавя нов елемент към
// масива с ключ "x"
unset($arr[5]); // Това премахва елемент от масива
unset($arr); // Това изтрива целия масив
?>
Забележка: Както беше споменато по-горе, ако предоставите квадратните скоби без указан ключ, тогава ще бъде взет максималния съществуващ целочислен индекс и новият ключ ще бъде тази стойност + 1 . Ако все още няма целочислени индекси, ключът ще бъде 0 (нула). Ако укажете ключ, който вече има присвоена стойност, то тази стойност ще бъде презаписана.
ПредупреждениеОт PHP 4.3.0 насам поведението за генериране на индекси, описано по-горе, се промени. Сега ако добавяте към масив, в който текущият максимален ключ е отрицателен, следващият създаден ключ ще бъде нула (0). А преди, новият индекс щеше да бъде установен в най-големия съществуващ ключ + 1, както е случая с положителните индекси.
Забележете, че максималната целочислена стойност, използвана за целта, не е задължително да същестува в масива в момента. Тя просто трябва да е съществувала някога в масива от последния път, когато масивът е бил повторно индексиран. Следният пример пояснява:
<?php
// Създаване на обикновен масив.
$array = array(1, 2, 3, 4, 5);
print_r($array);
// Сега изтриваме всеки елемент, но оставяме самия масив непокътнат:
foreach ($array as $i => $value) {
unset($array[$i]);
}
print_r($array);
// Добавяне на елемент (забележете, че новият ключ е 5, а не 0, както
// вероятно бихте очаквали).
$array[] = 6;
print_r($array);
// Повторно индексиране:
$array = array_values($array);
$array[] = 7;
print_r($array);
?>Примерът по-горе ще изведе:
Array ( [0] => 1 [1] => 2 [2] => 3 [3] => 4 [4] => 5 ) Array ( ) Array ( [5] => 6 ) Array ( [0] => 6 [1] => 7 )
Има няколко полезни функции за работа с масиви. Вж. раздел функции за масиви.
Забележка: Функцията unset() позволява унищожаването на ключове от масив, при което масивът НЯМА да бъде повторно индексиран. Ако използвате единствено "обичайните целочислени индекси" (започващи от нула, увеличаващи се с едно), можете да постигнете ефекта на повторно индексиране като използвате array_values().
<?php
$a = array(1 => 'one', 2 => 'two', 3 => 'three');
unset($a[2]);
/* ще доведе до масив, който би бил дефиниран като
$a = array(1 => 'one', 3 => 'three');
а НЕ като
$a = array(1 => 'one', 2 =>'three');
*/
$b = array_values($a);
// Сега $b е array(0 => 'one', 1 =>'three')
?>
Контролната структура foreach е създадена специално за масиви. Тя предоставя лесен начин за обхождане на масив.
Винаги трябва да заграждате низовите индекси на масиви с апострофи. Например използвайте $foo['bar'], а не $foo[bar]. Но защо все пак $foo[bar] е неправилно? Може би сте виждали следния синтаксис в по-стари скриптове:
<?php
$foo[bar] = 'враг';
echo $foo[bar];
// etc
?>
Това е погрешно, но работи. Защо тогава все пак е погрешно? Причината е, че този код използва недефинирана константа (bar), а не низ ('bar' - забележете апострофите) и в бъдеще е възможно PHP да дефинира константи, които за нещастие на кода ви, да имат същото име. Това работи, защото PHP автоматично преобразува голия низ (не-апострофиран низ, който не отговаря на нито един известен символ) в низ, съдържащ голия низ. Например ако няма дефинирана константа bar, PHP ще сложи на нейно място низа 'bar' и ще използва него.
Забележка: Това не означава, че трябва винаги да апострофирате ключа. Не трябва да апострофирате ключове, които са константи или променливи, тъй като това ще попречи на PHP да ги интерпретира.
<?php
error_reporting(E_ALL);
ini_set('display_errors', true);
ini_set('html_errors', false);
// Прост масив:
$array = array(1, 2);
$count = count($array);
for ($i = 0; $i < $count; $i++) {
echo "\nПроверка $i: \n";
echo "Неправилно: " . $array['$i'] . "\n";
echo "Правилно: " . $array[$i] . "\n";
echo "Неправилно: {$array['$i']}\n";
echo "Правилно: {$array[$i]}\n";
}
?>Примерът по-горе ще изведе:
Проверка 0: Notice: Undefined index: $i in /path/to/script.html on line 9 Неправилно: Правилно: 1 Notice: Undefined index: $i in /path/to/script.html on line 11 Неправилно: Правилно: 1 Проверка 1: Notice: Undefined index: $i in /path/to/script.html on line 9 Неправилно: Правилно: 2 Notice: Undefined index: $i in /path/to/script.html on line 11 Неправилно: Правилно: 2
Още илюстриращи примери:
<?php
// Let's show all errors
error_reporting(E_ALL);
$arr = array('fruit' => 'apple', 'veggie' => 'carrot');
// Правилно
print $arr['fruit']; // apple
print $arr['veggie']; // carrot
// Неправилно. Това работи, но също така хвърля грешка в PHP от ниво
// E_NOTICE, заради недефинирана константа fruit
//
// Notice: Use of undefined constant fruit - assumed 'fruit' in...
print $arr[fruit]; // apple
// Нека дефинираме константа, за да демонстрираме какво става. Ще
// присвоим стойност 'veggie' на константа fruit.
define('fruit', 'veggie');
// Забележете разликата сега
print $arr['fruit']; // apple
print $arr[fruit]; // carrot
// Следното е наред, защото е вътре в низ. В низовете не се търсят константи,
// така че няма да има грешка от ниво E_NOTICE.
print "Hello $arr[fruit]"; // Hello apple
// С едно изключение. Фигурните скоби заобикалящи масиви в низове, позволяват
// намирането на константи.
print "Hello {$arr[fruit]}"; // Hello carrot
print "Hello {$arr['fruit']}"; // Hello apple
// Това няма да работи, ще предизвика синтактична грешка подобна на:
// Parse error: parse error, expecting T_STRING' or T_VARIABLE' or T_NUM_STRING'
// Разбира се, това се отнася също и за употребата на свръхглобални в низове.
print "Hello $arr['fruit']";
print "Hello $_GET['foo']";
// Същото може да бъде постигнато и чрез съединяване
print "Hello " . $arr['fruit']; // Hello apple
?>
В случай, че повишите нивото на error_reporting() до E_NOTICE (например, задавайки го на ниво E_ALL), ще можете да видите тези грешки. По подразбиране нивото на error_reporting е такова, че да не ги показва.
Както беше споменато и в раздел синтаксис, между квадратните скоби ('[' и ']') трябва да има израз. Това означава, че бихте могли да пишете неща подобни на това:
<?php
echo $arr[somefunc($bar)];
?>
Това е пример за използване на стойност, върната от функция, като индекс на масив. PHP също разбира и от константи, както може би сте забелязали в случая с тези от вида E_*.
<?php
$error_descriptions[E_ERROR] = "Настъпи фатална грешка";
$error_descriptions[E_WARNING] = "PHP изведе предупреждение";
$error_descriptions[E_NOTICE] = "Това е просто информиращо съобщение";
?>
Забележете, че E_ERROR също е валиден индентификатор, също както bar в първия пример. Последният пример всъщност е идентичен на следното:
<?php
$error_descriptions[1] = "Настъпи фатална грешка";
$error_descriptions[2] = "PHP изведе предупреждение";
$error_descriptions[8] = "Това е просто информиращо съобщение";
?>
понеже E_ERROR е равно на 1, и т.н.
Както вече обяснихме по-горе, $foo[bar] работи, но е погрешно. Работи, понеже се очаква bar, заради синтаксиса си, да бъде константен израз. В този случай, обаче, не съществува константа с името bar. Тогава PHP приема, че сте имали предвид литерала bar, като низа "bar", но че сте забравили да напишете кавичките.
В даден момент от бъдещето е възможно екипът на PHP да реши да добави нова константа или ключова дума, или пък вие да решите да добавите константа в собственото си приложение и в този случай се оказвате в беда. Например, вече не можете да използвате думите empty и default по този начин, защото те са специални запазени ключови думи.
Забележка: Да повторим, в рамките на низ, ограден от кавички, е валидно да не заграждате индексите на масивите с апострофи - така "$foo[bar]" е валидно. Вижте горните примери за причините, както и разделът за синтактичен разбор на променливи в низ.
За всеки от типовете: integer (цяло число), float (плаващ), string (низ), boolean (булев) или resource (ресурс), ако преобразувате стойност в масив ще получите масив с единствен елемент (с индекс 0), който е скаларната стойност, която сте подали.
Ако преобразувате обект в масив ще получите свойствата (член-променливите) на обекта като елементи на масива. Ключовете са имената на член-променливите, с някои изключния: частните (private) променливи ще имат добавено името на класа пред името на променливата; защитените (protected) променливи ще имат добавено "*" пред името на променливата. Тези допълнителни стойности имат null байт от двете страни. Това би могло да доведе до неочаквани резултати.
<?php
class A {
private $A; // Това ще стане '\0A\0A'
}
class B extends A {
private $A; // Това ще стане '\0B\0A'
public $AA; // Това ще стане 'AA'
}
var_dump((array) new B());
?>
В горния пример ще изглежда, че има два ключа 'AA', въпреки че единият от тях всъщност е '\0A\0A'.
Ако преобразувате стойността NULL в масив ще получите празен масив.
Можете да сравнявате масиви посредством array_diff() или чрез някой от операторите за масиви.
Типът масив в PHP е много гъвкав, така че ето няколко примера, които да демонстрират пълната мощ на масивите.
<?php
// това
$a = array( 'color' => 'red',
'taste' => 'sweet',
'shape' => 'round',
'name' => 'apple',
4 // ключът ще бъде 0
);
// е абсолютно еквивалентно на
$a['color'] = 'red';
$a['taste'] = 'sweet';
$a['shape'] = 'round';
$a['name'] = 'apple';
$a[] = 4; // ключът ще бъде 0
$b[] = 'a';
$b[] = 'b';
$b[] = 'c';
// ще създаде масив array(0 => 'a' , 1 => 'b' , 2 => 'c'),
// или просто array('a', 'b', 'c')
?>
Example #1 Употреба на array()
<?php
// асоциативен масив
$map = array( 'version' => 4,
'OS' => 'Linux',
'lang' => 'english',
'short_tags' => true
);
// цифрови ключове
$array = array( 7,
8,
0,
156,
-10
);
// това е същото като array(0 => 7, 1 => 8, ...)
$switching = array( 10, // ключ = 0
5 => 6,
3 => 7,
'a' => 4,
11, // ключ = 6 (най-големият целочислен индекс беше 5)
'8' => 2, // ключ = 8 (целочислен!)
'02' => 77, // ключ = '02'
0 => 12 // стойността 10 ще бъде заменена от 12
);
// празен масив
$empty = array();
?>
Example #2 Колекция
<?php
$colors = array('red', 'blue', 'green', 'yellow');
foreach ($colors as $color) {
echo "Do you like $color?\n";
}
?>
Примерът по-горе ще изведе:
Do you like red? Do you like blue? Do you like green? Do you like yellow?
Прякото променяне на стойности в масив е възможно след PHP 5 чрез подаването им по референция. Предишните версии се нуждаят от заобиколно решение:
Example #3 Колекция
<?php
// PHP 5
foreach ($colors as &$color) {
$color = strtoupper($color);
}
unset($color); /* осигуряване, че последващо писане в
$color няма да промени последния елемент на масива */
// заобикаляне за по-стари версии
foreach ($colors as $key => $color) {
$colors[$key] = strtoupper($color);
}
print_r($colors);
?>
Примерът по-горе ще изведе:
Array
(
[0] => RED
[1] => BLUE
[2] => GREEN
[3] => YELLOW
)
Този пример създава масив, започвайки с ключ едно.
Example #4 Едно-базиран индекс
<?php
$firstquarter = array(1 => 'January', 'February', 'March');
print_r($firstquarter);
?>
Примерът по-горе ще изведе:
Array
(
[1] => 'January'
[2] => 'February'
[3] => 'March'
)
Example #5 Попълване на масив
<?php
// пълнене на масив с всички неща от дадена директория
$handle = opendir('.');
while (false !== ($file = readdir($handle))) {
$files[] = $file;
}
closedir($handle);
?>
Масивите са подредени. Можете също да променяте реда с помощта на някоя подреждаща функции. Вижте раздел функции за масиви за повече информация. Можете да получите броя на елементите в масив с функцията count().
Example #6 Подреждане на масив
<?php
sort($files);
print_r($files);
?>
Тъй като стойността на масив може да бъде всякаква, то съответно тя може да бъде и друг масив. По този начин можете да правите рекурсивни и многомерни масиви.
Example #7 Рекурсивни и многомерни масиви
<?php
$fruits = array ( "fruits" => array ( "a" => "orange",
"b" => "banana",
"c" => "apple"
),
"numbers" => array ( 1,
2,
3,
4,
5,
6
),
"holes" => array ( "first",
5 => "second",
"third"
)
);
// някои примери за достъп до масива по-горе
echo $fruits["holes"][5]; // отпечатва "second"
echo $fruits["fruits"]["a"]; // отпечатва "orange"
unset($fruits["holes"][0]); // премахва "first"
// създаване на нов много-измерен масив
$juices["apple"]["green"] = "good";
?>
Трябва да сте наясно, че присвояването в масиви винаги става с копиране по стойност. Това също означава, че вътрешният масивен указател, използван от current() и подобните й функции, се изчиства. За да копирате масив по референция, трябва да използвате референтния оператор.
<?php
$arr1 = array(2, 3);
$arr2 = $arr1;
$arr2[] = 4; // $arr2 е променен,
// $arr1 е все още array(2, 3)
$arr3 = &$arr1;
$arr3[] = 4; // сега $arr1 и $arr3 са едно и също
?>
За да създадете нов обект, използвайте инструкцията new, така че да инициализирате клас.
<?php
class foo
{
function do_foo()
{
echo "Doing foo.";
}
}
$bar = new foo;
$bar->do_foo();
?>
За пълно описание, моля прочетете раздел Класове и обекти.
Ако обект бъде преобразуван в обект, то той няма да бъде променен. Ако стойност от кой да е друг тип бъде преобразувана в обект, то се създава нова инстанция на вградения клас stdClass. Ако стойността е била NULL, новата инстанция ще бъде празна. Масив ще се преобразува в обект със свойства, именувани според ключовете на масива и със съответните им стойности. Всяка друга стойност ще бъде налична в член-променливата с име scalar.
<?php
$obj = (object) 'ciao';
echo $obj->scalar; // извежда 'ciao'
?>
Ресурсът е специална променлива, която държи референция към външен източник. Ресурсите се създават и биват използвани посредством специални функции. Вижте приложението за списък с всички тези функции и съответните ресурсни типове.
Забележка: Типът ресурс беше въведен в PHP 4
Вж. също get_resource_type().
Тъй като ресурсите държат специални манипулатори към отворени файлове, връзки към бази от данни, изображения и т.н., преобразуването на каквато и да е стойност в ресурс не е възможно.
Благодарение на системата за броене на референции, въведена в Zend Engine на PHP 4, случаи, в които няма останали референции към даден ресурс, се откриват автоматично (също като в Java). В този случай всички източници, които са били използвани от този ресурс, се освобождават от боклукчията (garbage collector). Затова, рядко се налага паметта да бъде освобождавана ръчно, посредством някоя функция от рода free_result.
Забележка: Постоянните връзки към бази от данни са специални - те не се унищожават от боклукчията. Вижте и раздела относно постоянни връзки.
Специалната стойност NULL обозначава, че променливата няма стойност. NULL е единствената възможна стойност от тип NULL.
Забележка: Типът null беше въведен в PHP 4.
Променливата се счита за NULL ако
й е била присвоена константата NULL.
все още не е установена в никаква стойност.
е била изчистена с unset().
mixed обозначава, че даден параметър може да приема множество (но не непременно всички) типове.
gettype() например приема всички типове в PHP, докато str_replace() приема само низове и масиви.
number обозначава, че параметърът може да бъде или цяло (integer) или плаващо (float) число.
Някои функции като call_user_func() или usort() приемат като параметър потребителски-дефинирани функции за обратно извикване. Последните могат да бъдат не само прости функции, но също и методи на обекти, включително и статични такива.
Функцията в PHP просто се предава с името си под формата на низ. Можете да предавате коя да е вградена или потребителски-дефинирана функция. Забележете, че езикови конструкции като array(), echo(), empty(), eval(), exit(), isset(), list(), print() и unset() не могат да бъдат извикани с обратно извикване.
Метод на инстанцииран обект се предава като масив, съдържащ обекта като елемент с индекс 0 и името на метода като елемент с индекс 1.
Статичните методи на клас също могат да бъдат предавани, без да е необходимо да се инстанциира обект от този клас, чрез предаването на името на класа, вместо обекта, за елемента с индекс 0.
Освен обикновените потребителски-дефинирани функции, create_function() може да бъде изполозвана, за да се създаде анонимна функция за обратно извикване.
Example #1 Примери за функции с обратно извикване
<?php
// Примерна функция за обратно извикване
function my_callback_function() {
echo 'hello world!';
}
// Примерен метод за обратно извикване
class MyClass {
static function myCallbackMethod() {
echo 'Hello World!';
}
}
// Тип 1: Просто извикване
call_user_func('my_callback_function');
// Тип 2: Извикване на статичен метод от клас
call_user_func(array('MyClass', 'myCallbackMethod'));
// Тип 3: Извикване на метод от обект
$obj = new MyClass();
call_user_func(array($obj, 'myCallbackMethod'));
// Тип 4: Извикване на статичен метод от обект (От PHP 5.2.3)
call_user_func('MyClass::myCallbackMethod');
// Тип 5: Относително извикване на статичен метод (От PHP 5.3.0)
class A {
public static function who() {
echo "A\n";
}
}
class B extends A {
public static function who() {
echo "B\n";
}
}
call_user_func(array('B', 'parent::who')); // A
?>
Забележка: В PHP4, ще трябва да използвате референция, за да създадете обратно извикване, което да сочи към самия обект, а не към копие от него. За повече информация вижте Референции.
void във връщания тип означава, че връщаната стойност е безполезна. void в списъка с параметри означава, че функцията не приема никакви параметри.
$... в прототипа на функция означава и така нататък. Това име на променлива се използва, когато функцията може да приеме неограничен брой аргументи.
PHP не изисква (и не поддържа) изрично дефиниране на тип при декларирането на променлива; типът на променливата зависи от контекста, в който се използва. С други думи, ако присвоите низова стойност на променливата $var , $var става низ. Ако в последствие присвоите целочислена стойност на $var , то тя става цяло число.
Пример за автоматичното преобразуване на типове в PHP е операторът за събиране '+'. Ако кой да е от операндите е плаващо число, то всички операнди се изчисляват като плаващи и резултатът ще бъде отново плаващо число. В противен случай операндите ще бъдат интерпретирани като цели числа и резултатът също ще бъде цяло число. Забележете, че това НЕ променя типа на самите операнди; единствената промяна е в начина, по който те се изчисляват.
<?php
$foo = "0"; // $foo е низ (ASCII 48)
$foo += 2; // сега $foo е цяло число (2)
$foo = $foo + 1.3; // сега $foo е плаващо (3.3)
$foo = 5 + "10 Little Piggies"; // $foo е цяло число (15)
$foo = 5 + "10 Small Pigs"; // $foo е цяло число (15)
?>
Ако предните два примера изглеждат неясни, разгледайте Превръщане на низ в число.
Ако желаете изрично да накарате променлива да се изчисли като даден тип, вижте раздела за Преобразуване на типове. Ако желаете да промените типа на променлива, вижте settype().
Ако искате да изпробвате някой от примерите в този раздел, можете да използвате функцията var_dump().
Забележка: Поведението при автоматично преобразуване в масив за момента не е дефинирано.
Също, понеже PHP поддържа индексирането в низове чрез отместване посредством същия синтаксис като индексирането в масиви, следното е в сила за всички версии на PHP:<?php
$a = 'car'; // $a е низ
$a[0] = 'b'; // $a продължава да бъде низ
echo $a; // bar
?>
Вижте раздел Достъп до знаците в низ за повече информация.
Преобразуването на типове в PHP работи доста подобно на това в C: името на желания тип се поставя в скоби преди променливата, която трябва да бъде преобразувана.
<?php
$foo = 10; // $foo е цяло число
$bar = (boolean) $foo; // $bar е от булев тип
?>
Разрешените преобразувания са:
(binary) преобразуването и бъдещата поддръжка на представката b бяха добавени в PHP 5.2.1
Забележете, че табулациите и интервалите са разрешени вътре в скобите, така че следните са функционално еквивалентни:
<?php
$foo = (int) $bar;
$foo = ( int ) $bar;
?>
Преобразуване на буквени низове и променливи в двоични низове:
<?php
$binary = (binary)$string;
$binary = b"binary string";
?>
Забележка: Вместо да преобразувате променлива в низ, можете да я заградите с кавички.
<?php
$foo = 10; // $foo е целочислена
$str = "$foo"; // $str е низ
$fst = (string) $foo; // $fst също е низ
// Това отпечатва, че "те са едни и същи"
if ($fst === $str) {
echo "те са едни и същи";
}
?>
Възможно е резултатът от преобразуването между някои типове да не е съвсем очевиден. За повече информация, вижте тези раздели:
Променливите в PHP се представят чрез знака за долар, последван от името на променливата. Името на променливата е чувствително към регистъра.
Имената на променливите следват същите правила като другите етикети в PHP. Валидното име на променлива започва с буква или подчертавка, последвана от произволен брой букви, цифри или подчертавки. Като регулярен израз, това би могло да бъде представено така: '[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*'
Забележка: В случая, под буква се разбират a-z, A-Z и байтовете от 127 до 255 (0x7f-0xff).
Забележка: $this е специална променлива, която не може да бъде присвоявана.
Вж. също Userland Naming Guide.
За информация относно функциите, свързани с променливи, вижте Справочник на функциите за променливи.
<?php
$var = 'Bob';
$Var = 'Joe';
echo "$var, $Var"; // извежда "Bob, Joe"
$4site = 'not yet'; // невалидно; започва с цифра
$_4site = 'not yet'; // валидно; започва с подчертавка
$tдyte = 'mansikka'; // валидно; 'д' е (Разширен) ASCII 228.
?>
По подразбиране променливите винаги се присвояват по стойност. С други думи, когато присвоявате израз на променлива, цялата стойност на оригиналния израз се копира в променливата. Това означава, например, че след присвояване стойността на една променлива на друга, променянето на една от тези променливи няма да се отрази на другата. За повече информация относно този тип присвояване, вижте главата за Изрази.
PHP също предлага и още един начин за присвояване на стойности на променливи: присвояване по референция. Това означава, че новата променлива просто указва (с други думи, "става псевдоним на" или "сочи към") оригиналната променлива. Промени в новата променлива влияят на оригиналната и обратно.
За да присвоите променлива по референция, просто сложете амперсанд (&) в началото на променливата, която се присвоява (променливата - източник). Например, следващото парче код извежда 'My name is Bob' два пъти:
<?php
$foo = 'Bob'; // Присвояване на стойността 'Bob' на $foo
$bar = &$foo; // Указване на $foo чрез $bar. (Присвояване по референция)
$bar = "My name is $bar"; // Променяне на $bar...
echo $bar;
echo $foo; // $foo е променена също.
?>
Важно нещо за отбелязване е, че само именувани променливи могат да бъдат присвоявани по референция.
<?php
$foo = 25;
$bar = &$foo; // Това е валидно присвояване.
$bar = &(24 * 7); // Невалидно; указва безименен израз.
function test()
{
return 25;
}
$bar = &test(); // Невалидно.
?>
Инициализирането на променливите в PHP не е необходимо, но все пак е добра практика то да се прави. Неинициализираните променливи имат стойност по подразбиране според типа им в зависимост от контекста, в който се използват - булевите имат стойност по подразбиране FALSE, целочислените и плаващите - нула, низовете (напр. използваните в echo()) се установяват в празен низ, а масивите - в празен масив.
Example #1 Стойности по подразбиране на неинициализирани променливи
<?php
// Неинициализирана И нереферирана (без контекст) променлива; извежда NULL
var_dump($unset_var);
// Употреба на булеви; извежда 'false' (Вж. третичния оператор за повече относно синтаксиса)
echo($unset_bool ? "true\n" : "false\n");
// Употреба на низове; извежда 'string(3) "abc"'
$unset_str .= 'abc';
var_dump($unset_str);
// Употреба на целочислени; извежда 'int(25)'
$unset_int += 25; // 0 + 25 => 25
var_dump($unset_int);
// Употреба на плаващи/двойна точност; извежда 'float(1.25)'
$unset_float += 1.25;
var_dump($unset_float);
// Употреба на масиви; извежда array(1) { [3]=> string(3) "def" }
$unset_arr[3] = "def"; // array() + array(3 => "def") => array(3 => "def")
var_dump($unset_arr);
// Употреба на обекти; създава нов обект от stdClass (вж. http://www.php.net/manual/en/reserved.classes.php)
// Извежда: object(stdClass)#1 (1) { ["foo"]=> string(3) "bar" }
$unset_obj->foo = 'bar';
var_dump($unset_obj);
?>
Да се разчита на стойностите по подразбиране на неинициализирана променлива е проблемно в случай на включване (include) на един файл в друг, който използва същото име на променлива. Това също представлява и значителен риск за сигурността с включена директива register_globals. В случай на работа с неинициализирани променливи се извежда грешка от ниво E_NOTICE, освен в случаите на добавяне на елементи към неициализиран масив. За установяване дали дадена променлива е била инициализирана може да се използва езиковата конструкция isset().
PHP предоставя голям брой предварително-дефинирани променливи във всеки скрипт, който пуска. Много от тези променливи, обаче, не могат да бъдат напълно документирани, тъй като те са зависими от това кой сървър работи, версията и устройството на сървъра, както и от други фактори. Някои от тези променливи няма да бъдат налични, когато PHP се пусне на командния ред. За списък с тези променливи, моля вижте раздела в Запазени предварително-дефинирани променливи.
От PHP 4.2.0 стойността по подразбиране на директивата register_globals в PHP е off (изключено). Това е значителна промяна в PHP. register_globals бидейки off влияе на набора от предварително-дефинирани порменливи, налични в глобалната област на действие. Например, за да вземете DOCUMENT_ROOT ще използвате $_SERVER['DOCUMENT_ROOT'] вместо $DOCUMENT_ROOT, или $_GET['id'] от URL-а http://www.example.com/test.php?id=3 вместо $id, или $_ENV['HOME'] вместо $HOME.
За информация, свързана с тази промяна, прочетете конфигурационната точка за register_globals, главата по сигурността в Използване на регистриране на глобални , също както и PHP съобщенията към изданията на » 4.1.0 и » 4.2.0.
Използването на наличните запазени предварително-дефинирани променливи в PHP, като свръхглобалните масиви, е за предпочитане.
От версия 4.1.0 нататък PHP предоставя допълнителен набор от предварително-дефинирани масиви, съдържащи променливи от уеб сървъра (ако е приложимо), от обкръжението, и от потребителския вход. Тези нови масиви са по-специални с това, че са автоматично глобални, т.е. автоматично налични във всеки обхват. Поради тази причина, те често биват познавани като "свръхглобални" (superglobals). (Няма механизъм в PHP за потребителски дефинирани свръхглобални променливи.) Свръхглобалните променливи са изброени по-долу; все пак, за списък с тяхното съдържание и по-нататъшна дискусия за предварително-дефинираните променливи в PHP и тяхната същност, моля вижте раздела Запазени предварително-дефинирани променливи. Също, ще забележите, че старите предварително-дефинирани променливи ($HTTP_*_VARS) все още съществуват. От PHP 5.0.0, дългите PHP предварително-дефинираните променливи могат да бъдат изключени посредством register_long_arrays директивата.
Забележка: Променливи променливи
Свръхглобалните не могат да бъдат използвани като променливи променливи във функции или методи на клас.
Забележка: Макар че и двете - свръхглобалните и HTTP_*_VARS, могат да съществуват едновременно, те не са идентични, така че модифицирането на едното няма да промени другото.
Ако някои променливи в variables_order не са зададени, съответните им PHP предварително-дефинирани масиви също остават празни.
Област на действие или обхват (scope) на променлива е контекстът, в който тя е дефинирана. На повечето места променливите в PHP имат само една област на действие. Тази единствена област на действие се разпростира също и във включените и в изискваните файлове. Например:
<?php
$a = 1;
include 'b.inc';
?>
Тук променливата $a ще бъде налична във включения скрипт b.inc. В рамките на потребителски-дефинирани функции, обаче, се въвежда локална област на действие. Всяка променлива, използвана вътре във функция, по подразбиране е ограничена в локалната област на действие на функцията. Например:
<?php
$a = 1; /* глобална област на действие */
function test()
{
echo $a; /* референция към променлива от локалната област на действие */
}
test();
?>
Този скрипт няма да изведе нищо, защото изразът echo се отнася за локална версия на променливата $a, а тя няма присвоена стойност в тази област на действие. Вероятно забелязвате, че това е малко по-различно от езика C с това, че в C променливите са налични автоматично във функциите, освен ако не са отменени от локална дефиниция. Това може да създаде проблеми, тъй като човек може по невнимание да промени глобална променлива. В PHP глобалните променливи трябва да бъдат декларирани като глобални вътре в дадена функция, ако ще бъдат използвани в тази функция.
Първо, примерна употреба на global:
Example #1 Употреба на global
<?php
$a = 1;
$b = 2;
function Sum()
{
global $a, $b;
$b = $a + $b;
}
Sum();
echo $b;
?>
Горният скрипт ще изведе "3". Декларирайки $a и $b като глобални за функцията, всички референции към променливите ще сочат към глобалната версия. Няма ограничение в броя на глобалните променливи, които могат да бъдат манипулирани от функция.
Вторият начин за достъп до променливи от глобалния обхват е да се използва специалния масив $GLOBALS в PHP. Предният пример може да бъде пренаписан така:
Example #2 Използване на $GLOBALS вместо global
<?php
$a = 1;
$b = 2;
function Sum()
{
$GLOBALS['b'] = $GLOBALS['a'] + $GLOBALS['b'];
}
Sum();
echo $b;
?>
$GLOBALS е асоциативен масив, в който името на глобалната променлива е ключът, а съдържанието на тази променлива е стойността на елемента от масива. Забележете, че $GLOBALS е наличен във всяка област на действие, a това е така, тъй като $GLOBALS е свръхглобален. Ето пример, демонстриращ възможностите на свръхглобалните:
Example #3 Пример, показващ свръхглобални и обхват
<?php
function test_global()
{
// Повечето предварително-дефинирани променливи не са "super" и изискват
// 'global', за да бъдат налични в локалния обхват на функция.
global $HTTP_POST_VARS;
echo $HTTP_POST_VARS['name'];
// Свръхглобалните са налични във всеки обхват и
// не изискват 'global'. Свръхглобалните са налични
// от PHP 4.1.0, и сега HTTP_POST_VARS се
// смята за непрепоръчителен.
echo $_POST['name'];
}
?>
Друга важна особеност на обхвата на променливите е статичната променлива. Статичната променлива съществува единствено в локалната област на действие на функцията, но не губи стойността си, когато изпълнението на програмата напусне тази област. Разгледайте следния пример:
Example #4 Пример, показващ нуждата от статични променливи
<?php
function test()
{
$a = 0;
echo $a;
$a++;
}
?>
Тази функция е напълно безполезна, тъй като всеки път, когато бива извикана, тя установява $a в 0 и отпечатва "0". Изразът $a++ , който инкрементира променливата, е безсмислен, понеже в момента, в който функцията излезе, променливата $a изчезва. За да направим полезна брояща функция, която да не губи представа за текущата сума, променливата $a се дефинира като статична:
Example #5 Примерна употреба на статични променливи
<?php
function test()
{
static $a = 0;
echo $a;
$a++;
}
?>
Тук $a се инициализира само при първото извикване на функцията и при всяко следващо извикване на test(), тя ще отпечатва стойността на $a и ще я инкрементира.
Статичните променливи предоставят също и начин за работа с рекурсивни функции. Рекурсивна функция е такава, която извиква сама себе си. Трябва да се внимава при писане на рекурсивна функция, защото е възможно тя да бъде принудена да се самоизвиква до безкрайност. Трябва да се уверите, че имате подходящ начин за спиране на рекурсията. Следната проста функция брои рекурсивно до 10, използвайки статичната променлива $count, за да разбере кога да спре:
Example #6 Статични променливи с рекурсивни функции
<?php
function test()
{
static $count = 0;
$count++;
echo $count;
if ($count < 10) {
test();
}
$count--;
}
?>
Забележка: Статичните променливи могат да бъдат декларирани, както в примерите по-горе. Опитът да се присвоят стойности на тези променливи, които са резултат от изрази, ще причини грешка в разбора (parse error).
Example #7 Деклариране на статични променливи
<?php
function foo(){
static $int = 0; // правилно
static $int = 1+2; // грешно (тъй като е израз)
static $int = sqrt(121); // грешно (тъй като също е израз)
$int++;
echo $int;
}
?>
Zend Engine 1, управляваща PHP 4, реализира static и global модификаторите за променливи от гледна точка на референции. Например, истинска глобална променлива, внесена в обхвата на функция посредством израза global, в действителност създава референция към глобалната променлива. Това може да доведе до неочаквано поведение, за което става дума и в следващия пример:
<?php
function test_global_ref() {
global $obj;
$obj = &new stdclass;
}
function test_global_noref() {
global $obj;
$obj = new stdclass;
}
test_global_ref();
var_dump($obj);
test_global_noref();
var_dump($obj);
?>
Изпълнението на този пример ще изведе следното:
Подобно поведение е в сила и за израза static. Референциите не се пазят статично:
<?php
function &get_instance_ref() {
static $obj;
echo 'Static object: ';
var_dump($obj);
if (!isset($obj)) {
// Присвояване на референция на статичната променлива
$obj = &new stdclass;
}
$obj->property++;
return $obj;
}
function &get_instance_noref() {
static $obj;
echo 'Static object: ';
var_dump($obj);
if (!isset($obj)) {
// Присвояване на обект на статичната променлива
$obj = new stdclass;
}
$obj->property++;
return $obj;
}
$obj1 = get_instance_ref();
$still_obj1 = get_instance_ref();
echo "\n";
$obj2 = get_instance_noref();
$still_obj2 = get_instance_noref();
?>
Изпълнението на този пример ще изведе следното:
Този пример показва, че когато присвоявате референция на статична променлива, при извикването на функцията &get_instance_ref() за втори път, тя не е запомнена.
Понякога е удобно да можем да имаме променливи имена на променливи. Това означава - име на променлива, което може да бъде установявано и използвано динамично. Обикновената променлива се установява посредством израз като:
<?php
$a = 'hello';
?>
Променливата променлива взима стойността на променлива и разглежда тази стойност като име на променлива. В горния пример hello може да бъде използвано за име на променлива с помощта на два доларови знака. Т.е.
<?php
$$a = 'world';
?>
В този момент са дефинирани и съхранени две променливи в символното дърво на PHP: $a със съдържание "hello" и $hello със съдържание "world". Следователно, следният израз:
<?php
echo "$a ${$a}";
?>
ще изведе абсолютно същото като:
<?php
echo "$a $hello";
?>
т.е. и двата извеждат: hello world.
За да използвате променливи променливи с масиви, трябва да разрешите една двусмисленост. А именно, когато напишете $$a[1], синтактичният анализатор трябва да знае дали сте искали да използвате $a[1] като променлива, или сте искали $$a като променлива и [1] като индекс от тази променлива. Синтаксисът за разрешаване на тази двусмисленост е: ${$a[1]} за първия случай и ${$a}[1] за втория.
Моля забележете, че променливите променливи не могат да бъдат използвани със Свръхглобалните масиви на PHP вътре във функции или методи на клас. Освен това променливата $this е специална променлива, която не може да бъде достъпвана динамично.
Когато се предаде формуляр към PHP скрипт, автоматично информацията от този формуляр става достъпна в скрипта. Има много начини за осъществяване на достъп до тази информация, например:
Example #1 Прост HTML формуляр
<form action="foo.php" method="post">
Name: <input type="text" name="username" /><br />
Email: <input type="text" name="email" /><br />
<input type="submit" name="submit" value="Submit me!" />
</form>
В зависимост от вашата дистрибуция, настройки и лични предпочитания, има много начини да осъществявате достъп до данните от вашите HTML формуляри. Ето някои примери:
Example #2 Достъпване на данни от прост POST HTML формуляр
<?php
// Налично от PHP 4.1.0
echo $_POST['username'];
echo $_REQUEST['username'];
import_request_variables('p', 'p_');
echo $p_username;
// След PHP 6 не са налични. От PHP 5.0.0, тези дълги предварително-дефинирани
// променливи могат да бъдат изключвани посредством директивата register_long_arrays.
echo $HTTP_POST_VARS['username'];
// Налично, ако PHP директивата register_globals = on. От
// PHP 4.2.0 стойността по подразбиране на register_globals = off.
// Използването/уповаването на този метод е непрепоръчително.
echo $username;
?>
Изполването на GET формуляр е подобно, с изключение на това, че ще използвате подходящата GET предварително-дефинирана променлива. GET също се отразява и в QUERY_STRING (информацията след '?' в URL). Така че, например http://www.example.com/test.php?id=3 съдържа GET данни, които са достъпни посредством$_GET['id']. Вж. също $_REQUEST и import_request_variables().
Забележка: Свръхглобални масиви, като $_POST и $_GET, станаха налични в PHP 4.1.0
Както показахме, преди PHP 4.2.0 стойността по подразбиране на register_globals беше on. Общността на PHP насърчава всички да не разчитат на тази директива, тъй като е за предпочитане да се приеме, че тя е off и да кодират по съответния начин.
Забележка: Конфигурационната директива magic_quotes_gpc влияе върху Get, Post и Cookie стойностите. Ако е включена, стойността (It's "PHP!") автоматично ще се преобразува в (It\'s \"PHP!\"). Необходимо е избягване при вкарване в база данни. Вж. също addslashes(), stripslashes() и magic_quotes_sybase.
PHP също приема и масиви в контекста на променливи от формуляр. (вж. faq в тази връзка). Например, можете да групирате свързаните променливи заедно, или да използвате това свойство, за да получите стойности, въведени чрез множествен (multiple) select. Нека, например, да изпратим формуляр към него си и при предаването му да извеждаме данните:
Example #3 По-сложни формулярни променливи
<?php
if ($_POST) {
echo '<pre>';
echo htmlspecialchars(print_r($_POST, true));
echo '</pre>';
}
?>
<form action="" method="post">
Име: <input type="text" name="personal[name]" /><br />
E-mail: <input type="text" name="personal[email]" /><br />
Бира: <br />
<select multiple name="beer[]">
<option value="shumensko">Шуменско</option>
<option value="kamenitza">Каменица</option>
<option value="zagorka">Загорка</option>
</select><br />
<input type="submit" value="Изпрати ме!" />
</form>
Когато предавате формуляр, можете да използвате изображение вместо предаващ бутон, посредством таг от типа:
<input type="image" src="image.gif" name="sub" />
Когато потребителят щракне някъде по изображението, придружаващият формуляр ще бъде предаден на сървъра с две допълнителни променливи, sub_x и sub_y. Те съдържат координатите на потребителското щракване върху изображението. По-опитните от вас може би са забелязали, че действителните имена на променливите, изпратени от браузъра, съдържат точки, а не подчертавки, но PHP автоматично превръща точката в подчертавка.
В повечето случаи, PHP не променя имената на променливите, когато биват предадени на скрипт. Трябва да бъде отбелязано обаче, че точката не е валиден знак за име на променлива в PHP. Поради тази причина, прегледайте:
<?php
$varname.ext; /* невалидно име на променлива */
?>
Сега, това което синтактичният анализатор вижда е променлива с име $varname, последвана от оператора за съединяване на низове, последван от голия низ (низ извън кавички, който не съвпада с никой известен ключ или запазена дума) 'ext'. Очевидно, това няма да даде желания резултат.
Поради тази причина е важно да се отбележи, че PHP автоматично ще замести всички точки в постъпващите променливи с подчертавки.
Тъй като PHP установява типовете на променливите и ги преобразува (обикновено) ако е необходимо, не винаги е очевидно от какъв тип е дадена променлива във всеки един момент. PHP включва няколко функции, които откриват от какъв тип е променливата, като: gettype(), is_array(), is_float(), is_int(), is_object() и is_string(). Вж. също глава Типове.
Константата е индентификатор (име) за проста стойност. Както подсказва и името, тази стойност не може да се променя по време на изпълнение на скрипта (с изключение на вълшебните константи, които всъщност не са константи). Константата е чувствителна към регистъра (case-sensitive) по подразбиране. Неписано правило е константните индентификатори да се пишат винаги с главни букви.
Имената на константите следват същите правила като другите етикети в PHP. Валидното име на константа започва с буква или подчертавка, последвана от произволен брой букви, цифри или подчертавки. Като регулярен израз, това би могло да бъде представено така: [a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*
Вж. също Userland Naming Guide.
Example #1 Валидни и невалидни имена на константи
<?php
// Валидни имена на константи
define("FOO", "нещо");
define("FOO2", "нещо друго");
define("FOO_BAR", "нещо в повече");
// Невалидни имена на константи
define("2FOO", "нещо");
// Това е валидно, но трябва да се избягва:
// Възможно е някой ден PHP да предостави вълшебна константа,
// която ще счупи скрипта ви
define("__FOO__", "нещо");
?>
Забележка: В случая, под буква се разбират a-z, A-Z, и ASCII знаците от 127 до 255 (0x7f-0xff).
Както и за superglobals, константата има глобална област на действие. Можете да достъпвате константи където и да е във вашия скрипт без оглед на контекста. За повече информация относно обхват и контекст, прочетете раздел Област на действие на променливи.
Можете да дефинирате константа посредством функциятаdefine() или чрез ключовата дума const извън дефиницията на клас, от PHP 5.3.0. Веднъж дефинирана, константата никога повече не може да бъде променяна или отменяна.
В константи могат да се съхраняват единствено скаларни данни (boolean, integer, float и string). По принцип е възможно да дефинирате и данни от тип resource, но това трябва да бъде избягвано, тъй като може да доведе до неочаквани резултати.
Можете да вземете стойността на константа като просто укажете името й. За разлика от променливите, пред константа не трябва да слагате $. Можете също да използвате функцията constant(), за да получите стойността на константа, в случай, че желаете да получите името на константата динамично. За списък с всички дефинирани константи, използвайте get_defined_constants().
Забележка: Константите и (глобалните) променливи са в различни пространства от имена (namespaces). Това означава, че TRUE и $TRUE обикновено са различни.
Ако използвате недефинирана константа, PHP приема, че имате предвид името на самата константа, също както ако сте я извикали като string (CONSTANT и "CONSTANT"). Когато това се случи, ще бъде изведена грешка от ниво E_NOTICE. Вижте също раздела, в който се повдига въпросът защо $foo[bar] е погрешно (освен ако преди това не сте дефинирали с define() bar като константа). Ако просто искате да проверите дали дадена константа е дефинирана, използвайте функцията defined().
Това са разликите между константи и променливи:
Example #1 Дефиниране на константи
<?php
define("CONSTANT", "Здравей свят.");
echo CONSTANT; // извежда "Здравей свят."
echo Constant; // извежда "Constant" и пуска съобщение (notice).
?>
Example #2 Дефиниране на константи посредством ключовата дума const
<?php
// Работи от PHP 5.3.0
const CONSTANT = 'Здравей свят';
echo CONSTANT;
?>
Вж. също Класови константи.
PHP предоставя голям брой предварително-дефинирани константи във всеки скрипт, който изпълнява. Много от тези константи, все пак, са създадени от различни разширения и ще бъдат налични единствено, в случай че тези разширения са налични, било то чрез динамично зареждане или защото са били компилирани.
Има седем вълшебни константи, които се променят според мястото, на което се използват. Например, стойността на __LINE__ зависи от реда, на който се използва в скрипта ви. Тези специални константи не са чувствителни към регистъра и са както следва:
| Име | Описание |
|---|---|
| __LINE__ | Текущия номер на реда във файла. |
| __FILE__ | Пълния път и име на файла. Ако се използва вътре във включен (include) файл, ще бъде върнато името на включвания файл. След PHP 4.0.2, __FILE__ винаги съдържа абсолютен път с разпънати символни връзки, докато в по-стари версии, при определени обстоятелства, съдържаше относителен път. |
| __DIR__ | Директорията на файла. Ако се използва вътре във включен (include) файл, ще бъде върната директорията на включвания файл. Това е равносилно на dirname(__FILE__). Това име на директория няма последваща наклонена черта, освен ако не е коренната директория. (Добавена в PHP 5.3.0.) |
| __FUNCTION__ | Името на функцията. (Това беше добавено в PHP 4.3.0) След PHP 5 тази константа връща името на функцията така, както е била дефинирана (чувствително към регистъра). В PHP 4 стойността й винаги е с малки букви. |
| __CLASS__ | Името на класа. (Това беше добавено в PHP 4.3.0) След PHP 5 тази константа връща името на класа така, както е бил дефиниран (чувствително към регистъра). В PHP 4 стойността му винаги е с малки букви. |
| __METHOD__ | Името на метода. (Това беше добавено в PHP 5.0.0) Връща името на метода така, както е бил дефиниран (чувствително към регистъра). |
| __NAMESPACE__ | Името на текущото пространство от имена (чувствително към регистъра). Тази константа се дефинира по време на компилация (Добавена в PHP 5.3.0). |
Вж. също get_class(), get_object_vars(), file_exists() и function_exists().
Изразите са най-важните градивни елементи на PHP. Почти всичко, което пишете в PHP, е израз. Най-простият и точен начин да се дефинират изразите е "всичко, което има стойност".
Най-простите форми на изрази са константите и променливите. Когато напишете "$a = 5", вие присвоявате '5' на $a. '5', очевидно има стойност 5, или с други думи, '5' е израз със стойността 5 (в този случай '5' е целочислена константа).
След това присвояване, бихте очаквали стойността на $a да бъде също 5, така че би трябвало $b = $a да работи по същия начин като $b = 5. С други думи, $a също става израз със стойност 5. Ако всичко работи правилно, ще се случи точно това.
Малко по-сложен пример за изрази са функциите. Например, да вземем следната функция:
<?php
function foo ()
{
return 5;
}
?>
Ако приемем, че сте наясно с концепцията за функциите (ако не сте, вижте главата за функции), би трябвало да предположите, че $c = foo() е по същество същото като $c = 5, и ще сте прави. Функциите са изрази със стойност - стойността която връщат. Тъй като foo() връща 5, стойността на израза 'foo()' е 5. Обикновено, функциите не просто връщат статична стойност, а изчисляват нещо.
Разбира се, не е задължително стойностите в PHP да са целочислени и в много случаи те не са. PHP поддържа четири скаларни типа стойности: целочислени стойности, стойности с плаваща запетая (плаващи), низови стойности и булеви стойности (скаларни стойности са такива стойности, които не могат да бъдат 'счупени' на по-малки парчета, както масивите, например). PHP също поддържа два съставни (не-скаларни) типа: масиви и обекти. Всеки един от тези типове стойности може да бъде присвояван на променливи или връщан от функции.
PHP навлиза много по-дълбоко в изразите, както правят и много други езици. PHP е изразно-ориентиран език, в смисъл, че почти всичко е израз. Да вземем примера, който вече разгледахме - '$a = 5'. Лесно е да се види, че в случая има две замесени стойности - стойността на целочислената константа '5' и стойността на $a, която се променя на 5. Но истината е, че тук има замесена още една допълнителна стойност и това е стойността на самото присвояване. Самото присвояване се изчислява на присвоената стойност, която в случая е 5. На практика, това означава, че '$a = 5', независимо от това, което прави, е израз със стойност 5. Така че, писането на нещо като '$b = ($a = 5)' е същото като да напишеш '$a = 5; $b = 5;' (точката и запетаята обозначават край на инструкция). Понеже присвояванията се предават от дясно на ляво, можете също да напишете '$b = $a = 5'.
Друг добър пример за изразна ориентираност са предварителното и последващото инкрементиране и декрементиране. Потребителите на PHP и на много други езици вероятно са запознати с нотацията променлива++ и променлива--. Това са операторите за инкрементиране и декрементиране. В PHP/FI 2, инструкцията '$a++' няма стойност (не е израз), и затова не можете да я присвоите или използвате по никакъв начин. PHP увеличава възможностите на инкрементирането и декрементирането като ги прави също изрази, като в C. В PHP, както в C, има два типа инкрементиране - предварително и последващо. И двете всъщност увеличават стойността на променливата с единица и ефектът върху променливата е един и същ. Разликата е в стойността на инкременталния израз. Предварителното инкрементиране, което се пише '++$променлива', се изчислява на увеличената стойност (PHP инкрементира променливата преди да е прочел стойността й, от там и името 'предварително инкрементиране'). Последващото инкрементиране, което се пише '$променлива++' се изчислява на първоначалната стойност на $променлива, преди да бъде инкрементирана (PHP инкрементира променливата след като е прочел стойността й, от там и името 'последващо инкрементиране').
Широко разпространен тип изрази са изразите за сравнение. Тези изрази се изчисляват или на FALSE или на TRUE. PHP поддържа > (по-голямо), >= (по-голямо или равно), == (равно), != (различно), < (по-малко) и <= (по-малко или равно). Езикът също поддържа набор от стриктни оператори за еквивалентност: === (равно и от същия тип) и !== (различно или не от същия тип). Тези изрази най-често се използват при условно изпълнение, като инструкцията if.
Последният пример за изрази, с който ще се занимаваме, е изразът за операторно присвояване. Вече знаете, че за да увеличите $a с 1, можете просто да напишете '$a++' или '++$a'. Но какво ако искате да добавите повече от единица, например 3? Бихте могли да напишете '$a++' няколко пъти, но това очевидно не е много ефикасен и удобен начин. Много по-разпространена практика е да се напише '$a = $a + 3'. '$a + 3' се изчислява на стойността на $a плюс 3, и се присвоява обратно на $a, което увеличава $a с 3. В PHP, както и в много други езици като C, можете да напишете това по-съкратено, което с времето би трябвало да стане също и по-изчистено и по-разбираемо. Добавянето на 3 към текущата стойност на $a може да се напише така: '$a += 3'. Това буквално означава "вземи стойността на $a, добави 3 към нея и я присвои обратно на $a". Освен че е по-късо и по-изчистено, това също е и по-бързо за изпълнение. Стойността на '$a += 3', също като стойността на обикновено присвояване, е присвояваната стойност. Отбележете, че тя НЕ е 3, а комбинираната стойност от $a плюс 3 (това е стойността, която се присвоява на $a). Всички двуместни оператори могат да бъдат използвани в този операторно-присвоителен режим, например '$a -= 5' (изваждане на 5 от стойността на $a), '$b *= 7' (умножаване стойността на $b със 7) и т.н.
Има още един израз, който може би изглежда странно, ако не сте го виждали досега в други езици - третичния оператор:
<?php
$first ? $second : $third
?>
Ако стойността на първия под-израз е TRUE (не-нула), тогава се изчислява вторият под-израз и това е резултатът на условния израз. В противен случай се изчислява третият под-израз и това е стойността.
Следващият пример би трябвало да ви помогне да разберете по-добре предварителното и последващото инкрементиране и изразите като цяло:
<?php
function double($i)
{
return $i*2;
}
$b = $a = 5; /* присвояване на стойността пет на променливите $a и $b */
$c = $a++; /* последващо инкрементиране, присвояване на първоначалната стойност на $a
(5) на $c */
$e = $d = ++$b; /* предваричелно инкрементиране, присвояване на инкрементираната стойност на
$b (6) на $d и $e */
/* в този момент, и $d и $e са равни на 6 */
$f = double($d++); /* присвояване на удвоената стойност на $d преди инкрементирането
2*6 = 12 на $f */
$g = double(++$e); /* присвояване на удвоената стойност на $e след инкрементирането
2*7 = 14 на $g */
$h = $g += 10; /* първо, $g се увеличава с 10 като се получава стойността 24.
след това, стойността на присвояването (24) се
присвоява на $h, и така $h получава също стойност 24. */
?>
Някои изрази могат да бъдат използвани като инструкции. В този случаи, инструкцията е във формат 'израз' ';', т.е. израз последван от точка и запетая. В '$b=$a=5;', $a=5 е валиден израз, но сам по себе си не е инструкция. '$b=$a=5;', обаче, е валидна инструкция.
Едно последно нещо за споменаване е истинната стойност на изразите. При много събития, главно при условно изпълнение и при цикли, не се интересувате от специфичната стойност на израза, а само дали означава TRUE или FALSE. Константите TRUE (истина) и FALSE (неистина) (нечувствителни към регистъра) са двете възможни булеви стойности. Когато е необходимо, изразът автоматично се преобразува в булев тип. Вж. разделът за преобразуване на типове за подробности как става това.
PHP предлага пълна и мощна реализация на изразите и пълното им документиране излиза извън обхвата на това ръководство. Горните примери би трябвало да са ви дали добра представа за това какво са изразите и как да създавате полезни изрази. В останалата част на това ръководство ще пишем expr, за да обозначим валиден израз в PHP.
Операторът е нещо, на което се подават една или повече стойности (или изрази, казано на програмистки език), и който дава като резултат друга стойност (така че конструкцията сама по себе си да стане израз). С други думи, можете да считате функциите или конструкциите, които връщат стойност (като print), за оператори, а тези, които не връщат нищо (като echo) - за всичко останало.
Съществуват три типа оператори. Първият тип са унарните оператори, които оперират върху една единствена стойност, например ! (оператора за отрицание) или ++ (оператора за инкрементация). Втората група са двоичните оператори; тази група съдържа повечето оператори, които поддържа PHP, и списък с тях следва по-долу в раздела Приоритет на операторите.
Третата група е третичния оператор: ?:. Той трябва да бъде използван при избор между два израза, зависещи от трети израз, а не при избор между две изречения или два пътя на изпълнение. Заграждането на третичните изрази със скоби е много добра идея.
Приоритетът на операторите описва колко "плътно" даден оператор свързва два израза. Например, в израза 1 + 5 * 3 отговорът е 16, а не 18, защото операторът за умножение ("*") има по-висок приоритет от оператора за събиране ("+"). Ако е необходимо, могат да бъдат използвани скоби, за да се укаже изрично приоритет. Например: (1 + 5) * 3 се изчислява на 18. Ако два оператора имат еднакъв приоритет се използва асоциативност отляво надясно.
Следната таблица описва приоритета на операторите, като операторите с най-висок приоритет са най-отгоре. Операторите на един и същи ред имат еднакъв приоритет, в който случай редът им на изчисление зависи от съответната им асоциативност.
| Асоциативност | Оператори | Допълнителна информация |
|---|---|---|
| без асоциативност | clone new | clone и new |
| лява | [ | array() |
| без асоциативност | ++ -- | инкрементиране/декрементиране |
| без асоциативност | ~ - (int) (float) (string) (array) (object) (bool) @ | типове |
| без асоциативност | instanceof | типове |
| дясна | ! | логически |
| лява | * / % | аритметични |
| лява | + - . | аритметични и низови |
| лява | << >> | побитови |
| без асоциативност | < <= > >= <> | сравнителни |
| без асоциативност | == != === !== | сравнителни |
| лява | & | побитови и референции |
| лява | ^ | побитови |
| лява | | | побитови |
| лява | && | логически |
| лява | || | логически |
| лява | ? : | третични |
| дясна | = += -= *= /= .= %= &= |= ^= <<= >>= | присвоителни |
| лява | and | логически |
| лява | xor | логически |
| лява | or | логически |
| лява | , | множество употреби |
Лява асоциативност означава, че изразът се изчислява отляво надясно, дясна асоциативност - обратното.
Example #1 Асоциативност
<?php
$a = 3 * 3 % 5; // (3 * 3) % 5 = 4
$a = true ? 0 : true ? 1 : 2; // (true ? 0 : true) ? 1 : 2 = 2
$a = 1;
$b = 2;
$a = $b += 3; // $a = ($b += 3) -> $a = 5, $b = 5
?>
Използвайте скоби, за да увеличите прегледността на кода.
Забележка: Въпреки че = има по-нисък приоритет от повечето останали оператори, PHP позволява изрази като този: if (!$a = foo()), в който случай изходът на foo() се присвоява на $a.
Спомняте ли си началната аритметика от училище? Тези работят точно по същия начин.
| Пример | Наименование | Резултат |
|---|---|---|
| -$a | Отрицание | Противоположното на $a. |
| $a + $b | Събиране | Сумата на $a и $b. |
| $a - $b | Изваждане | Разликата между $a и $b. |
| $a * $b | Умножение | Произведението на $a и $b. |
| $a / $b | Деление | Частното на $a и $b. |
| $a % $b | Остатък от деление | Остатъкът от $a делено на $b. |
Операторът за деление ("/") връща стойност с плаваща запетая, освен ако двата операнда са цели числа (или низове, които са били превърнати в цели числа) и числата се делят без остатък, в който случай ще бъде върната целочислена стойност.
Операндите на остатък от деление (%) се преобразуват в цели числа (чрез изрязване на десетичната част) преди операцията.
Забележка: Остатъкът от $a % $b е отрицателен за отрицателни $a.
Разгледайте също страницата от ръководството за Математически функции.
Основният оператор за присвояване е "=". Първото ви предположение за него би могло да бъде "равно на". Не трябва. Той всъщност означава, че на левия операнд се присвоява стойността от израза на десния.
Стойността на присвоителния израз е и стойността, която бива присвоявана. Така че стойността на "$a = 3" е 3. Това ви позволява да правите някои хитри неща:
<?php
$a = ($b = 4) + 5; // $a е равно на 9, а на $b е присвоена стойност 4.
?>
Освен основния присвоителен оператор, съществуват и "комбинирани оператори" за всички оператори за двоична аритметика, обединение на масиви и низове, които ви позволяват да използвате стойности в изрази и след това да присвоявате резултата от тези изрази. Например:
<?php
$a = 3;
$a += 5; // присвоява 8 на $a, както ако бяхме казали: $a = $a + 5;
$b = "Ей, ти ";
$b .= "там!"; // присвоява на $b "Ей, ти там!", също както $b = $b . "там!";
?>
Забележете, че присвояването копира оригиналната стойност на новата стойност (присвояване по стойност), така че промените върху едната няма да се отразят на другата. Това би могло да бъде от значение, в случаите когато трябва да копирате неща като големи масиви в тежък цикъл. Присвояването по референция също се поддържа, посредством синтаксиса $var = &$othervar;. 'Присвояването по референция' означава, че и двете променливи сочат към едни и същи данни и нищо не се копира никъде. За да научите повече за референциите, прочетете Обяснение на референциите. След PHP 5, обектите се присвояват по референция, освен ако изрично е указано друго с новата ключова дума clone.
Побитовите оператори ви позволяват да променяте определени битове в целите числа. Ако и левият и десният параметър са низове, побитовият оператор ще оперира с ASCII стойностите на съответния символ.
<?php
echo 12 ^ 9; // Извежда '5'
echo "12" ^ "9"; // Извежда символа за изтриване (Backspace) (ascii 8)
// ('1' (ascii 49)) ^ ('9' (ascii 57)) = #8
echo "hallo" ^ "hello"; // Извежда ASCII стойностите #0 #4 #0 #0 #0
// 'a' ^ 'e' = #4
echo 2 ^ "3"; // Извежда 1
// 2 ^ ((int)"3") == 1
echo "2" ^ 3; // Извежда 1
// ((int)"2") ^ 3 == 1
?>
| Пример | Наименование | Резултат |
|---|---|---|
| $a & $b | И (And) | Вдигат се битовете, които са установени и в $a и в $b. |
| $a | $b | Или (Or) | Вдигат се битовете, които са установени или в $a или в $b. |
| $a ^ $b | Изключващо или (Xor) | Вдигат се битовете, които са установени само в $a или само в $b, но не и в двете едновременно. |
| ~ $a | Не (Not) | Вдигат се битовете, които не са установени в $a, и обратното - тези, които са установени, се свалят. |
| $a << $b | Преместване наляво (Shift left) | Преместване битовете на $a с $b позиции наляво (всяка позиция означава "умножение по две") |
| $a >> $b | Преместване надясно (Shift right) | Преместване битовете на $a с $b позиции наляво (всяка позиция означава "деление на две") |
Не премествайте надясно повече от 32 бита на 32-битови системи. Също, не премествайте наляво в случай, че резултатът ще бъде число по-дълго от 32 бита.
Сравнителните оператори, както подсказва и името им, ви позволяват да сравнявате две стойности. Вероятно бихте били заинтересувани да видите и таблицата със сравнение на типовете, тъй като там има примери със сравнения, свързани с типовете.
| Пример | Наименование | Резултат |
|---|---|---|
| $a == $b | Равно | TRUE ако $a е равна на $b. |
| $a === $b | Идентично | TRUE ако $a е равна на $b и ако са от един и също тип. (въведено в PHP 4) |
| $a != $b | Не-равно | TRUE ако $a не е равна на $b. |
| $a <> $b | Не-равно | TRUE ако $a не е равна на $b. |
| $a !== $b | Не-идентично | TRUE ако $a не е равна на $b или ако не са от един и същи тип. (въведено в PHP 4) |
| $a < $b | По-малко | TRUE ако $a е строго по-малка от $b. |
| $a > $b | По-голямо | TRUE ако $a е строго по-голяма от $b. |
| $a <= $b | По-малко или равно | TRUE ако $a е по-малка или равна на $b. |
| $a >= $b | По-голямо или равно | TRUE ако $a е по-голяма или равна на $b. |
В случай, че сравнявате цяло число с низ, низът бива преобразуван в число. Ако пък сравнявате два цифрови низа, те биват сравнявани като цели числа. Тези правила са в сила също и за инструкцията switch.
<?php
var_dump(0 == "a"); // 0 == 0 -> true
var_dump("1" == "01"); // 1 == 1 -> true
var_dump("1" == "1e0"); // 1 == 1 -> true
switch ("a") {
case 0:
echo "0";
break;
case "a": // никога не се достига, тъй като "a" вече е съвпаднала с 0
echo "a";
break;
}
?>
За различните типове сравнението се извършва съгласно следната таблица (по ред).
| Тип на Операнд 1 | Тип на Операнд 2 | Резултат |
|---|---|---|
| null или string | string | Преобразува NULL в "", цифрово или лексикално сравнение |
| bool или null | всякакъв | Преобразува до bool, FALSE < TRUE |
| object | object | Вградените класове могат да дефинират техни собствени сравнения, различните класове са несравними, еднаквите класове - сравняват свойствата по същия начин както масивите (PHP 4), PHP 5 има свое собствено обяснение |
| string, resource или number | string, resource или number | Преобразува низовете и ресурсите до числа, обикновена математика |
| array | array | Масив с по-малко елементи е по-малък, ако даден ключ от първия операнд не бъде намерен във втория, тогава масивите са несравними, иначе - сравнява стойност по стойност (по-долния пример) |
| array | всякакъв | Масивът винаги е по-голям |
| object | всякакъв | Обектът винаги е по-голям |
Example #1 Транскрипция на стандартното сравнение на масиви
<?php
// Масивите биват сравнявани посредством стандартни оператори за сравнение, по следния начин
function standard_array_compare($op1, $op2)
{
if (count($op1) < count($op2)) {
return -1; // $op1 < $op2
} elseif (count($op1) > count($op2)) {
return 1; // $op1 > $op2
}
foreach ($op1 as $key => $val) {
if (!array_key_exists($key, $op2)) {
return null; // несравняемо
} elseif ($val < $op2[$key]) {
return -1;
} elseif ($val > $op2[$key]) {
return 1;
}
}
return 0; // $op1 == $op2
}
?>
Вж. също strcasecmp(), strcmp(), Оператори за масиви и разделът от ръководството за Типове.
Друг условен оператор е "?:" (или третичния) оператор.
Example #2 Присвояване на стойност по подразбиране
<?php
// Примерна употреба на: Третичен Оператор
$action = (empty($_POST['action'])) ? 'default' : $_POST['action'];
// Горното е идентично на тази if/else конструкция
if (empty($_POST['action'])) {
$action = 'default';
} else {
$action = $_POST['action'];
}
?>
Изразът (expr1) ? (expr2) : (expr3) се изчислява на expr2 ако expr1 се изчисли на TRUE, и на expr3 в случай, че expr1 се изчисли на FALSE.
От PHP 5.3 нататък е възможно да пропуснете средната част на третичния оператор. Изразът expr1 ?: expr3 връща expr1 ако expr1 се изчисли на TRUE, и expr3 - иначе.
Забележка: Забележете, че третичният оператор е израз, и че той не се изчислява до променлива, а до резултата на израза. Това е важно да се знае, когато искате да върнете променлива по референция. Затова изразът return $var == 42 ? $a : $b; във функция, която връща по референция няма да работи и в по-късни версии на PHP ще бъде изведено предупреждение.
Забележка: Препоръчително е да избягвате "натрупването" на третични изрази. Поведението на PHP при използване на повече от един третичен оператор в рамките на един израз не е очевиден:
Example #3 Неясно третично поведение
<?php
// на пръв поглед, следното изглежда, че извежда 'true'
echo (true?'true':false?'t':'f');
// действителният изход, обаче, е 't'
// това е така, понеже третичните изрази се изчисляват от ляво на дясно
// следното е по-ясен вариант на същия код
echo ((true ? 'true' : 'false') ? 't' : 'f');
// в този случай може да видите, че първият израз се изчислява на 'true', което
// от своя страна се изчислява на (bool)true и така се връща истинното разклонение на
// втория третичен израз.
?>
PHP поддържа един оператор за контрол на грешки: символът at (@). Когато бъде поставен пред израз в PHP, всички съобщения за грешка, които биха били генерирани от този израз, ще бъдат пренебрегнати.
Ако свойството track_errors е включено, всички съобщения за грешка, генерирани от израза, ще бъдат запазени в променливата $php_errormsg. Тази променлива ще бъде презаписвана при всяка грешка, така че ако искате да я използвате трябва да я проверявате възможно най-рано.
<?php
/* Intentional file error */
$my_file = @file ('non_existent_file') or
die ("Несполучливо отваряне на файл: грешката беше '$php_errormsg'");
// това работи за всякакви изрази, не само за функции:
$value = @$cache[$key];
// няма да изведе съобщение (notice) ако ключът $key не съществува.
?>
Забележка: Операторът @ работи единствено върху изрази. Правилото е: ако можете да вземете стойността на нещо, то можете да поставите и оператора @ пред него. Например, можете да го слагате пред променливи, извиквания на функции и включвания посредством include(), пред константи, и т.н. Не можете да го поставяте пред дефиниции на функции или класове, или пред условни структури като if и foreach, и т.н.
Вж. също error_reporting() и раздела от ръководството Функции за обработка на грешки и дневници.
Понастоящем употребата на оператора за контрол на грешки "@" ще изключи отчитането на грешки дори и за критични грешки, които прекъсват изпълнението на скрипта. Това също означава, че ако използвате "@", за да подтиснете грешките от дадена функция, и ако последната не е налична или пък е написана погрешно, скриптът ще умре точно на това място без никаква индикация за причината.
PHP поддържа един оператор за изпълнение: обратни апострофи (``). Забележете, че това не са единични кавички! PHP ще опита да изпълни съдържанието на обратните апострофи като команда от обвивката; изходът ще бъде върнат (т.е. няма просто да бъде изкаран на изхода, а може да бъде присвоен на променлива). Употребата на този оператор е идентична на shell_exec().
<?php
$output = `ls -al`;
echo "<pre>$output</pre>";
?>
Забележка: Операторът обратни апострофи е изключен, когато е включен защитен режим или когато функцията shell_exec() е изключена.
Вж. също Функции за изпълнение на програми, popen() proc_open() и Употреба на PHP от командния ред.
PHP поддържа предварително и последващо-инкрементиращи и декрементиращи оператори в стил C.
Забележка: Операторите за инкрементиране (нарастване) и декрементиране (намаляване) не влияят на булеви стойности. Декрементирането на NULL стойности също няма ефект, но инкрементирането им дава резултат 1.
| Пример | Наименование | Ефект |
|---|---|---|
| ++$a | Предварително инкрементиране | Увеличава $a с едно, след което връща $a. |
| $a++ | Последващо инкрементиране | Връща $a, след което увеличава $a с едно. |
| --$a | Предварително декрементиране | Намалява $a с едно, след което връща $a. |
| $a-- | Последващо декрементиране | Връща $a, след което намалява $a с едно. |
Ето прост примерен скрипт:
<?php
echo "<h3>Последващо инкрементиране</h3>";
$a = 5;
echo "Би трябвало да бъде 5: " . $a++ . "<br />\n";
echo "Би трябвало да бъде 6: " . $a . "<br />\n";
echo "<h3>Предварително инкрементиране</h3>";
$a = 5;
echo "Би трябвало да бъде 6: " . ++$a . "<br />\n";
echo "Би трябвало да бъде 6: " . $a . "<br />\n";
echo "<h3>Последващо декрементиране</h3>";
$a = 5;
echo "Би трябвало да бъде 5: " . $a-- . "<br />\n";
echo "Би трябвало да бъде 4: " . $a . "<br />\n";
echo "<h3>Предварително декрементиране</h3>";
$a = 5;
echo "Би трябвало да бъде 4: " . --$a . "<br />\n";
echo "Би трябвало да бъде 4: " . $a . "<br />\n";
?>
PHP следва конвенцията на Perl, когато работи с аритметически операции върху символни променливи, а не тази на C. Например, в Perl 'Z'+1 се превръща в 'AA', докато в C 'Z'+1 се превръща в '[' ( ord('Z') == 90, ord('[') == 91 ). Забележете, че символните променливи могат да бъдат инкрементирани, но не и декрементирани и дори тогава се поддържат единствено знаци в чист ASCII (a-z и A-Z).
Example #1 Аритетмически операции върху символни променливи
<?php
$i = 'W';
for ($n=0; $n<6; $n++) {
echo ++$i . "\n";
}
?>
Примерът по-горе ще изведе:
X Y Z AA AB AC
Инкрементирането или декрементирането на булеви стойности няма ефект.
| Пример | Наименование | Резултат |
|---|---|---|
| $a and $b | И | TRUE ако и $a и $b са TRUE. |
| $a or $b | Или | TRUE ако $a или $b е TRUE. |
| $a xor $b | Изключващо или | TRUE ако или $a или $b е TRUE, но не и двете. |
| ! $a | Не | TRUE ако $a не е TRUE. |
| $a && $b | И | TRUE ако и $a и $b са TRUE. |
| $a || $b | Или | TRUE ако $a или $b е TRUE. |
Причината за съществуването на две разновидности на операторите "и" и "или" е, че те оперират с различен приоритет. (Вж. Приоритет на операторите.)
Example #1 Нагледно пояснение на логическите оператори
<?php
// foo() никога няма да бъде извикана, тъй като операторите водят до късо съединение
$a = (false && foo());
$b = (true || foo());
$c = (false and foo());
$d = (true or foo());
// "||" has има по-висок приоритет от "or"
$e = false || true; // на $e ще бъде присвоена стойността от израза (false || true), която е true
$f = false or true; // на $f ще бъде пристоена стойност false
var_dump($e, $f);
// "&&" има по-висок приоритет от "and"
$g = true && false; // на $g ще бъде присвоена стойността от израза (true && false), която е false
$h = true and false; // на $h ще бъде пристоена стойност true
var_dump($g, $h);
?>
Примерът по-горе ще изведе нещо подобно на:
bool(true) bool(false) bool(false) bool(true)
Съществуват два оператора за низове. Първият е операторът за съединяване ('.'), който връща свързването на левия и десния му аргумент. Вторият е съединително-присвоителният оператор ('.='), който прибавя аргумента от дясната страна на аргумента от лявата страна. Моля прочетете Оператори за присвояване за повече информация.
<?php
$a = "Здравей ";
$b = $a . "свят"; // сега $b съдържа "Здравей свят!"
$a = "Здравей ";
$a .= "свят!"; // сега $a съдържа "Здравей свят!"
?>
Вж. също разделите в ръководството за Тип низ и Низови функции.
| Пример | Наименование | Резултат |
|---|---|---|
| $a + $b | Обединение | Обединението на $a и $b. |
| $a == $b | Равенство | TRUE ако $a и $b имат едни и същи двойки ключ/стойност. |
| $a === $b | Идентичност | TRUE ако $a и $b имат едни и същи двойки ключ/стойност в един и същи ред и са от един и същи тип. |
| $a != $b | Неравенство | TRUE ако $a не е равно на $b. |
| $a <> $b | Неравенство | TRUE ако $a не е равно на $b. |
| $a !== $b | Неидентичност | TRUE ако $a не е идентично на $b. |
Операторът + добавя елементи от оставащите ключове на масива от дясната страна на този от лявата страна, при което дублиращите се ключове НЕ се презаписват.
<?php
$a = array("a" => "ябълка", "b" => "банан");
$b = array("a" => "круша", "b" => "ягода", "c" => "череша");
$c = $a + $b; // Обединенито на $a и $b
echo "Обединението на \$a и \$b: \n";
var_dump($c);
$c = $b + $a; // Обединението на $b и $a
echo "Обединението на \$b и \$a: \n";
var_dump($c);
?>
Когато бъде изпълнен, този скрипт ще отпечата следното:
Обединението на $a и $b:
array(3) {
["a"]=>
string(6) "ябълка"
["b"]=>
string(5) "банан"
["c"]=>
string(6) "череша"
}
Обединението на $b и $a:
array(3) {
["a"]=>
string(5) "круша"
["b"]=>
string(5) "ягода"
["c"]=>
string(6) "череша"
}
За целите на сравнението елементите на масивите се считат за равни ако имат едни и същи ключ и стойност.
Example #1 Сравняване на масиви
<?php
$a = array("ябълка", "банан");
$b = array(1 => "банан", "0" => "ябълка");
var_dump($a == $b); // bool(true)
var_dump($a === $b); // bool(false)
?>
Вж. също разделите от ръководството за Тип масив и Функции за масиви.
instanceof се използва, за да се установи дали дадена променлива в PHP представлява инстанцииран обект от определен клас:
Example #1 Употреба на instanceof с класове
<?php
class MyClass
{
}
class NotMyClass
{
}
$a = new MyClass;
var_dump($a instanceof MyClass);
var_dump($a instanceof NotMyClass);
?>
Примерът по-горе ще изведе:
bool(true) bool(false)
instanceof може също да се използва и за определяне дали променливата е инстанцииран обект от клас, който наследява родителския клас:
Example #2 Употреба на instanceof с наследени класове
<?php
class ParentClass
{
}
class MyClass extends ParentClass
{
}
$a = new MyClass;
var_dump($a instanceof MyClass);
var_dump($a instanceof ParentClass);
?>
Примерът по-горе ще изведе:
bool(true) bool(true)
За проверка дали даден обект не е инстанция на клас, може да се използва логическия оператор not.
Example #3 Употреба на instanceof за проверка дали даден обект не е инстанция на клас
<?php
class MyClass
{
}
$a = new MyClass;
var_dump(!($a instanceof stdClass));
?>
Примерът по-горе ще изведе:
bool(true)
Накрая, instanceof може също да се използва и за да се установи дали дадена променлива представлява инстанция на обект от клас, който осъществява интерфейс:
Example #4 Употреба на instanceof за клас
<?php
interface MyInterface
{
}
class MyClass implements MyInterface
{
}
$a = new MyClass;
var_dump($a instanceof MyClass);
var_dump($a instanceof MyInterface);
?>
Примерът по-горе ще изведе:
bool(true) bool(true)
Въпреки че instanceof обикновено се използва с буквеното име на класа, той също може да бъде използван и с друг обект или низова променлива:
Example #5 Употреба на instanceof с други променливи
<?php
interface MyInterface
{
}
class MyClass implements MyInterface
{
}
$a = new MyClass;
$b = new MyClass;
$c = 'MyClass';
$d = 'NotMyClass';
var_dump($a instanceof $b); // $b е обект от клас MyClass
var_dump($a instanceof $c); // $c е низа 'MyClass'
var_dump($a instanceof $d); // $d е низа 'NotMyClass'
?>
Примерът по-горе ще изведе:
bool(true) bool(true) bool(false)
Има няколко клопки, за които трябва да се внимава. Преди версия 5.1.0 на PHP instanceof ще извика __autoload() ако класът не съществува. Освен това, ако класът не е бил зареден, това ще доведе до фатална грешка. Това може да бъде заобиколено като се използва динамична референция към клас или низова променлива, съдържаща името на класа:
Example #6 Избягване търсенето на клас и фатални грешки с instanceof в PHP 5.0
<?php
$d = 'NotMyClass';
var_dump($a instanceof $d); // в случая фатална грешка няма
?>
Примерът по-горе ще изведе:
bool(false)
Операторът instanceof беше въведен в PHP 5. Преди това се използваше is_a(), но от тогава се препоръчва вместо него да се използва instanceof. От PHP 5.3.0 нататък is_a() вече не е непрепоръчителна.
Вж. също get_class() и is_a().
Всеки PHP скрипт се състои от поредици от инструкции. Инструкция може да бъде задаване на стойност, извикване на функция, цикъл, условен израз или дори инструкция, която не прави нищо (празен израз). Инструкциите обикновено завършват с точка и запетая. В допълнение, инструкциите могат и да бъдат групирани като групата от инструкции се загради във фигурни скоби. Групата от инструкции сама по себе си също представлява инструкция. В тази глава са описани различните видове инструкции.
Конструкцията if (ако) е едно от най-важните свойства на много езици, включително и на PHP. Тя позволява условно изпълнение на части от кода. PHP предоставя структура if, подобна на тази в C:
if (expr)
statement
Както е описано и в раздела за изразите, expression се изчислява до булевата си стойност. Ако expression се изчисли на TRUE, PHP ще изпълни statement, а ако се изчисли на FALSE - ще го пренебрегне. Повече информация относно това кои стойности се изчисляват на FALSE може да бъде намерена в раздела 'Превръщане в булев тип'.
Следващият пример ще изведе a е по-голямо от b ако $a е по-голяма от $b:
<?php
if ($a > $b)
echo "a е по-голямо от b";
?>
В много случаи ще искате условното изпълнение на повече от една инструкция. Разбира се, няма нужда да обвивате всеки израз с клауза if. Вместо това, можете да групирате няколко инструкции в група от инструкции. Например, този код ще изведе a е по-голямо от b ако $a е по-голяма от $b и след това ще присвои стойността на $a в $b:
<?php
if ($a > $b) {
echo "a е по-голямо от b";
$b = $a;
}
?>
Kонструкциите if могат да бъдат вмествани безкраен брой пъти в други конструкции if, което ви дава пълна гъвкавост за условното изпълнение на различни части от вашата програма.
В много случаи ще искате да изпълните една инструкция ако дадено условие е изпълнено и друга инструкция, ако условието не е изпълнено. Точно за това служи else (иначе). else разширява конструкцията if, като изпълнява инструкция в случай, че изразът в конструкцията if се изчисли на FALSE. Например, следният код ще изведе a е по-голямо от b ако $a е по-голяма от $b, или a НЕ е по-голямо от b - в противен случай:
<?php
if ($a > $b) {
echo "a е по-голямо от b";
} else {
echo "a НЕ е по-голямо от b";
}
?>
Конструкцията else се изпълнява само ако изразът if се е изчислил на FALSE и всички налични изрази elseif (ако има такива) са се изчислили също на FALSE (вж. elseif).
elseif, както подсказва и името й, е комбинация от if и else. Също както else, тя разширява конструкцията if така, че да изпълни различна инструкция, в случай че първоначалният израз if се е изчислил на FALSE. За разлика от else обаче тя ще изпълни този алтернативен израз само ако условният израз elseif се изчислява на TRUE. Например, следният код ще изведе a е по-голямо от b, a е равно на b или a е по-малко от b:
<?php
if ($a > $b) {
echo "a е по-голямо от b";
} elseif ($a == $b) {
echo "a е равно на b";
} else {
echo "a е по-малко от b";
}
?>
В рамките на една конструкция if може да има много изрази elseif. Първият израз elseif (ако има такъв), който се изчисли на TRUE ще бъде изпълнен. В PHP можете също да напишете и 'else if' (с две думи) и поведението му ще бъде идентично на 'elseif' (с една дума). Синтактичното значение е малко по-различно (ако сте запознати със C, тук е налице същото поведение), но последният ред е този, който и в двата случая ще има абсолютно същото поведение.
Конструкцията elseif се изпълнява само ако предшестващият израз if и всички предшестващи изрази elseif се изчислят на FALSE и текущият израз elseif се е изчислил на TRUE.
Забележка: Забележете, че elseif и else if ще бъдат разгледани като напълно еднакви, единствено когато се използват къдрави скоби, както в горния пример. Когато използвате двоеточие, за да дефинирате вашите условия if/elseif, не трябва да разделяте else if на две думи, в противен случай PHP ще се провали със синтактична грешка.
<?php
/* Неправилен метод: */
if($a > $b):
echo $a." е по-голямо от ".$b;
else if($a == $b): // Няма да се компилира.
echo "Горният ред предизвиква синтактична грешка.";
endif;
/* Правилен метод: */
if($a > $b):
echo $a." е по-голямо от ".$b;
elseif($a == $b): // Забележете комбинацията от думи.
echo $a." е равно на ".$b;
else:
echo $a." не е по-голямо или равно на ".$b;
endif;
?>
PHP предоставя алтернативен синтаксис за някои от контролните структури, а именно: if, while, for, foreach и switch. Във всички случаи, основната форма на алтернативния синтаксис се получава като се смени отварящата фигурна скоба на двоеточие и затварящата къдрава скоба съответно на endif;, endwhile;, endfor;, endforeach; или endswitch;.
<?php if ($a == 5): ?>
A е равно на 5
<?php endif; ?>
В горния пример, HTML блокът "A е равно на 5" е вложен в конструкция if, написана с алтернативния синтаксис. HTML блокът ще бъде изведен само ако $a е равна на 5.
Алтернативният синтаксис важи също и за else и elseif. Следващият пример представлява структурата if с elseif и else в алтернативен формат:
<?php
if ($a == 5):
echo "a е равно на 5";
echo "...";
elseif ($a == 6):
echo "a е равно на 6";
echo "!!!";
else:
echo "a не е нито 5, нито 6";
endif;
?>
Циклите while (докато) са най-простия тип цикъл в PHP. Те работят по същия начин както техния еквивалент в C. Основната форма на конструкцията while е:
while (expr)
statement
Смисълът на конструкцията while е прост. Тя казва на PHP да повтаря изпълнението на вложените конструкции, докато изразът while се изчислява на TRUE. Стойността на израза се проверява всеки път в началото на цикъла, така че дори и тази стойност да се промени докато се изпълняват вложените конструкции, изпълнението няма да спре докато не се достигне края на итерацията (всеки път, когато PHP пуска конструкциите в цикъла, е една итерация). В случай че изразът while се изчисли на FALSE от самото начало, вложените конструкции няма да бъдат пуснати нито веднъж.
Също както и с конструкцията if, можете да групирате множество конструкции в един и същи цикъл while като оградите групата от конструкции с фигурни скоби, или като използвате алтернативен синтаксис:
while (expr):
statement
...
endwhile;
Следните примери са идентични като и двата отпечатват числата от 1 до 10:
<?php
/* пример 1 */
$i = 1;
while ($i <= 10) {
echo $i++; /* отпечатаната стойност ще бъде
$i преди инкрементацията
(пост-инкрементация) */
}
/* пример 2 */
$i = 1;
while ($i <= 10):
echo $i;
$i++;
endwhile;
?>
Циклите do-while (прави-докато) са подобни на циклите while, с тази разлика, че вместо в началото, изразът за истинност се проверява в края на всяка итерация. Основната разлика от обикновените цикли while е, че първата итерация на цикъл do-while със сигурност ще се изпълни (условието се проверява единствено в края на итерацията), докато при циклите while не е задължително да се изпълни (условието се проверява в началото на всяка итерация, така че ако се изчисли на FALSE от самото начало, цикълът ще завърши незабавно).
Съществува само един синтаксис за цикли do-while:
<?php
$i = 0;
do {
echo $i;
} while ($i > 0);
?>
Горният цикъл ще се изпълни точно един път, тъй като след първата итерация, когато се провери условието, то ще се изчисли на FALSE ($i не е по-голяма от 0) и изпълненито на цикъла ще спре.
Напредналите програмисти на C може би са запознати с една друга употреба на цикъла do-while: в случай че трябва да се спре изпълнението в средата на блокове от код, те се заграждат с do-while (0) и се използва командата break. Следният фрагмент от код демонстрира това:
<?php
do {
if ($i < 5) {
echo "i не е достатъчно голямо";
break;
}
$i *= $factor;
if ($i < $minimum_limit) {
break;
}
echo "i е ОК";
/* работа с i */
} while (0);
?>
Не се притеснявате ако не разберете това веднага или изобщо никога. Можете да пишете скриптове и то мощни скриптове без да използвате това 'свойство'.
Циклите for (за) са най-сложните цикли в PHP. Те се държат по същия начин като техния еквивалент в C. Синтаксисът на цикъл for е:
for (expr1; expr2; expr3) statement
Първият израз (expr1) се изчислява (изпълнява) безусловно веднъж в началото на цикъла.
expr2 се изчислява в началото на всяка итерация. Ако се изчисли на TRUE, цикълът продължава и вложените команди се изпълняват. Ако се изчисли на FALSE, изпълнението на цикъла свършва.
expr3 се изчислява (изпълнява) в края на всяка итерация.
Всеки един от изразите може да бъде празен или да съдържа множество изрази, разделени със запетая. В expr2 се изчисляват всички изрази, разделени със запетая, но резултатът се взима само от последната част. Ако expr2 е празен, това означава, че цикълът ще се изпълнява безкрайно (PHP имплицитно го смята за TRUE, както C). Това би могло и да не бъде толкова безполезно, колкото може би ви се струва, тъй като в много случаи ще искате да прекъснете цикъла посредством команда break, вместо да изполвате истинния израз във for.
Разгледайте следните примери. Всички те извеждат числата от 1 до 10:
<?php
/* пример 1 */
for ($i = 1; $i <= 10; $i++) {
echo $i;
}
/* пример 2 */
for ($i = 1; ; $i++) {
if ($i > 10) {
break;
}
echo $i;
}
/* пример 3 */
$i = 1;
for (; ; ) {
if ($i > 10) {
break;
}
echo $i;
$i++;
}
/* пример 4 */
for ($i = 1, $j = 0; $i <= 10; $j += $i, print $i, $i++);
?>
Разбира се, първият пример изглежда най-добре (или може би четвъртият), но вероятно в много случаи ще оцените възможността за използване на празни изрази в цикли for за доста удобна.
PHP поддържа също и заместващия "двуеточен синтаксис" за цикли for.
for (expr1; expr2; expr3):
statement
...
endfor;
Често срещано сред потребителите е да обикалят през масивите като в примера по-долу.
<?php
/*
* Това е масив с данни, които искаме да променим,
* докато работи цикълът for.
*/
$people = Array(
Array('name' => 'Kalle', 'salt' => 856412),
Array('name' => 'Pierre', 'salt' => 215863)
);
for($i = 0; $i < sizeof($people); ++$i)
{
$people[$i]['salt'] = rand(000000, 999999);
}
?>
Проблемът е във втория израз на for. Този код може да бъде бавен, защото на всяка итерация трябва да изчисли размера на масива. Тъй като размерът не се променя никога, кодът може да бъде оптимизиран лесно посредством междинна променлива, в която да се съхрани размера и в цикъла да се използва тази променлива, вместо sizeof. По-долният пример илюстрира това:
<?php
$people = Array(
Array('name' => 'Kalle', 'salt' => 856412),
Array('name' => 'Pierre', 'salt' => 215863)
);
for($i = 0, $size = sizeof($people); $i < $size; ++$i)
{
$people[$i]['salt'] = rand(000000, 999999);
}
?>
В PHP 4 беше въведена конструкция foreach (за всеки), много наподобяваща тази в Perl и в някои други езици. Тя предоставя лесен начин за обхождане на масиви. foreach работи само с масиви и ще изведе грешка, ако се опитате да я използвате върху променлива от друг тип или върху неинициализирана променлива. Съществуват два синтаксиса; вторият е минимално, но полезно разширение на първия:
foreach (array_expression as $value) statement foreach (array_expression as $key => $value) statement
Първата форма обикаля през зададения от array_expression масив. При всяка итерация стойността на текущия елемент се присвоява на $value и вътрешният указател на масива се придвижва с единица (така че при следващата итерация, ще гледате следващия елемент).
Втората форма прави същото нещо, с тази разлика, че ключът на текущия елемент ще бъде присвоен на променливата $key при всяка итерация.
След PHP 5 е възможно също да обхождате и обекти.
Забележка: Когато foreach започва първоначалното си изпълнение, вътрешният указател на масива автоматично се нулира, така че да сочи към първия елемент на масива. Това означава, че няма нужда да извиквате reset() преди цикъл foreach.
Забележка: С изключение на случаите, в които масивът е указан с референция, foreach ще работи с копие от зададения масив, а не със самия масив. foreach има някои странични ефекти върху указателя на масива. Не разчитайте на указателя на масива по време или след изпълнението на foreach без да сте го изчистили изрично.
От PHP 5 нататък лесно можете да променяте елементите на даден масив като предшествате $value с &. Това ще присвои по референция, вместо да копира стойността.
<?php
$arr = array(1, 2, 3, 4);
foreach ($arr as &$value) {
$value = $value * 2;
}
// в този момент $arr е array(2, 4, 6, 8)
unset($value); // премахване референцията към последния елемент
?>
Това е възможно единствено, в случай че обхожданият масив може да бъде указван с референция (т.е. ако е променлива).
Референцията между $value и последния елемент от масива остава дори и след приключването на цикъла foreach. Препоръчително е да я унищожите посредством unset().
Забележка: foreach не поддържа възможността за подтискане на съобщения за грешка чрез използване на '@'.
Може би сте забелязали, че следните примери са функционално идентични:
<?php
$arr = array("едно", "две", "три");
reset ($arr);
while (list(, $value) = each ($arr)) {
echo "Стойност: $value<br />\n";
}
foreach ($arr as $value) {
echo "Стойност: $value<br />\n";
}
?>
Следните примери са също функционално идентични:
<?php
$arr = array("едно", "две", "три");
reset($arr);
while (list($key, $value) = each ($arr)) {
echo "Ключ: $key; Стойност: $value<br />\n";
}
foreach ($arr as $key => $value) {
echo "Ключ: $key; Стойност: $value<br />\n";
}
?>
Още няколко примера за демонстриране на употребата:
<?php
/* foreach пример 1: само стойност */
$a = array(1, 2, 3, 17);
foreach ($a as $v) {
echo "Текущата стойност на \$a: $v.\n";
}
/* foreach пример 2: value (нагледно, с отпечатване на ръчната нотация) */
$a = array(1, 2, 3, 17);
$i = 0; /* само за нагледни цели */
foreach ($a as $v) {
echo "\$a[$i] => $v.\n";
$i++;
}
/* foreach пример 3: ключ и стойност */
$a = array(
"едно" => 1,
"две" => 2,
"три" => 3,
"седемнадесет" => 17
);
foreach ($a as $k => $v) {
echo "\$a[$k] => $v.\n";
}
/* foreach пример 4: многомерни масиви */
$a = array();
$a[0][0] = "a";
$a[0][1] = "b";
$a[1][0] = "y";
$a[1][1] = "z";
foreach ($a as $v1) {
foreach ($v1 as $v2) {
echo "$v2\n";
}
}
/* foreach пример 5: динамични масиви */
foreach (array(1, 2, 3, 4, 5) as $v) {
echo "$v\n";
}
?>
break прекъсва изпълнението на текущата структура for, foreach, while, do-while или switch.
break приема незадължителен цифров параметър, който указва колко вложени заграждащи структури да бъдат прекъснати.
<?php
$arr = array('едно', 'две', 'три', 'четири', 'стоп', 'пет');
while (list (, $val) = each ($arr)) {
if ($val == 'стоп') {
break; /* Тук бихте могли да напишете също и 'break 1;'. */
}
echo "$val<br />\n";
}
/* Използване на незадължителния параметър. */
$i = 0;
while (++$i) {
switch ($i) {
case 5:
echo "В 5<br />\n";
break 1; /* Изход само от switch. */
case 10:
echo "В 10; излизане<br />\n";
break 2; /* Изход от switch и от while. */
default:
break;
}
}
?>
continue (продължи) се използва в циклични структури, за да се пропусне остатъка от текущата итерация и изпълнението да продължи в проверката на условието и след това в началото на следващата итерация.
Забележка: Забележете, че в PHP конструкцията switch се смята за циклична структура в контекста на continue.
continue приема незадължителен цифров параметър, който указва до края на колко нива на заграждащи цикли трябва да пропусне.
<?php
while (list ($key, $value) = each ($arr)) {
if (!($key % 2)) { // пропускане на нечетните членове
continue;
}
do_something_odd ($value);
}
$i = 0;
while ($i++ < 5) {
echo "Външен<br />\n";
while (1) {
echo " Среден<br />\n";
while (1) {
echo " Вътрешен<br />\n";
continue 3;
}
echo "Това никога няма да бъде изведено.<br />\n";
}
echo "Нито пък това.<br />\n";
}
?>
Пропускането на точката и запетаята след continue може да доведе до объркване. Ето пример за това какво не трябва да правите.
<?php
for ($i = 0; $i < 5; ++$i) {
if ($i == 2)
continue
print "$i\n";
}
?>
Някои ще очакват резултатът да бъде:
0 1 3 4
но скриптът ще изведе:
2
защото връщаната стойност от извикването на print() е int(1), а тя ще изглежда като незадължителния цифров параметър, споменат по-горе.
Kонструкцията switch (пренасочвам) наподобява поредица от конструкции IF върху един и същи израз. В много случаи, ще искате да сравните една и съща променлива (или израз) с много различни стойности и да изпълните различно парче код, в зависимост от това на коя стойност отговаря. Точно за това служи конструкцията switch.
Забележка: Забележете, че за разлика от някои други езици, инструкцията continue важи за switch и работи подобно на break. Ако имате switch вътре в цикъл и искате да продължите със следващата итерация на външния цикъл, използвайте continue 2.
Забележка: Забележете, че switch/case извършва свободно сравнение.
Следващите два примера представляват два различни начина да напишете едно и също нещо, едното чрез изполване на поредица от инструкции if и elseif, а другото - с конструкция switch:
Example #1 Структура switch
<?php
if ($i == 0) {
echo "i е равно на 0";
} elseif ($i == 1) {
echo "i е равно на 1";
} elseif ($i == 2) {
echo "i е равно на 2";
}
switch ($i) {
case 0:
echo "i е равно на 0";
break;
case 1:
echo "i е равно на 1";
break;
case 2:
echo "i е равно на 2";
break;
}
?>
Example #2 Структурата switch работи и с низове
<?php
switch ($i) {
case "ябълка":
echo "i е ябълка";
break;
case "круша":
echo "i е круша";
break;
case "кекс":
echo "i е кекс";
break;
}
?>
За да се избегнат грешки, е важно да се разбере как се изпълнява конструкцията switch. Тя се изпълнява ред по ред (всъщност, инструкция по инструкция). В началото не се изпълнява никакъв код. Чак когато се срещне инструкцията case (случай) със стойност, която да съвпада със стойността на израза switch, PHP започва да изпълнява инструкциите. PHP продължава да ги изпълнява докато не достигне края на switch блока, или до първия път, където види инструкция break. Ако не напишете инструкция break накрая на списъка с инструкции за текущия случай (case), PHP ще продължи с изпълнението на инструкциите в следващия случай. Например:
<?php
switch ($i) {
case 0:
echo "i е равно на 0";
case 1:
echo "i е равно на 1";
case 2:
echo "i е равно на 2";
}
?>
В случая, ако променливата $i е равна на 0, PHP ще изпълни всички инструкции echo! Ако $i е равна на 1, PHP ще изпълни последните две инструкции echo. Ще получите очакваното поведение (ще се изведе 'i е равно на 2') само ако $i е равна на 2. Следователно, е важно да не забравяте изразите break (дори и в случай, че искате да ги пропуснете умишлено при определени обстоятелства).
В конструкция switch условието се изчислява само веднъж и резултатът се сравнява с всяка клауза case. При elseif - условието се изчислява повторно. Ако условието ви е по-сложно от просто сравняване и/или е в тежък цикъл, switch ще бъде по-бърза.
Списъкът с инструкции за даден случай (case) може да бъде и празен, което просто предава управлението на списъка с инструкции в следващия случай.
<?php
switch ($i) {
case 0:
case 1:
case 2:
echo "i е по-малко от 3, но е неотрицателно";
break;
case 3:
echo "i е 3";
}
?>
Специален случай е случая default. Този случай съвпада с всичко, което не е било намерено от другите случаи. Например:
<?php
switch ($i) {
case 0:
echo "i е равно на 0";
break;
case 1:
echo "i е равно на 1";
break;
case 2:
echo "i е равно на 2";
break;
default:
echo "i не е равно нито на 0, нито на 1, нито на 2";
}
?>
Инструкцията case може да бъде всякакъв израз, който се изчислява до прост тип, т.е. цели числа, числа с плаваща запетая или низове. Масиви и обекти не могат да бъдат използвани в този случай, освен ако не се преобразуват до прост тип.
Алтернативният синтаксис за контролни структури се поддържа от switch. За повече информация погледнете Алтернативен синтаксис за контролни структури .
<?php
switch ($i):
case 0:
echo "i е равно на 0";
break;
case 1:
echo "i е равно на 1";
break;
case 2:
echo "i е равно на 2";
break;
default:
echo "i не е равно нито на 0, нито на 1, нито на 2";
endswitch;
?>
Възможно е да използвате точка и запетая вместо двоеточие след case така:
<?php
switch($beer)
{
case 'загорка';
case 'каменица';
case 'шуменско';
echo 'Добър избор';
break;
default;
echo 'Моля изберете отново...';
break;
}
?>
Конструкцията declare се използва за установяване на изпълними директиви за блокове от код. Синтаксисът на declare е подобен на този на другите конструкции за управление на потока:
declare (directive)
statement
Разделът directive позволява да се установява поведението на declare блок. Към момента се разпознават само две директиви: директивата ticks (вж. по-долу за повече информация относно директивата ticks) и директивата encoding (вж. по-долу за повече информация относно директивата encoding).
Забележка: Директивата encoding (кодировка) беше добавена в PHP 5.3.0
Частта statement от блока declare ще бъде изпълнена - как ще се изпълни и какви странични ефекти ще настъпят по време на изпълнението може да зависи от директивата указана в блока directive.
Конструкцията declare може също да се използва и в глобален обхват, като по този начин ще се отрази на целия код, който я следва (ако файлът с declare е бил включен (included), обаче, тя не повлиява родителския файл).
<?php
// тези са равносилни:
// можете да използвате това:
declare(ticks=1) {
// целия скрипт тук
}
// или да използвате това:
declare(ticks=1);
// целия скрипт тук
?>
Туптенето е непрепоръчително от PHP 5.3.0 и ще бъде премахнато в PHP 6.0.0.
Тупване (tick) е събитие, което се случва
на всеки N инструкции от ниско ниво,
изпълнени от синтактичния анализатор в declare блок.
Стойността на N се задава посредством
ticks=N
в рамките на directive на блока
declare.
Събитията, които се случват на всяко тупване, се задават посредством register_tick_function(). За повече подробности, вж. примера по-долу. Забележете, че за едно тупване, могат да настъпят повече от едно събития.
Example #1 Профил на част от PHP код
<?php
// Функция, която записва времето, когато е извикана
function profile($dump = FALSE)
{
static $profile;
// Връща времената, записани в профила и ги изтрива
if ($dump) {
$temp = $profile;
unset ($profile);
return $temp;
}
$profile[] = microtime ();
}
// Установяване на обработчик на туптене
register_tick_function("profile");
// Инициализиране на функцията преди деклариращия блок
profile();
// Пускане на блок от код, хвърляне на тупване на всеки втори израз
declare(ticks=2) {
for ($x = 1; $x < 50; ++$x) {
echo similar_text(md5($x), md5($x*$x)), "<br />;";
}
}
// Показване на данните, записани в профила
print_r(profile (TRUE));
?>
Примерът профилира PHP кода вътре в 'declare' блок, записвайки времето, в което всяка втора инструкция от ниско ниво в блока се изпълнява. След това, тази информация би могла да бъде използвана за откриване на бавни части в дадени откъси код. Тази операция може да бъде изпълнена и посредством други методи, но чрез използване на туптене е най-подходящо и лесно за осъществяване.
Туптенето е подходящо за откриване на грешки, осъществяване на проста многозадачност, фонов вход/изход и други.
Вж. също register_tick_function() и unregister_tick_function().
Кодировката на всеки скрипт може да бъде специфицирана посредством директивата encoding.
Example #2 Деклариране на кодировка за скрипта.
<?php
declare(encoding='ISO-8859-1');
// някакъв код тук
?>
В комбинация с пространства от имена, единственият валиден синтаксис за declare е declare(encoding='...');, където ... е кодировъчната стойност. declare(encoding='...') {} ще доведе до синтактична грешка, когато се комбинира с пространства от имена.
Кодировъчната тойност, указана от declare, се пренебрегва в PHP 5.3, освен ако PHP не е компилиран с --enable-zend-multibyte. В PHP 6.0 директивата encoding ще бъде използвана за уведомяване на синтактичния анализатор с каква кодировка е бил създаден файла. Правилните стойности са имената на кодировки, като UTF-8.
Ако се извиква от функция, инструкцията return() незабавно завършва изпълнението й и връща аргумента си като стойност от извикването на функцията. return() ще прекъсне също и изпълнението на конструкцията eval() или скриптов файл.
Ако се извиква от глобалния обхват, тогава изпълнението на текущия скрипт се прекратява. Ако текущият скриптов файл е бил include()-нат (включен) или require()-нат (изискан), тогава контролът се връща обратно на извикващия файл. Освен това, ако текущият скрипт е бил include()-нат, тогава стойността подадена на return() ще бъде върната като стойност от извикването на include(). Ако return() се извика от главния скрипт, изпълнението на скрипта се прекратява. Ако текущият скрипт е бил описан в конфигурационните опции auto_prepend_file или auto_append_file в php.ini, тогава изпълнението на този скрипт се прекратява.
За повече информация, вж. Връщане на стойности.
Забележка: Забележете, че тъй като return() е езикова конструкция, а не функция, заграждащите скоби не са необходими. Всеприето е скобите да се изпускат и всъщност дори е по-добре да го правите, тъй като в този случай PHP има по-малко работа за вършене.
Забележка: В никакъв случай не трябва да използвате скоби около връщаната променлива, когато се връща по референция, тъй като това няма да работи. По референция можете да връщате единствено променлива, но не и резултат от израз. Когато използвате return ($a);, тогава вие не връщате променлива, а резултата от израза ($a) (който, разбира се, е стойността на $a).
require() е идентична на include(), но при неуспех ще предизвика фатална грешка - E_ERROR. С други думи, тя ще прекъсне скрипта, докато include() само ще изведе предупреждение (E_WARNING), което ще позволи на скрипта да продължи.
Вижте документацията на include() за това как работи.
Инструкцията include() включва и изпълнява даден файл.
Документацията по-долу се отнася също и за require(). Двете конструкции са идентични във всяко едно отношение, с изключение на начина, по който обработват грешки. Те и двете предизвикват предупреждение, но require() предизвиква също и фатална грешка. С други думи, не се колебайте да използвате require() ако искате липсващ файл да спре изпълнението на скрипта. include() не се държи по този начин, скриптът ще продължи независимо от липсата. Трябва също така да сте сигурни, че имате подходяща стойност за include_path. Трябва да знаете, че грешка в синтаксиса на изисквания файл няма да предизвика спиране на изпълнението във версии на PHP преди PHP 4.3.5. От тази версия нататък - ще го предизвика.
Файловете за включване се търсят първо в пътя за включване (include_path) относително спрямо текущата работна директория, а след това - в директорията на текущия скрипт. Например, ако пътят ви за включване е libraries, текущата работна директория е /www/, вие сте включили include/a.php и там има include "b.php" в този файл, за b.php ще бъде търсено първо в /www/libraries/, а после във /www/include/. Ако името на файла започва с ./ или ../, той ще бъде потърсен само в текущата работна директория.
Когато даден файл бива включван, кодът в него наследява областта на действие на променливите на реда, на който става включването. От този момент нататък, всяка променлива, налична на този ред в извикващия файл ще бъде налична и в извиквания файл. Всички функции и класове, дефинирани във включвания файл, ще имат глобална област на действие.
Example #1 Основен пример за include()
vars.php
<?php
$color = 'зелена';
$fruit = 'ябълка';
?>
test.php
<?php
echo "Една $color $fruit"; // Една
include 'vars.php';
echo "Една $color $fruit"; // Една зелена ябълка
?>
Ако включването е вътре във функция в извикващия файл, тогава целият код, който се съдържа в извиквания файл ще се държи сякаш е бил дефиниран вътре в тази функция, така че ще вземе областта на действие на променливите на тази функция. Изключение от това правило са вълшебните константи, които се изчисляват от синтактичния анализатор още преди да се е случило включването (include).
Example #2 Включване във функции
<?php
function foo()
{
global $color;
include 'vars.php';
echo "Една $color $fruit";
}
/* vars.php е в обхвата на of foo(), така че *
* $fruit НЕ е налична извън този обхват *
* $color е налична, защото я декларирахме *
* като глобална. */
foo(); // Една зелена ябълка
echo "Една $color $fruit"; // Една зелена
?>
Когато даден файл бива включван, анализаторът излиза от режим PHP и влиза в режим HTML в началото на съответния файл и се връща обратно в края. Затова кодът във включвания файл, който трябва да бъде изпълнен като PHP код, трябва да бъде заграден с валидни тагове за начало и край в PHP.
Ако "опаковката URL fopen" е включена в PHP (а тя е в конфигурацията по подразбиране), можете да укажете файла, който да бъде включен, посредством URL (през HTTP или друга поддържана опаковка - вижте List of Supported Protocols/Wrappers за списък на протоколите) вместо локален път към файл. Ако отдалеченият сървър интерпретира дадения файл като PHP код, тогава е възможно да се предават променливи към включвания файл, посредством URL низ-заявка както при HTTP GET. Това не е съвсем същото като да се включва файла и той да наследи променливия обхват на родителския файл; всъщност скриптът се пуска на отдалечения сървър и резултатът чак тогава се включва в локалния скрипт.
Windows версиите на PHP преди PHP 4.3.0 не поддържат достъпа до отдалечени файлове посредством тази функция, дори и ако allow_url_fopen е включено.
Example #3 include() през HTTP
<?php
/* Този пример предполага, че www.example.com е конфигуриран да прави разбор на .php
* файлове и да не прави разбор на .txt файлове. Също така, в случая 'Работи' означава, че
* променливите $foo и $bar са налични във включвания файл. */
// Няма да работи; file.txt не се обработва от www.example.com като PHP
include 'http://www.example.com/file.txt?foo=1&bar=2';
// Няма да работи; гледа за файл с име 'file.php?foo=1&bar=2' в
// локалната файлова система.
include 'file.php?foo=1&bar=2';
// Работи.
include 'http://www.example.com/file.php?foo=1&bar=2';
$foo = 1;
$bar = 2;
include 'file.txt'; // Работи.
include 'file.php'; // Работи.
?>
Отдалечен файл може да бъде изпълнен на отдалечения сървър (в зависимост от файловото разширение и от това дали отдалеченият сървър стартира PHP или не) но той все пак трябва да даде валиден PHP скрипт, защото той ще бъде обработен на локалния сървър. Ако файлът от отдалечения сървър трябва да бъде обработен там и просто да бъде изведен, то много по-подходяща за тази работа е функцията readfile(). В противен случай трябва да се вземат специални мерки, за да се осигури, че отдалеченият скрипт дава валиден и желан код.
Вж. също Отдалечени файлове, fopen() и file() за информация по темата.
Обработка на връщания: Възможно е да се изпълни инструкция return() във включван файл, за да се прекъсне изпълнението на този файл и да се предаде контролът към извикващия скрипт. Също така е възможно да се връщат стойности от включвани файлове. Можете да вземете стойността на включвания файл, както бихте го направили с нормална функция. Това обаче не е възможно, когато включвате отдалечени файлове, освен ако отдалеченият файл има валидни тагове за начало и край в PHP (както и за локални файлове). Можете да декларирате нужните променливи в тези тагове и те ще бъдат внесени в точката на включването.
Тъй като include() е специална езикова конструкция, употребата на скоби около аргумента й не е необходима. Бъдете внимателни, когато сравнявате връщаната стойност.
Example #4 Сравнение на връщана стойност от include
<?php
// няма да работи, ще се изчисли като include(('vars.php') == 'OK'), т.е. include('')
if (include('vars.php') == 'OK') {
echo 'OK';
}
// работи
if ((include 'vars.php') == 'OK') {
echo 'OK';
}
?>
Example #5 include() и инструкцията return()
return.php
<?php
$var = 'PHP';
return $var;
?>
noreturn.php
<?php
$var = 'PHP';
?>
testreturns.php
<?php
$foo = include 'return.php';
echo $foo; // отпечатва 'PHP'
$bar = include 'noreturn.php';
echo $bar; // отпечатва 1
?>
$bar има стойност 1, защото включването е било успешно. Отбележете разликата в горните примери. Първият използва return() във включвания файл, докато другият - не. В случай че файлът не може да бъде включен, ще бъде върната стойност FALSE и ще се изведе E_WARNING.
Ако има функции, дефинирани във включвания файл, то те могат да бъдат използвани в главния файл независимо от това дали са преди или след return(). Ако файлът бъде включен повторно, PHP 5 ще изведе фатална грешка, понеже функциите вече са били декларирани, докато PHP 4 няма да се оплаче за функции, дефинирани след return(). Препоръчително е да се използва include_once() вместо да се проверява дали файлът вече е бил включен и да се връща условно във включвания файл.
Друг начин да се "включи" файл от тип PHP в променлива е да се прихване изхода посредством Функциите за контрол на изхода и include(). Например:
Example #6 Буфериране на изхода с цел включване на PHP файл в низ
<?php
$string = get_include_contents('somefile.php');
function get_include_contents($filename) {
if (is_file($filename)) {
ob_start();
include $filename;
$contents = ob_get_contents();
ob_end_clean();
return $contents;
}
return false;
}
?>
Ако искате да включвате файлове автоматично в скриптовете, вижте също конфигурационните директиви auto_prepend_file и auto_append_file в php.ini.
Забележка: Тъй като това е езикова конструкция а не функция, тя не може да бъде извикана посредством променливи функции
Вж. също require(), require_once(), include_once(), get_included_files(), readfile(), virtual() и include_path.
Инструкцията require_once() е идентична на require() с тази разлика, че PHP ще направи проверка дали файлът вече не е бил включен, и ако е бил, няма да го включи повторно.
Вижте документацията на include_once() за информация относно поведението _once (веднъж) и как то се различава от това на съответните им еквиваленти не-_once.
Инструкцията include_once() включва и изпълнява даден файл по време на изпълнението на скрипт. Начинът на работа е подобен на този на include(), с единствената разлика, че ако кодът от файла вече е бил включен, той няма да бъде включен повторно. Както подсказва и името, той ще бъде включен точно веднъж (once).
include_once() би трябвало да бъде използвана на места, където е възможно един и същи файл да бъде включен и изпълнен повече от веднъж по време на специфично изпълнение на скрипт, и когато искате да сте сигурни, че файлът ще бъде включен точно един път, за да се избегнат проблеми с повторно дефиниране на функции, повторно присвояване на променливи, и т.н.
За повече примери, показващи употребата на require_once() и include_once(), разгледайте » PEAR кода, включен в последната дистрибуция на PHP.
Връщаните стойности са същите както при include(). Ако файлът вече е бил включен, тази функция ще върне TRUE
Забележка: include_once() е добавена в PHP 4.0.1
Забележка: Отбележете, че поведението на include_once() и require_once() може да бъде различно от очакваното на операционни системи нечувствителни към регистъра (като Windows).
Example #1 include_once() е нечувствителна към регистъра под Windows
<?php
include_once "a.php"; // това ще включи a.php
include_once "A.php"; // това отново ще включи a.php под Windows! (само в PHP 4)
?>Поведението се промени в PHP 5 - пътят първо се нормализира така, че C:\PROGRA~1\A.php да стане C:\Program Files\a.php, след което файлът се включва еднократно.
Windows версиите на PHP преди PHP 4.3.0 не поддържат достъпа до отдалечени файлове посредством тази функция, дори и ако allow_url_fopen е включено.
Вж. също include(), require(), require_once(), get_required_files(), get_included_files(), readfile() и virtual().
Операторът goto може да бъде използван за скок до друга инструкция в програмата. Желаното място се специфицира с етикет и точка и запетая, а този етикет се поставя след goto.
Example #1 Пример за goto
<?php
goto a;
echo 'Foo';
a:
echo 'Bar';
?>
Примерът по-горе ще изведе:
Bar
Забележка: Операторът goto е наличен от PHP 5.3.
Скачането в цикъл или конструкция switch не е разрешено. В този случай ще бъде изведена фатална грешка.
Функция може да бъде дефинира посредством следния синтаксис:
Example #1 Псевдо-код, демонстриращ употребата на функции
<?php
function foo($arg_1, $arg_2, /* ..., */ $arg_n)
{
echo "Примерна функция.\n";
return $retval;
}
?>
Във функциите е разрешена употребата на какъвто и да е валиден код PHP, дори и дефиниция на други функции или класове.
Имената на функциите следват същите правила като другите етикети в PHP. Валидното име на функция започва с буква или подчертавка, следвана от произволен брой букви, цифри или подчертавки. Като регулярен израз, това би могло да бъде представено така: [a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*.
Вж. също Userland Naming Guide.
Не е необходимо функциите да бъдат дефинирани преди да бъдат използвани, освен в случаите, когато функцията е дефинирана условно, както в двата примера по-долу.
Когато дадена функция е дефинирна условно, то тя трябва да бъде дефинирана преди да бъде извикана.
Example #2 Условни функции
<?php
$makefoo = true;
/* Не можем да извикаме foo() оттук,
понеже тя все още не съществува,
но можем да извикаме bar() */
bar();
if ($makefoo) {
function foo()
{
echo "Аз не съществувам докато изпълнението на програмата не стигне до мен.\n";
}
}
/* Сега можем спокойно да извикаме foo(),
понеже $makefoo се е изчислила на истина */
if ($makefoo) foo();
function bar()
{
echo "Аз съществувам от стартирането на програмата.\n";
}
?>
Example #3 Функции във функции
<?php
function foo()
{
function bar()
{
echo "Аз не съществувам, докато не се извика foo().\n";
}
}
/* Не можем да извикаме bar() все още,
понеже не съществува. */
foo();
/* Сега можем да извикаме bar(),
изпълнението на foo() я
е направило достъпна. */
bar();
?>
Всички функции и класове в PHP имат глобална област на действие - могат да бъдат извиквани извън функция, дори и да са били дефинирани вътре и обратно.
PHP не поддържа нито претоварване на функции, нито отменянето на дефиницията или повторното дефиниране на функция, която е била дефинирана преди това.
Забележка: Имената на функциите не са чувствителни към регистъра, но все пак е добра практитка функциите да се извикват със същите имена, с които са били дефинирани.
При функциите се поддържат както променливия брой аргументи, така и дефинирането на аргументи по подразбиране. За повече информация вижте документацията на функциите func_num_args(), func_get_arg() и func_get_args().
В PHP е възможно рекурсивното извикване на функции. Все пак избягвайте рекурсивното извикване на функция/метод с повече от 100-200 нива на рекурсия, тъй като това може да доведе до смачкване на стека, което да предизвика прекратяване на скрипта.
Example #4 Рекурсивни функции
<?php
function recursion($a)
{
if ($a < 20) {
echo "$a\n";
recursion($a + 1);
}
}
?>
Към функциите може да бъде предавана информация посредством списък с аргументи под формата на разделен със запетаи списък с изрази.
PHP поддържа предаването на аргументи по стойност (по подразбиране), по референция, както и стойности по подразбиране. Списъци с аргументи с променлива дължина също се поддържат, вж. документацията на функциите func_num_args(), func_get_arg() и func_get_args() за повече информация.
Example #1 Предаване на масиви към функции
<?php
function takes_array($input)
{
echo "$input[0] + $input[1] = ", $input[0]+$input[1];
}
?>
По подразбиране аргументите се предават на функциите по стойност (така че ако стойността на даден аргумент бъде променена вътре във функцията, това няма да промени съответната променлива извън нея). За да се разреши на функция да променя аргументите си, те трябва да бъдат предадени по референция.
За да бъде предаван винаги по референция, съответният аргумент на функция трябва да бъде предшестван от амперсанд (&) пред името си в дефиницията на функцията:
Example #2 Предаване на функционални параметри по референция
<?php
function add_some_extra(&$string)
{
$string .= 'и още нещо.';
}
$str = 'Това е низ ';
add_some_extra($str);
echo $str; // извежда 'Това е низ и още нещо.'
?>
Функция може да дефинира стойности по подразбиране за скаларни аргументи, както в C++, така:
Example #3 Употреба на параметри по подразбиране във функции
<?php
function makecoffee($type = "капучино")
{
return "Приготвяне на чаша $type.\n";
}
echo makecoffee();
echo makecoffee(null);
echo makecoffee("еспресо");
?>
Изходът от горния откъс е:
PHP позволява също и употребата на масиви и на специалния тип NULL за стойности по подразбиране, например:
Example #4 Употреба на не-скаларни типове за стойности по подразбиране
<?php
function makecoffee($types = array("капучино"), $coffeeMaker = NULL)
{
$device = is_null($coffeeMaker) ? "на ръка" : $coffeeMaker;
return "Приготвяне на чаша ".join(", ", $types)." $device.\n";
}
echo makecoffee();
echo makecoffee(array("капучино", "лаваца"), "с машина за кафе");
?>
Стойността по подразбиране трябва да бъде константа, а не (например) променлива, член на клас или извикване на функция.
Забележете, че когато се използват аргументи по подразбиране, те трябва да бъдат от дясната страна, а тези без стойности по подразбиране - от лявата; в противен случай нещата може да не работят според очакванията. Разгледайте следния откъс:
Example #5 Неправилна употреба на подразбиращи се аргументи
<?php
function makeyogurt($type = "кисело", $flavour)
{
return "Сервиране на чаша $type $flavour.\n";
}
echo makeyogurt("мляко"); // няма да работи според очакваното
?>
Изходът от горния пример е:
Сега сравнете горното с това:
Example #6 Правилна употреба на подразбиращи се аргументи
<?php
function makeyogurt($flavour, $type = "кисело")
{
return "Сервиране на чаша $type $flavour.\n";
}
echo makeyogurt("мляко"); // работи както трябва
?>
Изходът от този пример е:
Забележка: От PHP 5 нататък стойностите по подразбиране могат да бъдат предавани по референция.
От PHP 4 нататък се поддържа списък с аргументи с променлива дължина в потребителски-дефинираните функции. Това е лесно, посредством функциите func_num_args(), func_get_arg() и func_get_args().
Не се изисква специален синтаксис и списъкът с аргументи може да бъде все така изрично предоставян с дефинициите на функциите и те ще работят както трябва.
Връщането на стойности става посредством незадължителната инструкция за връщане (return). Позволено е връщането на всякакви типове, включително списъци и обекти. Това кара функцията да спре незабавно изпълнението си и да предаде контрола обратно на реда, от който е била извикана. Погледнете return() за повече информация.
Example #1 Употреба на return()
<?php
function square($num)
{
return $num * $num;
}
echo square(4); // извежда '16'.
?>
Функцията не може да връща множество стойности, но подобен ефект може да бъде постигнат чрез връщането на масив.
Example #2 Връщане на масив, с цел получаване на множество стойности
<?php
function small_numbers()
{
return array (0, 1, 2);
}
list ($zero, $one, $two) = small_numbers();
?>
За да върнете референция от функция, използвайте референтния оператор & както при декларирането на функцията, така и при присвояването на връщаната стойност на променливата:
Example #3 Връщане на референция от функция
<?php
function &returns_reference()
{
return $someref;
}
$newref =& returns_reference();
?>
За повече информация относно референциите, разгледайте раздел Референции.
PHP поддържа концепцията за променливи функции. Това означава, че ако дадена променлива има скоби в края си, PHP ще потърси за функция с име - стойността на променливата и ще се опита да я изпълни. Освен за друго, това може да бъде използвано и с цел осъществяване на обратни извиквания, функционални таблици и други.
Променливите функции няма да работят с езикови конструкции като echo(), print(), unset(), isset(), empty(), include(), require() и други от този род. Използвайте функции-опаковки, за да можете да използвате някоя от тези езикови конструкции като променлива функция.
Example #1 Пример за променлива функция
<?php
function foo() {
echo "Във foo()<br />\n";
}
function bar($arg = '')
{
echo "В bar(); аргументът беше '$arg'.<br />\n";
}
// Това е функция-опаковка на echo
function echoit($string)
{
echo $string;
}
$func = 'foo';
$func(); // Това извиква foo()
$func = 'bar';
$func('test'); // Това извиква bar()
$func = 'echoit';
$func('test'); // Това извиква echoit()
?>
Методите на обекти също могат да бъдат извиквани посредством синтаксиса за променливи функции.
Example #2 Пример за променлив метод
<?php
class Foo
{
function Variable()
{
$name = 'Bar';
$this->$name(); // Това извиква метода Bar()
}
function Bar()
{
echo "Това е Bar";
}
}
$foo = new Foo();
$funcname = "Variable";
$foo->$funcname(); // Това извиква $foo->Variable()
?>
Вж. също call_user_func(), променливи променливи и function_exists().
PHP стандартно разполага с множество функции и конструкции. Съществуват също и функции, които изискват да бъде компилирано специфично разширение на PHP, в противен случай ще се получат фатални грешки за "недефинирани функции". Например, за да се използват функциите за изображения като imagecreatetruecolor(), е необходимо PHP да бъде компилиран заедно с поддръжка на GD. Или за достъп до mysql_connect(), PHP трябва да бъде компилиран с поддръжка на MySQL. Съществуват и много базови функции, които са включени във всяка версия на PHP като функциите string и variable. Извикване на phpinfo() или get_loaded_extensions() ще покаже кои разширения са заредени в PHP. Също отбележете, че много разширения са включени по подразбиране и че ръководството на PHP е разделено по разширения. Вж. конфигурация, инсталация и отделните глави за разширенията за повече информация как да конфигурирате вашия PHP.
Четенето и разбирането на функционални прототипи е обяснено в раздела, озаглавен как да четем дефиниции на функции. Важно е да се разбере какво връща функцията или дали функцията работи директно върху подадената й стойност. Например, str_replace() ще върне променения низ, докато usort() работи върху действително подадената стойност. Всяка страница в ръководството също съдържа специфична информация за всяка функция като информация за параметрите на функцията, промяна на поведението, връщани стойности при успех или неуспех, както и всякаква друга налична информация. Познаването на тези важни (и понякога едва доловими) разлики е ключово при писането на правилен код на PHP.
Забележка: Ако параметрите, подавани на дадена функция, не са такива, каквито очаква, като например предаването на масив, където се очаква низ, то връщаната стойност от функцията е недефинирана. В този случай най-вероятно тя ще върне NULL, но това е просто конвенция и на това не може да се разчита.
Вж. също function_exists(), функционалния справочник, get_extension_funcs() и dl().
Анонимните функции позволяват създаването на функции без да е необходимо да им се указва име. Те са най-удобни при параметрите с обратно извикване, но могат да бъдат използвани и на много други места.
Example #1 Пример за анонимна функция
<?php
echo preg_replace_callback('~-([a-z])~', function ($match) {
return strtoupper($match[1]);
}, 'hello-world');
// outputs helloWorld
?>
Вътрешно анонимните функции са осъществени посредством класа Closure.
Забележка: Анонимните функции са налични от PHP 5.3.0.
Класът е набор от променливи и функции, които работят с променливите. Променливите се дефинират с ключовата дума var, а функциите с function. Дефиницията на клас има следния синтаксис:
<?php
class Cart {
var $items; // Артикули в нашата пазарска количка
// Добавяне на $num артикули от $artnr към пазарската количка
function add_item($artnr, $num) {
$this->items[$artnr] += $num;
}
// Премахване на $num артикула от $artnr от пазарската количка
function remove_item($artnr, $num) {
if ($this->items[$artnr] > $num) {
$this->items[$artnr] -= $num;
return true;
} elseif ($this->items[$artnr] == $num) {
unset($this->items[$artnr]);
return true;
} else {
return false;
}
}
}
?>
В примера по-горе е дефиниран клас Cart, който се състои от асоциативен масив, от артикули на пазарска количка и две функции за добавяне и премахване на артикули от тази пазарска количка.
Не може дефиницията на клас да се помества в множество файлове. Също така не може дефиницията на клас да се помества в множество блокове PHP, освен ако прекъсването не е в декларацията на метод. Следният пример няма да работи:
<?php
class test {
?>
<?php
function test() {
print 'OK';
}
}
?>
Следното обаче е позволено:
<?php
class test {
function test() {
?>
<?php
print 'OK';
}
}
?>
Следните предупредителни забележки са валидни за PHP 4.
Наименованието stdClass се използва вътрешно от Zend и е запазено. Не можете да имате клас с име stdClass в PHP.
Имената на функциите __sleep и __wakeup са вълшебни в класовете на PHP. Не може да имате функции с тези имена във вашите класове, освен ако не искате да ползвате вълшебната функционалност свързана с тях. Вижте по-долу за повече информация.
PHP запазва всички имена на функции, започващи с __ като вълшебни. Препоръчително е да не използвате имена на функции в PHP, започващи с __, освен ако не искате да ползвате документираната вълшебна функционалност.
В PHP 4 var-променливите на класовете могат да се инициализират само с константни стойности. За да се инициализира променлива с неконстантна стойност, трябва да се използва инициализационна функция, която се извиква автоматично при инстанциирането на класа. Такава функция се нарича конструктор (вижте по-долу).
<?php
class Cart {
/* Нито една от долните конструкции няма да работи в PHP 4. */
var $todays_date = date("Y-m-d");
var $name = $firstname;
var $owner = 'Fred ' . 'Jones';
/* Масивите съдържащи константни стойности ще работят. */
var $items = array("VCR", "TV");
}
/* Това е начинът да се направи. */
class Cart {
var $todays_date;
var $name;
var $owner;
var $items = array("VCR", "TV");
function Cart() {
$this->todays_date = date("Y-m-d");
$this->name = $GLOBALS['firstname'];
/* и т.н. */
}
}
?>
Класовете са типове, което означава, че са шаблони за действителните променливи. Можете да създадете променлива от желаният от вас тип чрез оператора new
<?php
$cart = new Cart;
$cart->add_item("10", 1);
$another_cart = new Cart;
$another_cart->add_item("0815", 3);
?>
В горния пример се създават обектите $cart и $another_cart като и двата са инстанции на класа Cart. Функцията add_item() на обекта $cart се извиква за да се добави един артикул с номер 10 към $cart. Също така се добавят 3 артикула с номер 0815 към $another_cart.
И двата обекта - $cart и $another_cart, притежават функции add_item(), remove_item() и променливи. Можете да си представите обектите като нещо подобно на директориите в една файлова система. В дадена файлова система може да имате 2 отделни файла README.TXT, стига да се намират в различни директории. Също както при директориите ще трябва да въведете пълния път до файла, за да имате достъп до него от главната директория, трябва да зададете пълното име на функцията която искате да извикате: в контекста на PHP - главната директория ще бъде глобалното пространство от имена, а разделителят в името на пътя се явява ->. По този начин $cart->items и $another_cart->items са две различни променливи. Забележете, че променливата е $cart->items, а не $cart->$items, което означава, че името на променливата в PHP трябва да има само един знак $.
<?php
// правилно, единичен $
$cart->items = array("10" => 1);
// невалидно, понеже $cart->$items става $cart->""
$cart->$items = array("10" => 1);
// правилно, но резултата може да не е този, който очакваме:
// $cart->$myvar става $cart->items
$myvar = 'items';
$cart->$myvar = array("10" => 1);
?>
В дефиницията на класа вие не знаете името на обекта който ще го инстанциира: по времето на написването на класа Cart не беше известно, че по-късно обектът ще бъде кръстен $cart или $another_cart. Следователно няма как да напишете $cart->items в самия клас. Вместо това, за да имаме достъп до собствените функции и променливи на класа, може да използваме псевдо-променливата $this, която е референция към обекта, който е инстанциирал класа. Следователно '$this->items[$artnr] += $num' може да бъде прочетено като 'добави $num към брояча $artnr на артикулите на моя масив' или 'добави $num към брояча $artnr на артикулите на масива за текущия обект'.
Забележка: Псевдо-променливата $this обикновено не е дефинирана ако метода в който се намира е извикан статично. Това все пак не е стриктно правило: $this е дефинирана ако метода е извикан статично от друг обект. В този случай, стойността на $this е тази на извикващият обект. Това е илюстрирано със следният пример:
<?php
class A
{
function foo()
{
if (isset($this)) {
echo '$this е дефинирана (';
echo get_class($this);
echo ")\n";
} else {
echo "\$this не е дефинирана.\n";
}
}
}
class B
{
function bar()
{
A::foo();
}
}
$a = new A();
$a->foo();
A::foo();
$b = new B();
$b->bar();
B::bar();
?>Примерът по-горе ще изведе:
$this е дефинирана (a) $this не е дефинирана. $this е дефинирана (b) $this не е дефинирана.
Забележка: Съществуват няколко функции за работа с класове и обекти. Можете да ги разгледате в раздел Функции за класове и обекти.
Много често имаме нужда от класове с променливи и функции подобни на тези от друг съществуващ клас. Всъщност е добра практика да дефинираме общ клас, който да може да се използва във всичките проекти и да адаптираме този клас за специфичните нужди на конкретния проект. За да се улесни това, класовете могат да наследяват други класове. Производният клас има всички променливи и функции на базовия клас (това се нарича 'наследство', въпреки факта, че никой не е умрял), както и тези които са допълнително дефинирани. Не е възможно да изваждате променливи или функции от производен клас, т.е. да премахвате вече дефинирани функции и променливи. Производният клас винаги наследява от един базов клас, т.е. множествено наследяване не се поддържа. Наследяването на класове се осъществява с ключовата дума 'extends' (разширява).
<?php
class Named_Cart extends Cart {
var $owner;
function set_owner ($name) {
$this->owner = $name;
}
}
?>
В горния пример е дефиниран клас Named_Cart, който притежава всички променливи и функции от Cart, плюс допълнителната променлива $owner и допълнителната функция set_owner(). Може да създадете именувана пазарска количка по нормалния начин и да установите или да върнете като резултат името на собственика й. Можете да използвате и функциите на нормалната пазарска количка върху именуваната такава:
<?php
$ncart = new Named_Cart; // Създаване на именувана пазарска количка
$ncart->set_owner("kris"); // Задаване на име на пазарската количка
print $ncart->owner; // извежда името на собственика на пазарската количка
$ncart->add_item("10", 1); // (наследена функционалност от Cart)
?>
Това също така се нарича отношение родител-наследник. Създавате родителски клас и използвате extends, за да създадете нов клас базиран на родителския: дъщерен клас. Можете да използвате този дъщерен клас, за да дефинират друг клас базиран на него.
Забележка: Класовете трябва да бъдат дефинирани преди да бъдат използвани! Ако искате клас Named_Cart да наследи клас Cart, трябва първо да дефинирате клас Cart. Ако искате да създадете друг клас наречен Yellow_named_cart, наследяващ класа Named_Cart, ще трябва първо да дефинирате Named_Cart. Накратко: редът на дефиниране на класовете е важен.
Конструкторите са функции на класа, които се извикват автоматично при създаване на нова инстанция на съответния клас с ключовата дума new. Дадена функция е конструктор, когато името и съвпада с името на класа. Ако даден клас няма конструктор, то ще се бъде извикан конструктора на базовия му клас (ако съществува).
<?php
class Auto_Cart extends Cart {
function Auto_Cart() {
$this->add_item("10", 1);
}
}
?>
Горният код дефинира клас Auto_Cart, който представлява класа Cart плюс конструктор, който инициализира пазарската количка с артикул номер "10" всеки път, когато се създаде нов обект от тип Auto_Cart с ключовата дума "new". Конструкторите могат да приемат аргументи и тези аргументи могат да бъдат с подразбиращи се стойности, което ги прави още по-полезни. За да е възможно използването на класа без параметри, всички параметри на конструктора трябва да бъдат дефинирани със стойности по подразбиране.
<?php
class Constructor_Cart extends Cart {
function Constructor_Cart($item = "10", $num = 1) {
$this->add_item ($item, $num);
}
}
// Пазаруваме едни и същи стари неща...
$default_cart = new Constructor_Cart;
// Истинско пазаруване...
$different_cart = new Constructor_Cart("20", 17);
?>
Можете да използвате оператора @ за да подтиснете грешките които възникват в тялото на конструктора, т.е @new.
<?php
class A
{
function A()
{
echo "Аз съм конструкторът на клас A.<br />\n";
}
function B()
{
echo "Аз съм нормална функция B в клас A.<br />\n";
echo "Аз не съм конструктор на клас A.<br />\n";
}
}
class B extends A
{
}
// Това ще предизвика извикването на B() като конструктор
$b = new B;
?>
Функция B() в клас A ще се приеме като конструктор в клас B, въпреки че не е проектирана да бъде такава. В PHP 4 няма значение, дали функцията е дефинирана в клас B или е наследена от родителски клас.
В PHP 4 конструктора на базовия клас не се извиква автоматично от конструктора на производния клас. Отговорността за извикването на този конструктор, където е необходимо нагоре по йерархията на класовете, е на програмиста.
Деструкторите са функции, които се извикват автоматично, когато даден обект се унищожи, било то чрез unset() или просто като се излезе от областта на действие на обекта. В PHP не съществуват деструктори. Можете да използвате функцията register_shutdown_function(), за да симулирате голяма част от действието на деструкторите.
Следното е валидно само за PHP 4 и по-нови версии.
Понякога е полезно да се обръщаме към функции и променливи от базовите класове или да се обръщаме към функции, които все още нямат инстанции. В тези случаи се използва оператора ::.
<?php
class A {
function example() {
echo "Аз съм оригиналната функция A::example().<br />\n";
}
}
class B extends A {
function example() {
echo "Аз съм повторно-дефинираната функция B::example().<br />\n";
A::example();
}
}
// няма обект от клас A.
// това ще изведе
// Аз съм оригиналната функция A::example().<br />
A::example();
// създаване на обект от клас B.
$b = new B;
// това ще изведе
// Аз съм повторно-дефинираната функция B::example().<br />
// Аз съм оригиналната функция A::example().<br />
$b->example();
?>
В горния пример се извиква функция example() на клас A, без да е създаден обект от клас A, така че няма как да се напише $a->example() или нещо подобно. Вместо това example() се извиква като функция на класа, която е функция на самия клас, а не на обект от този клас.
Съществуват функции на класа, но не променливи на класа. В действителност, въобще не съществува обект в момента на извикването. По този начин функцията на класа не може да използва променливи на класа (но може да ползва локални или глобални променливи) и изобщо не може да използва $this.
В горния пример в клас B е дефинирана повторно функцията example(). Първоначалната дефиниция в клас А е препокрита и е недостъпна, освен ако не се обърнете изрично към реализацията на example() в клас A посредством оператора ::. Напишете A::example(), за да направите това (всъщност е по-добре да напишете parent::example(), както е показано в следващия раздел.
В контекста на казаното по-горе, съществува текущ обект и той може да има променливи. По този начин, при извикването от тялото на функция, можете да използвате ключовата дума и променливи на обекта.
Може да ви се наложи да пишете код, който се обръща към променливи и методи на базови класове. Това обикновено е така, когато наследеният клас е подобрение или конкретизация на код от базовия клас.
Вместо в кода да използвате конкретното име на базовия клас, можете да използвате специалното име parent, което представлява името на базовия клас, така както е указан в декларацията extends на класа. По този начин се избягва използването на името на базовия клас на повече от едно място. Ако трябва да се промени йерархията при наследяването, това може да се направи като просто се промени декларацията extends на класа.
<?php
class A {
function example() {
echo "Аз съм A::example() и осигурявам базова функционалност.<br />\n";
}
}
class B extends A {
function example() {
echo "Аз съм B::example() и осигурявам допълнителна функционалност.<br />\n";
parent::example();
}
}
$b = new B;
// Следният код ще извика B::example(), който от своя страна ще извика A::example().
$b->example();
?>
serialize() връща низ, съдържащ представяне под формата на byte-stream на всяка стойност, която PHP може да съхранява. unserialize() може да използва този низ, за да върне първоначалната стойност на променливите. При използването на serialize за съхраняване на обект ще се съхранят всички променливи на обекта. Името на класа също ще бъде запазено, но не и функциите на обекта.
За да десериализирате обекта, класът на този обект трябва да бъде дефиниран. По този начин ако имате обект $a от клас A в page1.php и го сериализирате, ще бъде върнат низ, който сочи към клас A и съдържа всички стойности на променливите в $a. Ако искате да десериализирате това в page2.php, възпроизвеждайки $a от клас A, дефиницията на клас A трябва да съществува в page2.php. Това може да бъде направено като дефиницията на клас A се съхрани във файл за вмъкване и този файл се вмъкне в page1.php и page2.php.
<?php
// classa.inc:
class A {
var $one = 1;
function show_one() {
echo $this->one;
}
}
// page1.php:
include("classa.inc");
$a = new A;
$s = serialize($a);
// съхранява $s някъде, където page2.php може да го намери.
$fp = fopen("store", "w");
fwrite($fp, $s);
fclose($fp);
// page2.php:
// това е нужно, за да може unserialize да работи коректно.
include("classa.inc");
$s = implode("", @file("store"));
$a = unserialize($s);
// сега използваме метода show_one() на обекта $a.
$a->show_one();
?>
Ако използвате сесии и session_register() за регистриране на обекти, то тези обекти се сериализират автоматично в края на всяка страница PHP и се десериализират автоматично на всяка от следващите страници. Това означава, че тези обекти могат да бъдат използвани на всяка страница, веднага след като са станали част от вашата сесия.
Горещо се препоръчва да включвате дефинициите на класовете на всички обекти регистрирани по този начин във всички страници, дори и на практика да не използвате тези класове навсякъде. Ако не направите това и даден обект се десериализира без да е налична дефиницията на класа му, то той ще изгуби връзката с класа и ще се интерпретира като обект от клас __PHP_Incomplete_Class_Name, без да са налични никакви методи и така ще стане абсолютно безполезен.
Ако в примера по-горе $a стане част от сесия посредством session_register("a"), файлът classa.inc трябва да бъде включен във всички страници, не само в page1.php и page2.php.
serialize() проверява дали вашият клас има функция с вълшебно име __sleep. Ако има такава, тази функция се изпълнява преди всяка сериализация. Тя може да извършва почистване на обекта и връща масив с имената на всички променливи на обекта, който ще бъде сериализиран. Ако методът не върне нищо, тогава се сериализира стойността NULL и се генерира грешка от тип E_NOTICE.
__sleep може да се използва за затваряне на всички връзки към базите от данни, които са създадени в даден обект, за изпълняване на заявките, които са на изчакване или да извърши други подобни почистващи задачи. Също така функцията може да бъде полезна, ако имате много големи обекти, които не трябва да се съхраняват изцяло.
Функцията unserialize() е обратната на serialize() и проверява за наличието на функцията с вълшебно име __wakeup. Ако е налична, тази функция може да реконструира ресурсите на даден обект.
Замисъла на __wakeup е да възстанови връзките към базите от данни, които са изгубени по време на сериализацията и да извърши други задачи свързани с прединициализирането.
Създаването на референции в конструктора може да доведе до объркващи резултати. Този раздел, написан във вид на ръководство, може да ви помогне да избегнете подобни проблеми.
<?php
class Foo {
function Foo($name) {
// създаване на референция в глобалния масив $globalref
global $globalref;
$globalref[] = &$this;
// установяне на името на предадената стойност
$this->setName($name);
// и извеждане
$this->echoName();
}
function echoName() {
echo "<br />", $this->name;
}
function setName($name) {
$this->name = $name;
}
}
?>
Нека сега да проверим дали има разлика между $bar1, създадена чрез оператора за копиране = и $bar2, създадена чрез оператора за референции - =&
<?php
$bar1 = new Foo('установяване в конструктора');
$bar1->echoName();
$globalref[0]->echoName();
/* изход:
установяване в конструктора
установяване в конструктора
установяване в конструктора */
$bar2 =& new Foo('установяване в конструктора');
$bar2->echoName();
$globalref[1]->echoName();
/* изход:
установяване в конструктора
установяване в конструктора
установяване в конструктора */
?>
Очевидно няма разлика, но всъщност има една значителна разлика: $bar1 и $globalref[0] не са извикани по референция и не са една и съща променлива. Това е така, тъй като операторът "new" по подразбиране връща не референция, а копие.
Забележка: Няма намаляване на производителността (след като от PHP 4 се използва брояч на референциите) при връщане на копия вместо референции. Точно обратното, често е по-добре просто да се работи с копия, вместо с референции, тъй като създаването на референции отнема известно време, докато създаването на копие фактически не отнема време (освен ако никое от тях не е голям масив или обект и един от тях е променен, а в последствие и останалите. В този случай ще бъде по-добре да се използват референции, за да бъдат променени едновременно).
За да докажем написаното по-горе, нека погледнем кода отдолу.
<?php
// сега ще променим името. Какво очаквате да стане?
// можете да очаквате, че $bar1 и $globalref[0] ще са с променени имена...
$bar1->setName('установяване от вън');
// както споменахме по-горе, това няма да стане
$bar1->echoName();
$globalref[0]->echoName();
/* изход:
установяване от вън
установяване в конструктора */
// нека сега видим каква е разликата между $bar2 и $globalref[1]
$bar2->setName('установяване от вън');
// за щастие те не само са равни, те представляват една и съща променлива
// така че, $bar2->name и $globalref[1]->name също са една и съща променлива
$bar2->echoName();
$globalref[1]->echoName();
/* изход:
установяване от вън
установяване от вън */
?>
Още един, последен пример, опитайте се да го разберете.
<?php
class A {
function A($i) {
$this->value = $i;
// опитайте се да разберете защо нямаме нужда от референция тук
$this->b = new B($this);
}
function createRef() {
$this->c = new B($this);
}
function echoValue() {
echo "<br />","class ",get_class($this),': ',$this->value;
}
}
class B {
function B(&$a) {
$this->a = &$a;
}
function echoValue() {
echo "<br />","class ",get_class($this),': ',$this->a->value;
}
}
// опитайте се да разберете, защо използването на обикновено копие тук,
// ще доведе до нежелани резултати в реда отбелязан със *.
$a =& new A(10);
$a->createRef();
$a->echoValue();
$a->b->echoValue();
$a->c->echoValue();
$a->value = 11;
$a->echoValue();
$a->b->echoValue(); // *
$a->c->echoValue();
?>
Примерът по-горе ще изведе:
class A: 10 class B: 10 class B: 10 class A: 11 class B: 11 class B: 11
В PHP 4 обектите се сравняват по много лесен начин, а именно: Две инстанции са равни, ако имат едни и същи атрибути и стойности и са инстанции на един и същ клас. Подобни правила се прилагат и при сравняване на два обекта с оператора за идентичност (===).
Нека разгледаме следния пример:
Example #1 Пример за сравняване на обекти в PHP 4
<?php
function bool2str($bool) {
if ($bool === false) {
return 'FALSE';
} else {
return 'TRUE';
}
}
function compareObjects(&$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 Flag {
var $flag;
function Flag($flag=true) {
$this->flag = $flag;
}
}
class SwitchableFlag extends Flag {
function turnOn() {
$this->flag = true;
}
function turnOff() {
$this->flag = false;
}
}
$o = new Flag();
$p = new Flag(false);
$q = new Flag();
$r = new SwitchableFlag();
echo "Сравняване на инстанции създадени с еднакви параметри\n";
compareObjects($o, $q);
echo "\nСравняване на инстанции създадени с различни параметри\n";
compareObjects($o, $p);
echo "\nСравняване на инстанция на родителски клас с този на дъщерния клас\n";
compareObjects($o, $r);
?>
Примерът по-горе ще изведе:
Сравняване на инстанции създадени с еднакви параметри o1 == o2 : TRUE o1 != o2 : FALSE o1 === o2 : TRUE o1 !== o2 : FALSE Сравняване на инстанции създадени с различни параметри o1 == o2 : FALSE o1 != o2 : TRUE o1 === o2 : FALSE o1 !== o2 : TRUE Сравняване на инстанция на родителски клас с този на дъщерния клас o1 == o2 : FALSE o1 != o2 : TRUE o1 === o2 : FALSE o1 !== o2 : TRUE
Горе е показан очаквания изход, при горните правила за сравнение. Само инстанции, които притежават едни и същи стойности за атрибутите си и са от един и същ клас се считат за равни и идентични.
Дори и в клас, в който имаме композиция на обекти, се прилагат същите правила за сравнение. В примера по-долу създаваме клас, който съдържа асоциативен масив от обекти от тип Flag.
Example #2 Сравняване на съставни обекти в PHP 4
<?php
class FlagSet {
var $set;
function FlagSet($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 FlagSet();
$u->addFlag('flag1', $o);
$u->addFlag('flag2', $p);
$v = new FlagSet(array('flag1'=>$q, 'flag2'=>$p));
$w = new FlagSet(array('flag1'=>$q));
echo "\nСъставни обекти u(o,p) и v(q,p)\n";
compareObjects($u, $v);
echo "\nu(o,p) и w(q)\n";
compareObjects($u, $w);
?>
Примерът по-горе ще изведе:
Съставни обекти u(o,p) и v(q,p) o1 == o2 : TRUE o1 != o2 : FALSE o1 === o2 : TRUE o1 !== o2 : FALSE u(o,p) и w(q) o1 == o2 : FALSE o1 != o2 : TRUE o1 === o2 : FALSE o1 !== o2 : TRUE
PHP 5 разполага с нов обектен модел. Управлението на обектите е изцяло преработено, с цел по-добра производителност и по-големи възможности.
Вж. също Userland Naming Guide.
Всяка дефиниция на клас започва с ключовата дума class, последвана от името на класа, което може да бъде всяко име, което не е запазена дума в PHP. Следват чифт фигурни скоби, между които се поставя дефиницията на свойствата и методите на класа. Псевдо-променливата $this е налична, когато се извиква дадено свойство или метод от тялото на класа. $this представлява референция към извикания обект (обикновено обекта, на който принадлежи метода, но може да бъде и друг обект, ако методът се извиква статично в контекста на вторичния обект). Това е илюстрирано в следните примери:
<?php
class A
{
function foo()
{
if (isset($this)) {
echo '$this е дефинирана (';
echo get_class($this);
echo ")\n";
} else {
echo "\$this не е дефинирана.\n";
}
}
}
class B
{
function bar()
{
A::foo();
}
}
$a = new A();
$a->foo();
A::foo();
$b = new B();
$b->bar();
B::bar();
?>
Примерът по-горе ще изведе:
$this е дефинирана (a) $this не е дефинирана. $this е дефинирана (b) $this не е дефинирана.
Example #1 Проста дефиниция на клас
<?php
class SimpleClass
{
// дефиниция на свойство
public $var = 'стойност по подразбиране';
// дефиниция на метод
public function displayVar() {
echo $this->var;
}
}
?>
Стойността по подразбиране трябва да е константен израз, не (примерно) променлива, метод на клас или извикване на функция.
Example #2 Стойност по подразбиране за член на клас
<?php
class SimpleClass
{
// невалидни декларации на членове:
public $var1 = 'hello '.'world';
public $var2 = <<<EOD
hello world
EOD;
public $var3 = 1+2;
public $var4 = self::myStaticMethod();
public $var5 = $myVar;
// валидни декларации на членове:
public $var6 = myConstant;
public $var7 = self::classConstant;
public $var8 = array(true, false);
}
?>
Забележка: Разработени са много удобни функции за работа с класове и обекти. Можете да ги видите в глава Функции за класове и обекти.
За разлика от heredoc, nowdoc може да се използва в контекста на всякакви статични данни.
Example #3 Пример със статични данни
<?php
class foo {
// От PHP 5.3.0
public $bar = <<<'EOT'
bar
EOT;
}
?>
Забележка: Поддръжката на nowdoc е добавена в PHP 5.3.0.
За да бъде създадена инстанция на клас, трябва да се създаде нов обект и да се присвои на променлива. Когато се създава обект, той винаги ще бъде присвоен на променливата, освен ако няма конструктор, който да хвърля изключение при грешка. Класовете трябва да бъдат дефинирани преди инстанцииране (а в някои случаи това е задължително).
Example #4 Създаване на инстанция
<?php
$instance = new SimpleClass();
?>
В контекста на клас може да се създаде нов обект посредством new self и new parent.
Когато се присвоява вече създадена инстанция на клас към нова променлива, новата променлива ще има достъп до същата инстанция като присвоения обект. Нещата стоят по същия начин и когато се предават инстанции към функции. Копие на вече създаден обект може да се създаде чрез клониране.
Example #5 Присвояване на обект
<?php
$assigned = $instance;
$reference =& $instance;
$instance->var = '$assigned ще приеме тази стойност';
$instance = null; // $instance и $reference приемат стойност null
var_dump($instance);
var_dump($reference);
var_dump($assigned);
?>
Примерът по-горе ще изведе:
NULL
NULL
object(SimpleClass)#1 (1) {
["var"]=>
string(30) "$assigned ще приеме тази стойност"
}
Даден клас може да наследи свойства и методи от друг клас, чрез използването на ключовата дума extends. Не се поддържа множествено наследяване, т.е. даден клас може да има само един базов клас.
Всички наследени свойства и методи могат да бъдат дефинирани отново, чрез повторното им дефиниране със същото име, с което са били дефинирани в родителския клас. Изключение се явяват случаите, когато в родителския клас даден метод е дефиниран като final. Достъпът до повторно дефинираните свойства или до статичните методи на родителския клас се осъществява чрез ключовата дума parent::
Example #6 Просто наследяване на клас
<?php
class ExtendClass extends SimpleClass
{
// Повторно дефиниране на родителския метод
function displayVar()
{
echo "Наследяване на клас\n";
parent::displayVar();
}
}
$extended = new ExtendClass();
$extended->displayVar();
?>
Примерът по-горе ще изведе:
Наследяване на клас стойност по подразбиране
Много разработчици на обектно-ориентирани приложения създават по един PHP файл за всеки клас. Едно от най-досадните неща е създаването на дълъг списък на файловете за включване в началото на всеки скрипт (по един за всеки клас).
В PHP 5 това вече не е необходимо. Можете да дефинирате функция __autoload, която се извиква автоматично, в случай че се опитате да използвате клас/интерфейс, който все още не е дефиниран. Извикването на тази функция е последната възможност на скриптовата машина да зареди този клас преди да бъде генерирана фатална грешка.
Забележка: Изключения, хвърлени от функцията __autoload, не могат да бъдат хванати в блока catch, в следствие на което се генерира фатална грешка.
Забележка: Автоматичното зареждане не е достъпно при използване на PHP в интерактивен режим CLI.
Забележка: Ако се използва име на клас като например при call_user_func(), то може да съдържа някои опасни знаци като ../. Препоръчително е да не използвате данни предоставени от потребителя в такива функции или поне да го проверявате във функцията __autoload().
Example #1 Пример за автоматично зареждане
В този пример се прави опит да се заредят класовете MyClass1 и MyClass2 от файловете MyClass1.php и съответно - MyClass2.php.
<?php
function __autoload($class_name) {
require_once $class_name . '.php';
}
$obj = new MyClass1();
$obj2 = new MyClass2();
?>
Example #2 Друг пример за автоматично зареждане
В този пример се прави опит за зареждане на интерфейс ITest.
<?php
function __autoload($name) {
var_dump($name);
}
class Foo implements ITest {
}
/*
string(5) "ITest"
Fatal error: Interface 'ITest' not found in ...
*/
?>
PHP 5 позволява на разработчиците да декларират конструктори на класовете. Класове, които имат метод-конструктор, извикват този метод при всяко създаване на нов обект, така че той е много подходящ за извършване на инициализации, от които обектът се нуждае преди да бъде използван.
Забележка: Конструкторите на родителските класове не се извикват автоматично, ако в даден дъщерен клас е дефиниран конструктор. За да се изпълни конструкторът на родителския клас, е необходимо да се извика parent::__construct() в тялото на конструктора на дъщерния клас.
Example #1 Използване на нови, унифицирани конструктори
<?php
class BaseClass {
function __construct() {
print "In BaseClass constructor\n";
}
}
class SubClass extends BaseClass {
function __construct() {
parent::__construct();
print "In SubClass constructor\n";
}
}
$obj = new BaseClass();
$obj = new SubClass();
?>
Поради обратната съвместимост, ако PHP 5 не може да намери в даден клас метод __construct(), той ще потърси конструктор дефиниран по начина, по който се дефинира конструктор в по-старите версии, т.е. чрез функция с името на самия клас. На практика това означава, че може да възникнат проблеми при съвместимостта, единствено ако класът е имал метод __construct(), който е имал друг смисъл.
В PHP 5 е въведен деструкторен метод, по подобие на другите обектно-ориентирани езици като C++. Деструкторът ще се извика в момента, в който обектът бъде унищожен.
Example #2 Пример за деструктор
<?php
class MyDestructableClass {
function __construct() {
print "In constructor\n";
$this->name = "MyDestructableClass";
}
function __destruct() {
print "Destroying " . $this->name . "\n";
}
}
$obj = new MyDestructableClass();
?>
Също както в случая с конструктора и тук деструкторът на родителския клас няма да бъде извикан автоматично. За да се изпълни деструкторът на родителския клас е необходимо изрично да се извика parent::__destruct() в тялото на деструктора.
Забележка: Деструкторите се извикват по време на спирането на скрипта, при което HTTP заглавките са изпратени. Работната директория по време на процеса на спирането на скрипта може да бъдат различна при някои SAPI-та (като например Apache).
Забележка: Опитът да се хвърли изключение в тялото на деструкто