Руководство по PHP

от:
Mehdi Achour
Friedhelm Betz
Antony Dovgal
Nuno Lopes
Hannes Magnusson
Georg Richter
Damien Seguy
Jakub Vrana
2023-09-30
Под редакцией: Peter Cowburn
от:
Алексей Шеин
Андрей Безруков
Максим Чабан
Александр Москалёв
Борис Клименко
Дмитрий Винярчук
Борис Флейтлих
Алексей Егоров
Юрий Бабиков
Михаил Баранов
Андрей Громов
Алексей Пыльцын
Сергей Пантелеев
Сергей Зорин
Евгений Четвериков

Авторские права

Авторские права © 1997 - 2023 принадлежат группе документирования PHP. Эти материалы могут быть распространены только на условиях и соглашениях, установленных в лицензии Creative Commons Attribution версии 3.0 или более поздней. Копия лицензии Creative Commons Attribution 3.0 распространяется вместе с руководством. Последняя на данный момент версия доступна по адресу » http://creativecommons.org/licenses/by/3.0/.

Если вы заинтересованы в распространении или публикации данного документа полностью или частично, с изменениями или без, и у вас есть вопросы, вы можете связаться с владельцами авторского права по адресу » doc-license@lists.php.net. Помните, что это адрес публичного списка рассылки.



Руководство по PHP


Предисловие

PHP, расшифровывающийся как "PHP: Hypertext Preprocessor" - «PHP: Препроцессор Гипертекста», является распространённым интерпретируемым языком общего назначения с открытым исходным кодом. PHP создавался специально для ведения веб-разработок и код на нем может внедряться непосредственно в HTML-код. Синтаксис языка берет начало из C, Java и Perl, и является лёгким для изучения. Основной целью PHP является предоставление веб-разработчикам возможности быстрого создания динамически генерируемых веб-страниц, однако область применения PHP не ограничивается только этим.

Это руководство состоит, главным образом, из справочника функций, а также содержит справочник языка, комментарии к наиболее важным из отличительных особенностей PHP, и другие дополнительные сведения.

Это руководство доступно в нескольких форматах по адресу » https://www.php.net/download-docs.php. Более подробную информацию о том, как ведётся работа над руководством, вы сможете получить обратившись к приложению Об этом руководстве. Если вам интересна история PHP, обратитесь к соответствующему приложению.

Авторы и Участники

Мы публикуем имена самых активных на данный момент участников разработки документации на первой странице, но есть ещё множество людей, которые помогают нам в процессе разработки или оказали неоценимую помощь в прошлом. Также, есть огромное количество людей, помогающих нам с помощью системы пользовательских замечаний, которые постоянно включаются в основную документацию. Все списки ниже отсортированы в алфавитном порядке.

Авторы и Редакторы

Следующие участники внесли значительный вклад в наполнение документации в прошлом: Bill Abt, Jouni Ahto, Alexander Aulbach, Stig Bakken, George Peter Banyard, Christoph M. Becker, Daniel Beckham, Nilgün Belma Bugüner, Jesus M. Castagnetto, Ron Chmara, Sean Coates, John Coggeshall, Simone Cortesi, Peter Cowburn, Daniel Egeberg, Markus Fischer, Wez Furlong, Sara Golemon, Rui Hirokawa, Brad House, Pierre-Alain Joye, Etienne Kneuss, Moriyoshi Koizumi, Rasmus Lerdorf, Andrew Lindeman, Stanislav Malyshev, Justin Martin, Rafael Martinez, Rick McGuire, Moacir de Oliveira Miranda Júnior, Kalle Sommer Nielsen, Yasuo Ohgaki, Philip Olson, Richard Quadling, Derick Rethans, Rob Richards, Sander Roobol, Egon Schmid, Thomas Schoefbeck, Sascha Schumann, Dan Scott, Masahiro Takagi, Yoshinari Takaoka, Yannick Torres, Michael Wallner, Lars Torben Wilson, Jim Winstead, Jeroen van Wolffelaar и Andrei Zmievski.

Следующие участники внесли значительный вклад в редактирование и корректирование документации в прошлом: Stig Bakken, Gabor Hojtsy, Hartmut Holzgraefe, Philip Olson и 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.

Другие переводчики

Наиболее активные переводчики присылавшие патчи: Spbima, Тигрович, Иван Ремень, Serg, Wolg, Degit, Nooneon, StelZek, Grul, Alexandr Fedotov, Marina Lagun, Mike, HaJIuBauKa, Sunny, dba, Александр Тушин.

Мы публикуем имена самых активных на данный момент переводчиков документации, но есть ещё множество людей, которые помогают нам. И каждый их перевод, поправка или совет ценен и важен.

Переводчики, ранее принимавшие участие в переводе руководства на русский язык (в алфавитном порядке): Alexander Voytsekhovskyy, Alexey Asemov, Andrey Demenev, Antony Dovgal, Boris Bezrukov, Daniil Reuzhkov, Evgeniy Syuzev, Irina Goble, Ivan Kovalenko, Jigkayev Kazbek, Kirill Barashkin, Olishuk Andrey, Veniamin Zolotukhin.

А также неизвестные переводчики со следующими никами: freespace, santiago, shafff, sveta.




Приступая к работе


Введение

Содержание


Что такое PHP?

PHP (рекурсивный акроним словосочетания PHP: Hypertext Preprocessor) - это распространённый язык программирования общего назначения с открытым исходным кодом. PHP специально сконструирован для веб-разработок и его код может внедряться непосредственно в HTML.

Простой ответ, но что он может означать? Вот пример кода:

Пример #1 Пример программирования на PHP

<!DOCTYPE html>
<html>
<head>
<title>Пример</title>
</head>
<body>

<?php
echo "Привет, я - скрипт PHP!";
?>

</body>
</html>

Вместо рутинного вывода HTML-кода командами языка (как это происходит, например, в Perl или C), скрипт PHP содержит HTML с встроенным кодом (в нашем случае, это вывод текста "Привет, я - скрипт PHP!"). Код PHP отделяется специальными начальным и конечным тегами <?php и ?>, которые позволяют "переключаться" в "PHP-режим" и выходить из него.

PHP отличается от JavaScript тем, что PHP-скрипты выполняются на сервере и генерируют HTML, который посылается клиенту. Если бы у вас на сервере был размещён скрипт, подобный вышеприведённому, клиент получил бы только результат его выполнения, но не смог бы выяснить, какой именно код его произвёл. Вы даже можете настроить свой сервер таким образом, чтобы обычные HTML-файлы обрабатывались процессором PHP, так что клиенты даже не смогут узнать, получают ли они обычный HTML-файл или результат выполнения скрипта.

PHP крайне прост для освоения, но вместе с тем способен удовлетворить запросы профессиональных программистов. Не пугайтесь длинного списка возможностей PHP. Вы можете быстро начать, и уже в течение нескольких часов сможете создавать простые PHP-скрипты.

Хотя PHP, главным образом, предназначен для работы в среде веб-серверов, область его применения не ограничивается только этим. Читайте дальше и не пропустите главу Возможности PHP либо, начните непосредственно с Вводного руководства, если вас интересует исключительно веб-программирование.



Возможности PHP

PHP может все. Главная область применения PHP - написание скриптов, работающих на стороне сервера; таким образом, PHP способен выполнять все то, что выполняет любая другая программа CGI, например, обрабатывать данные форм, генерировать динамические страницы или отсылать и принимать cookies. Но PHP способен выполнять намного больше.

Существуют три основных области применения PHP.

  • Создание скриптов для выполнения на стороне сервера. PHP традиционно и наиболее широко используется именно таким образом. Для этого вам будут необходимы три вещи. Интерпретатор PHP (в виде программы CGI или серверного модуля), веб-сервер и браузер. Для того чтобы можно было просматривать результаты выполнения PHP-скриптов в браузере, нужен работающий веб-сервер и установленный PHP. Просмотреть вывод PHP-программы можно в браузере, получив PHP-страницу, сгенерированную сервером. В случае, если вы просто экспериментируете, вы вполне можете использовать свой домашний компьютер вместо сервера. За более подробными сведениями обратитесь к главе Советы по установке.
  • Создание скриптов для выполнения в командной строке. Вы можете создать PHP-скрипт, способный запускаться без сервера или браузера. Все, что вам потребуется - парсер PHP. Такой способ использования PHP идеально подходит для скриптов, которые должны выполняться регулярно, например, с помощью cron (на платформах *nix или Linux) или с помощью планировщика задач (Task Scheduler) на платформах Windows. Эти скрипты также могут быть использованы в задачах простой обработки текстов. За дополнительной информацией обращайтесь к главе Использование PHP в среде командной строки.
  • Создание оконных приложений, выполняющихся на стороне клиента. Возможно, PHP является не самым лучшим языком для создания подобных приложений, но, если вы очень хорошо знаете PHP и хотели бы использовать некоторые его возможности в своих клиентских приложениях, вы можете использовать PHP-GTK для создания таких приложений. Подобным образом вы можете создавать и кросс-платформенные приложения. PHP-GTK является модулем PHP и не поставляется вместе с основным дистрибутивом PHP. Если вы заинтересованы, посетите » сайт PHP-GTK.

PHP доступен для большинства операционных систем, включая Linux, многие модификации Unix (такие как HP-UX, Solaris и OpenBSD), Microsoft Windows, macOS, RISC OS и многие другие. Также в PHP включена поддержка большинства современных веб-серверов, таких как Apache, IIS и многих других. В принципе, подойдёт любой веб-сервер, способный использовать бинарный файл FastCGI PHP, например, lighttpd или nginx. PHP может работать в качестве модуля или функционировать в качестве процессора CGI.

Таким образом, выбирая PHP, вы получаете свободу выбора операционной системы и веб-сервера. Более того, у вас появляется выбор между использованием процедурного или объектно-ориентированного программирования (ООП) или же их сочетания.

PHP способен генерировать не только HTML. Доступно формирование изображений, файлов PDF и даже роликов Flash (с использованием libswf и Ming), создаваемых «на лету». PHP также способен генерировать любые текстовые данные, такие, как XHTML и другие XML-файлы. PHP может осуществлять автоматическую генерацию таких файлов и сохранять их в файловой системе вашего сервера вместо того, чтобы отдавать клиенту, организуя, таким образом, серверный кеш для вашего динамического контента.

Одним из значительных преимуществ PHP является поддержка широкого круга баз данных. Создать скрипт, использующий базы данных, - невероятно просто. Можно воспользоваться модулем, специфичным для отдельной базы данных (таким как mysql) или использовать уровень абстракции от базы данных, такой как PDO, или подсоединиться к любой базе данных, поддерживающей Открытый Стандарт Соединения Баз Данных (ODBC), с помощью одноимённого модуля ODBC. Для других баз данных, таких как CouchDB, можно воспользоваться cURL или сокетами.

PHP также поддерживает взаимодействие с другими сервисами через такие протоколы, как LDAP, IMAP, SNMP, NNTP, POP3, HTTP, COM (на платформах Windows) и многих других. Кроме того, вы получаете возможность работать с сетевыми сокетами напрямую. PHP поддерживает стандарт обмена сложными структурами данных WDDX практически между всеми языками веб-программирования. Обращая внимание на взаимодействие между различными языками, следует упомянуть о поддержке объектов Java и возможности их использования в качестве объектов PHP.

PHP имеет много возможностей по обработке текста, включая регулярные выражения Perl (PCRE) и много других модулей и инструментов для обработки и доступа к XML-документам. В PHP обработка XML-документов стандартизирована и происходит на базе мощной библиотеки libxml2, расширив возможности обработки XML добавлением новых модулей SimpleXML, XMLReader и XMLWriter.

Есть ещё много других интересных модулей, которые можно просмотреть как в алфавитном порядке, так и по категориям. Есть ещё много дополнительных модулей PECL, которые также могут (а могут и нет) быть документированы в данном руководстве, такие как » XDebug.

Как вы видите, этой страницы не хватит для того, чтобы перечислить все, что может предложить вам PHP. Читайте следующую главу, Установка PHP и обратитесь к главе Справочник по функциям за более подробными сведениями о перечисленных выше модулях.




В этом кратком и простом учебнике мы бы хотели показать самые основы PHP. Этот текст включает в себя только создание динамических Web-страниц с помощью PHP, однако реальная область применения PHP гораздо шире. В разделе "Что может PHP" приведена дополнительная информация.

Web-страницы, созданные с использованием PHP, обрабатываются как обычные HTML-страницы. Их можно создавать и изменять точно таким же образом, как и обычные страницы на HTML.


Что мне потребуется?

В данном руководстве мы предполагаем, что ваш сервер имеет поддержку PHP и что все файлы, заканчивающиеся на .php, обрабатываются PHP. В большинстве серверов обычно используется это расширение для PHP-файлов, но всё-таки не лишним будет уточнить это у вашего администратора сервера. Итак, если ваш сервер поддерживает PHP, то у вас есть все, что требуется. Просто создавайте файлы .php и размещайте их в вашем каталоге Web-сервера - они будут обрабатываться автоматически. Не нужно ничего компилировать, не нужно никаких дополнительных программ. Считайте файлы PHP обычными файлами HTML с набором новых "волшебных" тегов, которые могут делать кучу разных вещей.

Например, вы хотите сэкономить на интернет-канале и вести разработку локально. В этом случае вам нужно будет установить веб-сервер, такой как » Apache, и, разумеется, » PHP. Скорее всего, вы также захотите установить базу данных, например, » MySQL.

Все это может быть установлено как отдельно друг от друга, так и более простым способом. В нашем руководстве есть инструкции по установке PHP (предполагается, что вы уже установили веб-сервер). Если у вас возникли проблемы при установке PHP, мы предлагаем вам задать вопросы в нашем » списке рассылки по вопросам установки. Если же вы выбрали более простой способ, то » найдите уже настроенный пакет для вашей операционной системы, который автоматически установит все вышеперечисленное несколькими кликами мыши. Устанавливать веб-сервер с поддержкой PHP довольно легко на любой операционной системе, включая MacOSX, Linux и Windows. На Linux вам, возможно, пригодятся » rpmfind и » PBone при поиске RPM-пакетов. Можно также использовать » apt-get для поиска пакетов под Debian.



Первая страница на PHP

Создайте файл с именем hello.php в корневом каталоге веб-сервера (DOCUMENT_ROOT) и запишите в него следующее:

Пример #1 Первый скрипт на PHP: hello.php

<!DOCTYPE html>
<html>
<head>
<title>Тестируем PHP</title>
</head>
<body>
<?php echo '<p>Привет, мир!</p>'; ?>
</body>
</html>

Откройте данный файл в браузере, набрав имя вашего веб-сервера и /hello.php. При локальной разработке эта ссылка может быть чем-то вроде http://localhost/hello.php или http://127.0.0.1/hello.php, но это зависит от настроек вашего сервера. Если всё настроено правильно, этот файл будет обработан PHP и браузер выведет следующий текст:

<!DOCTYPE html>
<html>
    <head>
        <title>Тестируем PHP</title>
    </head>
    <body>
        <p>Привет, мир!</p>
    </body>
</html>

Эта программа чрезвычайно проста, и для создания настолько простой странички даже необязательно использовать PHP. Все, что она делает, это вывод Hello World, используя инструкцию PHP echo. Заметьте, что файл не обязан быть выполняемым или ещё как-то отличаться от других файлов. Сервер знает, что этот файл должен быть обработан PHP, так как файл обладает расширением ".php", о котором в настройках сервера сказано, что подобные файлы должны передаваться PHP. Рассматривайте его как обычный HTML-файл, которому посчастливилось заполучить набор специальных тегов (доступных также и вам), способных на кучу интересных вещей.

Если у вас этот пример не отображает ничего или выводит окно загрузки, или если вы видите весь этот файл в текстовом виде, то, скорее всего, ваш веб-сервер не имеет поддержки PHP или был сконфигурирован неправильно. Попросите вашего администратора сервера включить такую поддержку. Предложите ему инструкцию по установке: раздел Установка данной документации. Если же вы разрабатываете скрипты на PHP дома (локально), то также прочтите эту главу, чтобы убедиться, что вы все настроили верно. Убедитесь также, что вы запрашиваете файл у сервера через протокол http. Если вы просто откроете файл из вашей файловой системы, он не будет обработан PHP. Если проблемы всё же остались, не стесняйтесь попросить помощи одним из » множества доступных способов получения поддержки по PHP.

Цель примера - показать формат специальных тегов PHP. В этом примере мы использовали <?php в качестве открывающего тега, затем шли команды PHP, завершающиеся закрывающим тегом ?>. Таким образом можно где угодно "запрыгивать" и "выпрыгивать" из режима PHP в HTML файле. Подробнее об этом можно прочесть в разделе руководства Основной синтаксис.

Замечание: Замечание о переводах строк

Переводы строк немногое означают в HTML, однако считается хорошей идеей поддерживать HTML в удобочитаемом виде, перенося его на новую строку. PHP автоматически удаляет перевод строки, идущий сразу после закрывающего тега ?>. Это может быть чрезвычайно полезно, если вы используете множество блоков PHP-кода или подключаете PHP-файлы, которые не должны ничего выводить. В то же время, это может приводить в недоумение. Можно поставить пробел после закрывающего тега ?> и тогда пробел будет выведен вместе с переводом строки, или же вы можете специально добавить перевод строки в последний вызов echo/print из блока PHP-кода.

Замечание: Пара слов о текстовых редакторах

Существует множество текстовых редакторов и интегрированных сред разработки (IDE), в которых вы можете создавать и редактировать файлы PHP. Список некоторых редакторов содержится в разделе » Список редакторов PHP. Если вы хотите порекомендовать какой-либо редактор, посетите данную страницу и попросите добавить редактор в список. Использование редактора с подсветкой синтаксиса может быть очень большим подспорьем в вашей работе.

Замечание: Пара слов о текстовых процессорах

Текстовые процессоры (StarOffice Writer, Microsoft Word, Abiword и др.) в большинстве случаев не подходят для редактирования файлов PHP. Если вы всё же хотите использовать какой-либо из них для тестового скрипта, убедитесь, что сохраняете файл как простой текст (plain text), иначе PHP будет не в состоянии прочесть и запустить ваш скрипт.

Теперь, когда вы успешно создали работающий PHP-скрипт, самое время создать самый знаменитый PHP-скрипт! Вызовите функцию phpinfo() и вы увидите множество полезной информации о вашей системе и настройке, такой как доступные предопределённые переменные, загруженные PHP-модули и параметры настройки. Уделите некоторое время изучению этой важной информации.

Пример #2 Получение информации о системе из PHP

<?php phpinfo(); ?>



Делаем что-нибудь полезное

Давайте сделаем что-нибудь полезное. К примеру, определим, какой браузер использует тот, кто смотрит в данный момент нашу страницу. Для этого мы проверим строку с именем браузера, посылаемую нам в HTTP-запросе. Эта информация хранится в переменной. Переменные в PHP всегда предваряются знаком доллара. Интересующая нас в данный момент переменная называется $_SERVER['HTTP_USER_AGENT'].

Замечание:

$_SERVER - специальная зарезервированная переменная PHP, которая содержит всю информацию, полученную от Web-сервера. Её также называют суперглобальной. Для более подробной информации смотрите раздел Суперглобальные переменные.

Для вывода данной переменной мы сделаем так:

Пример #1 Вывод значения переменной (элемента массива)

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

Пример вывода данной программы:

Mozilla/5.0 (Linux) Firefox/112.0

В PHP существует огромное количество типов переменных. В предыдущем примере мы печатали элемент массива. Массивы могут быть очень полезны.

$_SERVER - это просто одна из переменных, которые предоставляются вам языком PHP. Список таких переменных можно посмотреть в разделе "Зарезервированные переменные" или просмотрев вывод функции phpinfo(), используемой в примере в предыдущем разделе.

Внутрь PHP-тегов можно помещать несколько выражений и создавать маленькие блоки кода, делающие больше, чем простой вызов echo. Например, если вы хотите добавить проверку для Firefox, можно сделать так:

Пример #2 Пример использования управляющих структур и функций

<?php
if (str_contains($_SERVER['HTTP_USER_AGENT'], 'Firefox')) {
echo
'Вы используете Firefox.';
}
?>

Пример вывода данной программы:

Вы используете Firefox.

Здесь мы показали несколько новых элементов. Во-первых, здесь есть конструкция if. Если вы знакомы с основами синтаксиса языка C, то вы уже заметили что-то схожее. Если же вы не знаете C или подобного по синтаксису языка, то лучший вариант - взять какую-либо вводную книжку по PHP и прочитать первые пару глав. Другой вариант - почитать раздел Описание языка данного руководства.

Кроме этого, здесь присутствует вызов функции str_contains(). str_contains() - встроенная в PHP функция, которая определяет, содержит ли данная строка другую строку. В данном случае мы ищем строку 'Firefox' (так называемую "иголку" - needle) в $_SERVER['HTTP_USER_AGENT'] (в так называемом "сене" - haystack). Если "иголка" найдена внутри "сена", функция возвращает true. В противном случае она возвращает false. Если она вернёт true, то условие в if окажется истинным (true), и код в фигурных скобках ({ }) выполнится. В противном случае этот код не выполняется. Попробуйте создать аналогичные примеры с использованием команд if, else и других функций, таких, как strtoupper() и strlen(). Также подобные примеры содержатся во многих описаниях функций в данном руководстве. Если вы не знаете, как использовать функции, возможно, вам стоит прочесть страницу руководства о том, как читать определения функций и раздел о функциях в PHP.

Продемонстрируем, как можно входить в режим кода PHP и выходить из него даже прямо посередине блока с кодом:

Пример #3 Смешение режимов HTML и PHP

<?php
if (str_contains($_SERVER['HTTP_USER_AGENT'], 'Firefox')) {
?>
<h3>str_contains() возвращает true</h3>
<p>Вы используете Firefox</p>
<?php
} else {
?>
<h3>str_contains() возвращает false</h3>
<p>Вы не используете Firefox</p>
<?php
}
?>

Пример вывода данной программы:

<h3>str_contains() возвращает true</h3>
<p>Вы используете Firefox</p>

Вместо использования команды PHP echo для вывода, мы вышли из режима кода и просто послали содержимое HTML. Важный момент здесь то, что логическая структура кода PHP при этом не теряется. Только одна HTML-часть будет послана клиенту в зависимости от результата функции str_contains() (другими словами, в зависимости от того, найдена была строка Firefox или нет).



Работа с формами

Одно из главнейших достоинств PHP - то, как он работает с формами HTML. Здесь основным является то, что каждый элемент формы автоматически становится доступным вашим программам на PHP. Для подробной информации об использовании форм в PHP читайте раздел Переменные из внешних источников. Вот пример формы HTML:

Пример #1 Простейшая форма HTML

<form action="action.php" method="post">
    <label for="name">Ваше имя:</label>
    <input name="name" id="name" type="text">

    <label for="age">Ваш возраст:</label>
    <input name="age" id="age" type="number">

    <button type="submit">Submit</button>
</form>

В этой форме нет ничего особенного. Это обычная форма HTML без каких-либо специальных тегов. Когда пользователь заполнит форму и нажмёт кнопку отправки, будет вызвана страница action.php. В этом файле может быть что-то вроде:

Пример #2 Выводим данные формы

Здравствуйте, <?php echo htmlspecialchars($_POST['name']); ?>.
Вам <?php echo (int)$_POST['age']; ?> лет.

Пример вывода данной программы:

Здравствуйте, Сергей. Вам 30 лет.

Если не принимать во внимание куски кода с htmlspecialchars() и (int), принцип работы данного кода должен быть прост и понятен. htmlspecialchars() обеспечивает правильную кодировку "особых" HTML-символов так, чтобы вредоносный HTML или Javascript не был вставлен на вашу страницу. Поле age, о котором нам известно, что оно должно быть число, мы можем просто преобразовать в int, что автоматически избавит нас от нежелательных символов. PHP также может сделать это автоматически с помощью модуля filter. Переменные $_POST['name'] и $_POST['age'] автоматически установлены для вас средствами PHP. Ранее мы использовали суперглобальную переменную $_SERVER, здесь же мы точно так же используем суперглобальную переменную $_POST, которая содержит все POST-данные. Заметим, что метод отправки (method) нашей формы - POST. Если бы мы использовали метод GET, то информация нашей формы была бы в суперглобальной переменной $_GET. Кроме этого, можно использовать переменную $_REQUEST, если источник данных не имеет значения. Эта переменная содержит смесь данных GET, POST, COOKIE.

В PHP можно также работать и с XForms, хотя вы найдёте работу с обычными HTML-формами довольно комфортной уже через некоторое время. Несмотря на то, что работа с XForms не для новичков, они могут показаться вам интересными. В разделе возможностей PHP у нас также есть короткое введение в обработку данных из XForms.



Что дальше?

То, что вы узнали, поможет вам понять большую часть руководства и разобраться в большинстве приведённых примеров программ.

Если вы хотите посмотреть различные презентации и слайды, шире раскрывающие возможности PHP, вы можете посетить сайт с материалами PHP конференций: » http://talks.php.net/





Установка и настройка


Общие инструкции по установке

Перед началом установки вы должны знать, для чего вы хотите использовать PHP. Вы можете использовать PHP для целей, описанных в разделе Что может PHP?

  • Создавать веб-сайты и веб-приложения (Скрипты на стороне сервера)
  • Скрипты командной строки
  • GUI-приложения (Приложения с графическим интерфейсом пользователя)

Для первой и наиболее распространённой цели вам нужны три вещи: Сам PHP, веб-сервер и веб-браузер. Вероятно, у вас уже есть веб-браузер и, в зависимости от настроек вашей операционной системы, вы также можете иметь и веб-сервер (например, Apache в Linux и macOS; IIS в Windows). Также вы можете арендовать веб-сервер или некоторое дисковое пространство на веб-сервере. В этом случае вам не нужно устанавливать дополнительное программное обеспечение, только писать PHP-скрипты, загружать их на сервер и просматривать результат их работы в браузере.

В случае установки сервера и PHP самостоятельно у вас есть два варианта установки PHP. Для многих серверов PHP может быть установлен как модуль сервера. Это возможно для таких серверов, как Apache, Microsoft Internet Information Server, Netscape и iPlanet. Если PHP не поддерживает интерфейс для вашего сервера, вы всегда можете использовать его как обработчик CGI или FastCGI. Это означает, что вы должны настроить ваш сервер так, чтобы он исполнял все PHP файлы, как CGI-скрипты.

Если вы также собираетесь использовать PHP в командной строке (для генерации изображений, обработки текстов и т.д.), то вам понадобится PHP CLI. Подробнее об этом можно прочитать в разделе Использование PHP в командной строке. В этом случае вам не понадобятся ни сервер, ни браузер.

Вы также можете создавать приложения с графическим интерфейсом, используя при этом модуль PHP-GTK. Это требует абсолютно другого подхода, чем программирование под Веб, т.к. вы не выводите HTML или текст, а управляете окнами при помощи PHP. Для получения более полной информации о PHP-GTK » посетите сайт, посвящённый этому модулю . PHP-GTK не включён в стандартную поставку PHP.

Начиная с этого момента мы будем описывать установку PHP для веб-серверов на Unix и Windows, как модуля сервера и как CGI. Вы также можете найти информацию об использовании PHP в командной строке в следующих разделах.

Исходные коды и бинарные сборки для Windows можно получить здесь: » https://www.php.net/downloads.php.



Установка на Unix-системы

Содержание

Этот раздел описывает установку и настройку PHP на Unix-системах. Пожалуйста, прочитайте все разделы, касающиеся вашей платформы или веб-сервера, прежде чем вы приступите к установке.

Как сказано в разделе Общие указания по установке, в этом разделе в основном мы описываем установку PHP, ориентированную на веб, однако мы также затрагиваем установку PHP для использования в командной строке.

Есть несколько способов установки PHP на Unix платформы. Один из них - процесс конфигурирования и компиляции исходников, другой - установка из пакетов. Этот документ сфокусирован на установке из исходных кодов. Много Unix-подобных систем имеют различные системы установки программ из пакетов. Они могут помочь при установке стандартных конфигураций, но если вам необходимы другие варианты (такие как безопасный сервер или другой драйвер базы данных), вам может потребоваться скомпилировать PHP и/или ваш веб-сервер. Если вы незнакомы с компилированием собственного программного обеспечения, то, может быть, стоит поискать готовый пакет PHP с нужными вам возможностями, собранный кем-нибудь ещё.

Для компиляции PHP из исходных кодов вам потребуется следующее:

  • Базовые знания Unix (способность обращаться с "make" и компилятором C)
  • Компилятор ANSI C
  • Веб-сервер
  • Любые компоненты, специфичные для отдельных модулей PHP (такие как библиотеки GD, PDF и т.д.)

При сборке непосредственно из исходников Git или после ручных изменений вам может также понадобиться:

  • autoconf: 2.59+ (для PHP >= 7.0.0), 2.64+ (для PHP >= 7.2.0)
  • automake: 1.4+
  • libtool: 1.4.x+ (кроме версии 1.4.2)
  • re2c: 0.13.4+
  • bison:
    • PHP 7.0 - 7.3: 2.4 и выше (включая Bison 3.x)
    • PHP 7.4: > 3.0

Общая (или начальная) конфигурация PHP задаётся параметрами скрипта configure. Вы можете просмотреть список допустимых параметров вместе с их кратким пояснением при помощи команды ./configure --help. Различные опции документированы в данном руководстве отдельно, список основных параметров можно просмотреть в приложении Основные параметры конфигурации, тогда как параметры, специфичные для различных модулей, описаны на страницах документации, посвящённых этим модулям.

Когда PHP сконфигурирован, все готово к сборке модулей и/или исполняемых файлов. Об этом должна позаботиться команда make. Если что-то не получилось и вы не можете понять почему, смотрите раздел Проблемы установки.

Замечание:

Некоторые Unix системы (такие как OpenBSD и SELinux) могут запрещать, из соображений безопасности, выделение памяти одновременно как записываемой и исполняемой. Это называется PaX MPROTECT или нарушение защиты W^X. Тем не менее, такой режим выделения памяти необходим для поддержки JIT компиляции PCRE JIT, так что в таких случаях необходимо собирать PHP без поддержки JIT компиляции PCRE, либо бинарные файлы должны быть внесены в белый список операционной системы,

Замечание: Кросс-компиляция под ARM с помощью "Android toolchain" на данный момент не поддерживается.


Apache 2.x на Unix системах

Этот раздел описывает установку PHP c Apache 2.x на Unix системах.

Внимание

Мы не рекомендуем использовать потоковый MPM в промышленной среде вместе с Apache 2. Вместо этого, используйте prefork MPM, используемый по умолчанию в Apache 2.0 и 2.2. Подробную информацию по этому вопросу вы можете найти в соответствующем разделе FAQ Apache2 и потоковый MPM

Самым авторитетным источником информации по Apache 2.x является » документация Apache. Более подробная информация о настройках при установке может быть найдена там.

Самая последняя версия Apache Http Server может быть получена на » странице загрузки Apache, а адрес соответствующей версии PHP был указан выше. Это краткое руководство описывает лишь базовую установку Apache 2.x и PHP. Для получения более детальной информации прочитайте » документацию Apache. В инструкции ниже опущены номера версий - замените 'NN' на номер, соответствующий скачанной вами версии Apache.

На данный момент есть две версии Apache 2.x - 2.4 и 2.2. Хотя для выбора каждой из них существуют отдельные доводы, 2.4 является наиболее свежей и рекомендуемой версией, если вас устраивает такой выбор. Тем не менее, данные инструкции будут работать как для 2.4, так и для 2.2. Обратите внимание, что Apache httpd 2.2 официально больше не поддерживается, поэтому дальнейшая разработка не будет продолжаться, также как и приниматься новые патчи.

  1. Скачайте Apache HTTP server как было указано выше и распакуйте его:

    tar -xzf httpd-2.x.NN.tar.gz
    
  2. Аналогично, скачайте и распакуйте исходные коды PHP:

    tar -xzf php-NN.tar.gz
    
  3. Скомпилируйте и установите Apache. Более подробную информацию по сборке Apache смотрите в его документации.

    cd httpd-2_x_NN
    ./configure --enable-so
    make
    make install
    
  4. Теперь ваш Apache 2.x.NN доступен как /usr/local/apache2, сконфигурирован с поддержкой подгружаемых модулей и стандартным мульти-процессным модулем (MPM) prefork. Чтобы протестировать правильность установки используйте стандартную процедуру запуска Apache, такую как:

    /usr/local/apache2/bin/apachectl start
    
    Затем остановите сервер, чтобы сконфигурировать и установить PHP:
    /usr/local/apache2/bin/apachectl stop
    

  5. Теперь мы сконфигурируем и соберём PHP. Здесь вы можете настроить установку PHP с помощью различных опций, указывающих, например, какие модули нужно включить. Просмотрите вывод команды ./configure --help для получения полного списка параметров конфигурации. В нашем примере мы сконфигурируем PHP очень просто - с поддержкой Apache и MySQL.

    Если вы собирали Apache из исходников, как было описано выше, то используйте путь до apxs как указано в следующем примере, иначе, корректируйте этот путь соответствующим вашей установке образом. Учтите также, что в некоторых дистрибутивах apxs может иметь имя apxs2.

    cd ../php-NN
    ./configure --with-apxs2=/usr/local/apache2/bin/apxs --with-pdo-mysql
    make
    make install
    

    Если вы решите изменить параметры конфигурации после установки, вам надо будет повторить только три последних шага (configure, make, make install). Вам нужно будет только перезапустить Apache, чтобы новые модули подгрузились и начали работать. Перекомпиляция Apache для этого не требуется.

    Заметьте, что если не указано обратное, то 'make install' установит так же PEAR, различные инструменты PHP - такие как phpize, версию PHP для командной строки (PHP CLI) и т.д.

  6. Настройка вашего php.ini

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

    Вероятно, вы захотите изменить некоторые настройки в php.ini. Если вы предпочитаете держать файл php.ini в другом месте, используйте параметр --with-config-file-path=/some/path в шаге 5.

    Если же вы используете php.ini-production, прочитайте его, чтобы знать какие изменения в поведении PHP это повлечёт.

  7. Отредактируйте ваш httpd.conf, чтобы Apache загружал модуль PHP. Путь в правой части инструкции LoadModule должен указывать на модуль PHP. Команда make install может добавить эту инструкцию автоматически, но этого может и не произойти, поэтому проверьте, чтобы убедиться.

    Для PHP 8:

    LoadModule php_module modules/libphp.so

    Для PHP 7:

    LoadModule php7_module modules/libphp7.so
  8. Теперь следует сконфигурировать Apache, чтобы он передавал файлы с некоторыми расширениями на обработку модулю PHP. В нашем примере сделаем это для .php файлов. Вместо обычного использования директивы Apache AddType, мы хотим избежать интерпретации как PHP потенциально опасных загрузок и файлов наподобие exploit.php.jpg. С помощью данного примера можно указать для интерпретации PHP любые расширения, просто добавив их в конец списка. Продемонстрируем это на расширении .php.

    <FilesMatch \.php$>
        SetHandler application/x-httpd-php
    </FilesMatch>

    Или, если мы хотим добавить расширения .php, .php2, .php3, .php4, .php5, .php6 и .phtml, это можно записать так:

    <FilesMatch "\.ph(p[2-6]?|tml)$">
        SetHandler application/x-httpd-php
    </FilesMatch>

    Чтобы PHP отображал содержимое файлов .phps с подсветкой синтаксиса, нужно внести соответствующую директиву

    <FilesMatch "\.phps$">
        SetHandler application/x-httpd-php-source
    </FilesMatch>

    Можно использовать mod_rewrite для отображения любого .php файла с подсветкой синтаксиса, без нужды его переименования в .phps:

    RewriteEngine On
    RewriteRule (.*\.php)s$ $1 [H=application/x-httpd-php-source]

    Данный фильтр, отображающий исходный код, должен быть отключён в промышленном использовании, так как он может открыть конфиденциальную или другую важную информацию, включённую в исходный код.

  9. Используйте стандартную процедуру запуска Apache, например:

    /usr/local/apache2/bin/apachectl start
    

    ИЛИ

    service httpd restart
    

Если вы следовали инструкциям выше, то на данном этапе должны иметь запущенный веб-сервер Apache2 с поддержкой PHP, как модуля SAPI. Конечно, для PHP и Apache доступно гораздо больше параметров конфигурации. Используйте ./configure --help в соответствующей папке с исходными кодами для получения полного списка параметров конфигурации.

Если вы хотите собрать многопоточную версию Apache, то при сборке вам следует указать модуль MPM worker вместо стандартного модуля MPM prefork. Чтобы сделать это, нужно добавить следующий аргумент к ./configure на шаге 3:

--with-mpm=worker

Не следует бездумно использовать эту настройку, используйте её только если вы понимаете все последствия этого решения. Документация Apache по » модулям MPM значительно глубже раскрывает эту тему.

Замечание:

Если вы хотите использовать зависимый контент (content negotiation), прочитайте Apache MultiViews FAQ.

Замечание:

Для сборки многопоточной версии Apache, ваша система должна поддерживать потоки. Это так же подразумевает сборку PHP c поддержкой Zend Thread Safety (ZTS). И, как следствие, не все модули PHP смогут работать. Рекомендуется установка Apache с модулем MPM по умолчанию - prefork.



Установка Nginx 1.4.x на систему Unix

Данная документация описывает процесс установки и настройки PHP с PHP-FPM для Nginx 1.4.x HTTP сервера.

Данное руководство подразумевает, что вы собрали Nginx из исходников, следовательно, все бинарные файлы и файлы конфигурации располагаются в /usr/local/nginx. Если нет, и вы получили Nginx другим способом, тогда, пожалуйста, обратитесь к » Nginx Wiki, чтобы перевести данное руководство для вашей установки.

Данное руководство охватывает азы настройки Nginx сервера, для обработки PHP приложений и отображения их на порту 80. Рекомендуется изучить документацию Nginx и PHP-FPM, если вы хотите оптимизировать вашу установку за рамками данной документации.

Пожалуйста, обратите внимание, что во всей данной документации номера версий были заменены на 'x', чтобы данная документация оставалась корректной в будущем. Пожалуйста, замените 'x' на необходимый вам номер версии.

  1. Рекомендуется посетить » страницу установки на Nginx Wiki, для информации о получении и установке Nginx.

  2. Получение и распаковка исходники PHP:

    tar zxf php-x.x.x
    
  3. Настройка и сборка PHP. В этом разделе описывается настройка и сборка PHP из исходных кодов. Запустите ./configure --help для получения списка доступных опций. В нашем примере мы сделаем простые настройки с PHP-FPM и поддержкой MySQLi.

    cd ../php-x.x.x
    ./configure --enable-fpm --with-mysqli
    make
    sudo make install
    
  4. Перемещение файлов настройки в нужные директории

    cp php.ini-development /usr/local/php/php.ini
    cp /usr/local/etc/php-fpm.d/www.conf.default /usr/local/etc/php-fpm.d/www.conf
    cp sapi/fpm/php-fpm /usr/local/bin
    
  5. Важно, что мы запрещаем Nginx от отправлять запросы в бэкенд PHP-FPM, если файл не существует, что помогает избежать атаки инъекции скрипта.

    Мы может исправить это путём установки директивы cgi.fix_pathinfo равной 0 в нашем php.ini файле.

    Редактирование php.ini:

    vim /usr/local/php/php.ini
    

    Найдите опцию cgi.fix_pathinfo= и измените её следующим образом:

    cgi.fix_pathinfo=0
    
  6. php-fpm.conf должен быть модифицирован, чтобы точно определить, что php-fpm должен работать под пользователем www-data и группой www-data до того, как мы запустим сервис:

    vim /usr/local/etc/php-fpm.d/www.conf
    

    Найдите и измените следующее:

    ; Unix user/group of processes
    ; Замечание: Пользователь является обязательным. Если группа не установлена,
    ; то будет использована стандартная группа пользователя.
    user = www-data
    group = www-data
    

    Теперь можно запускать сервис php-fpm:

    /usr/local/bin/php-fpm
    

    Более в этом руководстве мы не будет касаться настройки php-fpm. Если вам необходимо произвести дополнительные настройки - обратитесь к документации по php-fpm.

  7. Теперь Nginx должен быть настроен на поддержку выполнения PHP:

    vim /usr/local/nginx/conf/nginx.conf
    

    Измените блок "location", заданный по умолчанию, так, чтобы можно было обрабатывать .php файлы:

    location / {
        root   html;
        index  index.php index.html index.htm;
    }

    Следующий шаг - убедиться, что .php файлы отправляются в бэкенд PHP-FPM. Введите следующее:

    location ~* \.php$ {
        fastcgi_index   index.php;
        fastcgi_pass    127.0.0.1:9000;
        include         fastcgi_params;
        fastcgi_param   SCRIPT_FILENAME    $document_root$fastcgi_script_name;
        fastcgi_param   SCRIPT_NAME        $fastcgi_script_name;
    }

    Перезапустите Nginx.

    sudo /usr/local/nginx/sbin/nginx -s stop
    sudo /usr/local/nginx/sbin/nginx
    
  8. Создайте тестовый файл

    rm /usr/local/nginx/html/index.html
    echo "<?php phpinfo(); ?>" >> /usr/local/nginx/html/index.php
    

    Теперь откройте в браузере http://localhost. Должна отобразиться информация phpinfo().

Следуя вышеуказанным шагам, вы получите рабочий Nginx сервер с поддержкой PHP как модуля FPM SAPI. Конечно, доступно большое число опций настроек для Nginx и PHP. Для более подробной информации наберите ./configure --help в соответствующем дереве исходных кодов.



Установка PHP на Lighttpd 1.4 на Unix-системах

Этот раздел содержит информацию по установке PHP на Unix-системы с сервером Lighttpd 1.4.

Прочитайте, пожалуйста, инструкции по установке Lighttpd в » документации по Lighttpd перед установкой PHP.

FastCGI - предпочитаемый интерфейс для связи PHP и Lighttpd. FastCGI доступен по умолчанию в php-cgi.

Управление процессами php через Lighttpd

Для настройки Lighttpd на соединение с PHP и порождения процессов FastCGI необходимо отредактировать конфигурационный файл lighttpd.conf. Предпочтительнее подключаться к процессам FastCGI используя Unix-сокеты.

Пример #1 Пример части файла 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
  ))
)

Директива bin-path позволяет lighttpd динамически запускать процессы FastCGI. Lighttpd будет динамически создавать дочерние процессы php, согласно переменной окружения PHP_FCGI_CHILDREN. Директива bin-environment задаёт настройки для дочерних процессов. PHP_FCGI_MAX_REQUESTS определяет порог, при достижении которого PHP завершит дочерний процесс. Директив min-procs и max-procs обычно стоит избегать. PHP управляет только своими дочерними процессами, и инструменты кеширования в байт-код (например, APC) будут использоваться только в этих дочерних процессах. Если значение min-procs установлено больше 1, общее количество процессов, обрабатывающих запросы, будет равно PHP_FCGI_CHILDREN * min-procs.

Управление процессами с помощью spawn-fcgi

Lighttpd предоставляет программу spawn-fcgi для облегчения управления дочерними процессами FastCGI.

Управление процессами с помощью php-cgi

Управлять процессами можно и без spawn-fcgi, но это потребует некоторых доработок. Переменная окружения PHP_FCGI_CHILDREN указывает количество дочерних процессов, запускаемых PHP для обработки входящих запросов. Переменная PHP_FCGI_MAX_REQUESTS отвечает за количество запросов, которые обработает один процесс. Ниже приведён простой bash-скрипт, облегчающий создание дочерних процессов.

Пример #2 Создание FastCGI-обработчиков

#!/bin/sh

# Местоположение бинарного файла php-cgi
PHP=/usr/local/bin/php-cgi

# Местоположение PID-файла
PHP_PID=/tmp/php.pid

# Привязка к адресу
#FCGI_BIND_ADDRESS=10.0.1.1:10000
# Привязка к сокету
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"

Подключение к удалённым процессам FCGI

Обработчики FastCGI могут находиться на нескольких отдельных машинах для масштабирования нагрузки.

Пример #3 Подключение к удалённым процессам fastcgi

fastcgi.server = ( ".php" =>
   (( "host" => "10.0.0.2", "port" => 1030 ),
    ( "host" => "10.0.0.3", "port" => 1030 ))
)


Веб-сервер LiteSpeed/OpenLiteSpeed на системах Unix

LiteSpeed PHP - это оптимизированная сборка PHP для работы с продуктами LiteSpeed через LiteSpeed SAPI. LSPHP запускается как самостоятельный процесс и имеет отдельный исполняемый файл, который используется как обычный исполняемый файл командной строки для запуска скриптов PHP.

LSAPI - это очень оптимизированный API, позволяющий LiteSpeed взаимодействовать с веб-движками других производителей. Он имеет тот же протокол, что и FCGI, но гораздо более эффективный.

Эта документация содержит инструкции по установке и конфигурированию PHP с LSAPI для веб-серверов LiteSpeed (LSWS) )и OpenLiteSpeed (OLS).

Это руководство предполагает, что LSWS или OLS установлены по стандартным путям и со стандартными флагами. Директория установки по умолчанию для обоих веб-серверов - /usr/local/lsws, и оба они запускаются из её подкаталога bin.

Обратите внимание, что во всей документации номера версий заменены на x, что говорит о том, что эта документация останется актуальной и в будущем. Так что смело можете заменить эти символы на номер вашей версии.

  1. Для получения и установки LSWS и OLS посетите сайт с документацией по LiteSpeed Web Server - » инструкции по установке или сайт с документацией по OpenLiteSpeed - » инструкции по установке.

  2. Загрузите и распакуйте исходные коды PHP:

    mkdir /home/php
    cd /home/php
    wget http://us1.php.net/get/php-x.x.x.tar.gz/from/this/mirror
    tar -zxvf php-x.x.x.tar.gz
    cd php-x.x.x
    
  3. Сконфигурируйте и соберите PHP. На этом этапе можно воспользоваться дополнительными опциями для более тонкой настройки PHP и добавления необходимых модулей. Запустите ./configure --help для получения списка возможных опций. В нижеследующем примере используются стандартные рекомендованные настройки для LSWS:

    ./configure ... '--with-litespeed'
    make
    sudo make install
    
  4. Проверьте установку LSPHP

    Один из самых простых путей для проверки корректности установки PHP - это запустить следующие команды:

    cd /usr/local/lsws/fcgi-bin/
    ./lsphp5 -v
    

    Должна появиться информация о сборке PHP:

    PHP 5.6.17 (litespeed) (built: Mar 22 2016 11:34:19)
    Copyright (c) 1997-2014 The PHP Group
    Zend Engine v2.6.0, Copyright (c) 1998-2015 Zend Technologies
    

    Обратите внимание на слово litespeed. Это означает, что PHP собран с поддержкой LSAPI.

После выполнения описанных выше шагов, LSWS/OLS должны запускаться с поддержкой PHP как модуля SAPI. Существует достаточно много дополнительных опций конфигурации для настройки работы LSWS / OLS c PHP. Более подробно почитать о них можно на сайте с документацией по LiteSpeed в разделе » PHP.

Использование LSPHP из командной строки:

Режим командной строки LSPHP(LSAPI + PHP) используется для обработки скриптов PHP запущенных на удалённом сервере без необходимости держать на нем веб-сервер. Это используется для обработки скриптов PHP на локальном веб-сервере (раздельно). Такая установка удобна для удобства масштабирования, так как нагрузка по обработке скриптов ложится на удалённый сервер.

Запустите lsphp из командной строки на удалённом сервере: LSPHP - является исполняемым файлом, может быть запущен вручную и привязан к IPv4, IPv6 или сокету Unix с помощью опции -b socket_address.

Пример:

Привязка LSPHP к порту 3000 на всех интерфейсах IPv4 и IPv6:

/path/to/lsphp -b [::]:3000

Привязка LSPHP к 3000 всех интерфейсов IPv4:

/path/to/lsphp -b *:3000

Привязка LSPHP к 192.168.0.2:3000:

/path/to/lsphp -b 192.168.0.2:3000

Привязка LSPHP к сокету Unix /tmp/lsphp_manual.sock с возможностью получать из него запросы:

/path/to/lsphp -b /tmp/lsphp_manual.sock

Перед запуском LSPHP можно выставить переменные окружения:

PHP_LSAPI_MAX_REQUESTS=500 PHP_LSAPI_CHILDREN=35 /path/to/lsphp -b IP_address:port

На данный момент LiteSpeed PHP можно использовать с веб-серверами LiteSpeed, OpenLiteSpeed и Apache mod_lsapi. Подробности о конфигурации сервера читайте на страницах » LiteSpeed Web Server и » OpenLiteSpeed.

LSPHP можно установить различными способами.

CentOS: На CentOS, LSPHP может быть установлен из репозиториев LiteSpeed или Remi, используя » RPM.

Debian: На Debian, LSPHP можно поставить из репозитория LiteSpeed, используя » apt.

cPanel: Для установки с cPanel и LSWS/OLS используя EasyApache 4, читайте соответствующую » документацию.

Plesk: Plesk можно использовать с LSPHP на CentOS, CloudLinux, Debian и Ubuntu. Более подробно описано в » документации



Установка с интерфейсами CGI и командной строки

По умолчанию, PHP собирается одновременно как CLI и CGI программа, которая может быть использована для обработки CGI-запросов. PHP как модуль сервера выигрывает в производительности, однако PHP CGI позволяет запускать PHP от пользователя, отличного от того, под которым исполняется сервер.

Внимание

Используя установку CGI, ваш сервер открыт перед несколькими возможными уязвимостями. Пожалуйста, ознакомьтесь с разделом "Безопасность CGI" чтобы узнать, как можно защитить себя от таких атак.

Тестирование

Если вы собрали PHP как CGI, вы можете протестировать вашу сборку командой make test. Тестирование вашей сборки - всегда хорошая идея. Таким образом вы сможете раньше обнаружить проблемы PHP на вашей платформе, вместо того, чтобы бороться с ними позже.

Использование переменных

Некоторые переменные окружения сервера не определены в текущей » спецификации CGI/1.1. Определены только следующие переменные: 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 и SERVER_SOFTWARE. Все остальное должно обрабатываться как дополнительные модули (vendor extensions).



OpenBSD, замечания по установке

Эта секция содержит замечания и советы, касающиеся установки PHP на » OpenBSD.

Использование бинарных пакетов

Использование бинарных пакетов для установки PHP на OpenBSD - это простейший и рекомендованный способ. Ядро (основной пакет) отделено от различных модулей, но каждый из них может быть установлен или удалён независимо от другого. Файлы, которые вам понадобятся, вы можете найти на вашем OpenBSD CD или на FTP.

Основной пакет, который необходимо установить - это php, он содержит базовый движок (плюс fpm, gettext и iconv) и может быть доступен в нескольких версиях на выбор. Далее, обратите внимание на пакеты модулей, такие как php-mysqli или php-imap. Вам следует использовать команду phpxs для активации или деактивации этих модулей в вашем php.ini.

Пример #1 Пример установки пакетов в OpenBSD

# pkg_add php
# pkg_add php-apache
# pkg_add php-mysqli
  (install the PEAR libraries)
# pkg_add pear

Следуйте инструкциям, выводимым пакетами во время установки!

  (to remove packages)
# pkg_delete php
# pkg_delete php-apache
# pkg_delete php-mysqli
# pkg_delete pear

Читайте страницу руководства » packages(7) для большей информации о бинарных пакетах в OpenBSD.

Использование портов

Вы можете также скомпилировать PHP из исходников, используя » дерево портов. Тем не менее, этот способ рекомендован только для тех, кто хорошо знакомых с OpenBSD. Порт PHP разбит на ядро и модули. Модули генерируют подпакеты для всех поддерживаемых модулей PHP. Если какие-либо из них вам не нужны, используйте FLAVOR no_*. Например, для пропуска модуля imap, установите FLAVOR в no_imap.

Стандартные проблемы

  • Apache и Nginx более не являются веб-серверами по умолчанию для OpenBSD, но их очень легко найти и поставить из портов и пакетов. Новый сервер по умолчанию называется 'httpd'.
  • Стандартная установка httpd работает в » chroot(2) окружении, что запрещает PHP доступ к файлам вне /var/www. Так что вам понадобится создать директорию /var/www/tmp для сохранения сессионных файлов PHP, или использовать альтернативный бэкенд для управления сессиями. К тому же, сокеты баз данных будет необходимо размещать в chroot, либо слушать на интерфейсе localhost. Если вы используете функции работы с сетью, некоторые файлы из /etc, такие как /etc/resolv.conf и /etc/services необходимо будет поместить в /var/www/etc. В OpenBSD, пакет PEAR автоматически устанавливается в правильные директории chroot.
  • Пакет модуля » gd для OpenBSD требует установки Xorg. Если он ещё не установлен при базовой установке путём добавления набора файлов xbase.tgz, его можно добавить после установки (смотрите » OpenBSD FAQ#4).


Инструкции по инсталляции для ОС Solaris

Данный раздел содержит инструкции и советы для установки PHP на ОС Solaris.

Требования к программному обеспечению

Зачастую в составе операционной системы Solaris отсутствует компиляторы языка C и сопутствующие им утилиты. Ознакомьтесь с этим FAQ, чтобы узнать, почему необходимо использовать GNU-версии этих утилит.

Для распаковки дистрибутива PHP вам понадобится

  • tar
  • gzip или
  • bzip2

Для компиляции PHP вам понадобится

  • gcc (рекомендован, но другие компиляторы C также могут подойти)
  • make
  • GNU sed

Для сборки некоторых модулей или редактирования исходников PHP также могут понадобиться

  • re2c
  • bison
  • m4
  • autoconf
  • automake
Дополнительно, вам нужно будет установить (и, возможно, скомпилировать) дополнительное ПО, необходимое в вашей конфигурации, например Oracle или MySQL.

Использование установочных пакетов

Вы можете упростить процесс установки в Solaris, используя утилиту pkgadd для установки нужных вам компонент. Система управления пакетами (IPS) операционной системы Solaris 11 Express также позволяет установить большинство требуемых компонент с помощью команды pkg.



Инструкции по установке на Debian GNU/Linux

Раздел содержит информацию и подсказки, относящиеся к установке PHP на » Debian GNU/Linux.

Внимание

Неофициальные сборки от третьих лиц не поддерживаются. О любых ошибках следует сообщать разработчикам Debian, но перед этим стоит проверить, возможно они уже исправлены в новых релизах, которые можно скачать на » странице загрузки.

Хотя и существует универсальная инструкция по установке PHP на Unix/Linux, в этом разделе мы рассмотрим особенности специфичные для Debian, такие как использование команд apt или aptitude. В рамках этого руководства обе эти команды рассматриваются как взаимозаменяемые.

Использование APT

Во первых, обратите внимание на то, что некоторые пакеты связаны: libapache-mod-php нужен для интеграции с Apache 2, и php-pear с PEAR.

Во-вторых, перед установкой убедитесь, что список пакетов находится в актуальном состоянии. Как правило, это делается с помощью команды apt update.

Пример #1 Пример установки Apache 2 на Debian

# apt install php-common libapache2-mod-php php-cli

APT автоматически установит модуль PHP для Apache 2 и все их зависимости и, затем, активирует их. Apache должен быть перезапущен для того, чтобы изменения вступили в силу. Например:

Пример #2 Остановка и запуск Apache после установки PHP

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

Контроль конфигурации

Изначально, PHP устанавливается только с основными модулями ядра. Если вы хотите установить дополнительные модули, такие как MySQL, cURL, GD и т.д., это также можно сделать с помощью команды apt.

Пример #3 Способы получить список дополнительных пакетов PHP

# apt-cache search php
# apt search php | grep -i mysql
# aptitude search php

Будет выведен список большого числа пакетов, включая несколько специфичных, таких как php-cgi, php-cli and php-dev. Определите, какие вам нужны и установите с помощью apt-get или aptitude. И, так как Debian производит проверку зависимостей, вам будет выведен запрос на их установку.

Пример #4 Установка PHP с MySQL и cURL

# apt install php-mysql php-curl

APT автоматически добавит необходимые строки в соответствующие php.ini, /etc/php/7.4/php.ini, /etc/php/7.4/conf.d/*.ini, и т.д. В зависимости от модуля, будут внесены записи типа extension=foo.so. В любом случае, чтобы эти изменения вступили в силу, необходимо будет перезапустить сервер веб-сервер.

Стандартные проблемы

  • Если скрипты PHP не разбираются веб-сервером, то скорее всего это означает, что PHP не был добавлен в конфигурацию веб-сервера. На Debian это обычно /etc/apache2/apache2.conf или похожий. Смотрите документацию Debian для выяснения подробностей.
  • Модуль, по-видимому, установлен, а его функции всё равно не распознаются. В таком случае убедитесь, что соответствующий ini-файл был загружен и/или веб-сервер был перезагружен после установки модуля.
  • Для установки пакетов в Debian существуют две основных команды (не считая стандартных вариантов Linux): apt и aptitude. Объяснения их синтаксиса, особенностей и отличий друг от друга выходит за рамки данного руководства.



Установка на macOS

Содержание

Этот раздел содержит руководство и различные советы по установке PHP на macOS. PHP поставлялся вместе с macOS, начиная с macOS X (10.0.0) по macOS Monterey (12.0.0). Компилирование на которых схоже с установкой в Unix-системах.


Использование пакетов

Существуют несколько предварительно упакованных и предварительно скомпилированных версий PHP для macOS. Это может помочь в создании стандартных конфигураций, но если вам нужны специфические функции (например, безопасный сервер, или другой драйвер базы данных), вы можете установить PHP и/или веб-сервер самостоятельно. Если вы не знакомы с процессом сборки и компиляции программного обеспечения, стоит проверить, может кто-то уже собрал версию PHP с функциями, которые вам необходимы.

Самый быстрый способ установить PHP на macOS - с помощью homebrew:

  1. Установите homebrew, следуя инструкциям на » brew.sh

  2. brew install php

Следующие альтернативные ресурсы также предлагают простые в установке пакеты и предварительно скомпилированные двоичные файлы для PHP в Mac OS:



Использование встроенного PHP до macOS Monterey

PHP поставлялся вместе с macOS, начиная с macOS X (10.0.0) по macOS Monterey (12.0.0). Включение PHP в стандартный веб-сервер делается простым раскомментированием нескольких строк в конфигурационном файле Apache httpd.conf в то время как CGI и/или CLI включены по умолчанию (доступны для использования терминальными программами).

Включение PHP согласно приведённой ниже инструкции предназначено для быстрой настройки локальной среды разработки. Крайне рекомендуется всегда обновлять PHP до новейшей стабильной версии. Для любого развивающегося ПО, новые версии выпускаются для исправления ошибок и добавления новой функциональности и PHP не является исключением. Читайте соответствующую документацию по установке на macOS, в которой описываются все подробности. Следующие инструкции предназначены для начинающих разработчиков и описывают стандартную установку, позволяющую быстро приступить к работе. Всем пользователям рекомендуется скомпилировать или установить из репозитория самую новую версию PHP.

Стандартная установка с использованием mod_php, который включается для стандартного веб-сервера macOS (сервер по умолчанию доступен через системные настройки) включает следующие шаги:

  1. Найдите и откройте конфигурационный файл Apache. По умолчанию он расположен по пути /private/etc/apache2/httpd.conf Использование Finder или Spotlight для нахождения файла может быть не простым, так как он располагается в приватном пространстве и принадлежит пользователю root.

    Замечание: Один из вариантов, как открыть этот файл - использовать консольный редактор, к примеру, nano, запустив его через терминал. Так как файл принадлежит пользователю root, для его открытия будет необходимо использовать команду sudo (которая повышает привилегии до пользователя root). Просто запустите приложение Terminal, введите команду sudo nano /private/etc/apache2/httpd.conf и, когда будет запрошен пароль, введите его. Полезные команды nano: ^w (искать), ^o (сохранить) и ^x (закрыть), где ^ - это клавиша Ctrl.

    Замечание: Версии macOS до 10.5 содержат устаревшие версии PHP и Apache. В этом случае конфигурационный файл может располагаться по пути /etc/httpd/httpd.conf.

  2. В текстовом редакторе найдите следующие строки и раскомментируйте их удалив символ # из начала строки (эти строки обычно находятся в разных местах файла):

    # LoadModule php5_module libexec/httpd/libphp5.so
    
    # AddModule mod_php5.c
    
    Запомните путь к файлу, так как при сборке PHP в будущем может потребоваться изменить эти строки.

  3. Убедитесь, что выбранные модули будут обрабатываться как файлы PHP (.php .html и .inc).

    Так как следующие выражения уже содержатся в httpd.conf (по состоянию на Mac Panther), единожды включив PHP, файлы .php будут автоматически обрабатываться им.

    <IfModule mod_php5.c>
        # Если PHP разрешён, он будет обрабатывать файлы .php и .phps.
        AddType application/x-httpd-php .php
        AddType application/x-httpd-php-source .phps
    
        # Часто требуется, чтобы  index.php рассматривался как
        # страница по умолчанию, если она прямо не указана.
        # Сделать это можно следующим образом
        <IfModule mod_dir.c>
            DirectoryIndex index.html index.php
        </IfModule>
    </IfModule>
    

    Замечание:

    До macOS 10.5 (Leopard), в состав ОС был включён PHP 4, а не PHP 5. В таком случае в инструкциях выше просто поменяйте 5 на 4.

  4. Убедитесь, что DirectoryIndex загружает индексный файл по умолчанию Данное поведение задаётся в httpd.conf. Обычно используются index.php и index.html. По умолчанию index.php разрешён. Если требуется, то отключите.
  5. Определите местоположение php.ini или используйте настройки по умолчанию Обычно на macOS он расположен по пути /usr/local/php/php.ini и вызов phpinfo() выведет соответствующую информацию. Если php.ini не используется, PHP будет использовать значения по умолчанию. Также обратите внимание на FAQ поиск php.ini.
  6. Как найти или установить DocumentRoot DocumentRoot - это корневая директория веб-сервера, в которой лежат скрипты сайта. Обычно, путь по умолчанию, он равен /Library/WebServer/Documents, но его можно изменить на любой другой в httpd.conf. Также, для индивидуальных пользователей, DocumentRoot может быть установлен как /Users/yourusername/Sites
  7. Создание файла с phpinfo()

    Функция phpinfo() отображает информацию о PHP. Создайте в DocumentRoot скрипт с таким кодом:

    <?php phpinfo(); ?>

  8. Перезапустите Apache и запросите через браузер созданный выше файл.

    Для перезапуска выполните sudo apachectl graceful в терминале или выполните stop/start для "Personal Web Server" в системных настройках macOS. По умолчанию, локальные файлы можно загрузить введя в строке браузера URL, например, так: http://localhost/info.php, или используя DocumentRoot в локальной директории пользователя, таким образом: http://localhost/~yourusername/info.php

CLI (или в более старых версиях CGI) именуется как php и содержится в /usr/bin/php. Откройте терминал, прочитайте раздел документации PHP командная строка, и запустите php -v для проверки установленной версии PHP. Вызов функции phpinfo() также покажет эту информацию.



Компилирование PHP на macOS

Для компиляции PHP на macOS прочтите руководство по установке на Unix.




Установка в системах Windows

Содержание

Установка PHP в современных операционных системах Microsoft Windows и рекомендуемая конфигурация под распространённые веб-серверы.

Официальные релизы PHP для Windows рекомендованы для использования в промышленной эксплуатации. Однако, вы также можете собрать PHP из исходных кодов. Вам потребуется окружение Visual Studio. Обратитесь к разделу » Пошаговое руководство по сборке для получения более полной информации.


Требования к установке

Для PHP требуется как минимум Windows 2008/Vista. 32-Bit или 64-bit (AKA X86 или X64. PHP не работает на Windows RT/WOA/ARM). Начиная с PHP 7.2.0, Windows 2008 и Vista больше не поддерживаются.

PHP требует наличия Visual C runtime(CRT). Многие приложения требуют, чтобы это уже было установлено.

Распространяемый Microsoft Visual C ++ для Visual Studio 2019 подходит для всех этих версий PHP, смотрите » https://visualstudio.microsoft.com/downloads/.

Вы должны скачать x86 CRT для сборки PHP x86 и x64 CRT для сборки PHP x64.

Если CRT уже установлен, установщик скажет вам об этом и ничего не будет устанавливать.

Инсталятор CRT поддерживает опции командной строки /quiet и /norestart, вы можете использовать их при запуске скрипта.



PECL

PECL модули для Windows предварительно скомпилированы и доступны по ссылке: »  http://windows.php.net/downloads/pecl/releases/

Некоторые модули используют особенности, специфичные для Unix систем и не доступны для Windows. Или напротив модули могут быть доступны только для Windows.



Инструмент установки PHP на Windows

Инструмент установки PHP

» XAMPP, WampServer и BitNami установят PHP с использованием в качестве веб-сервера Apache под Windows.

Установка и настройка Nginx на Windows потребует немного больше конфигурации. Смотрите » документацию по Nginx для получения помощи по установке.



Рекомендованная конфигурация для систем Windows

OpCache

Крайне рекомендуется использовать OpCache. Этот модуль идёт в составе дистрибутива для Windows. Модуль компилирует PHP-скрипт, оптимизирует его и кеширует в памяти , что позволяет не тратить время и ресурсы сервера на компиляцию скрипта при каждом запросе к нему.

Установите в вашем php.ini следующие опции

Пример #1 Рекомендованная конфигурация OpCache

opcache.enable=On
opcache.enable_cli=On
И перезагрузите ваш веб-сервер. Более подробно читайте: Конфигурация OpCache

WinCache

Если вы используете IIS, то рекомендуется вместе с ним использовать WinCache, особенно если используется виртуальный хостинг или сетевое хранилище (NAS). Все приложения PHP будут автоматически получать преимущества WinCache. Файловые операции будут кешироваться в памяти. Также WinCache может кешировать в памяти пользовательский объекты и разделять их между разными процессами php.exe или php-cgi.exe (разделение объектом между запросами). Многие веб-приложения имеют плагин, модуль или опции настройки, позволяющие использовать кеширование пользовательских объектов с помощью WinCache. Если вам нужна высокая производительность, вам придётся кешировать объекты в своём приложении. Загрузить WinCache можно по ссылке » http://pecl.php.net/package/WinCache. После загрузки будет нужно сохранить WinCache DLL в директорию модулей PHP (extensions_dir в вашем php.ini). Установите в вашем php.ini следующие опции:

Пример #2 Рекомендованная конфигурация WinCache

extension=php_wincache.dll
wincache.fcenabled=1
wincache.ocenabled=1 ; удалено в wincache 2.0.0.0
Более подробно читайте: Конфигурация WinCache

Конфигурация IIS

В IIS Manager установите модуль FastCGI и добавьте обработку `.php` файлом PHP-CGI.exe (не PHP.exe)

Вы можете использовать приложение APPCMD из командной строки для автоматизации настройки ISS.

База данных

Наверное вам понадобится сервер баз данных. Для всех популярных баз данных существуют модули PHP. Если ваш сайт не рассчитывается под высокую нагрузку, то сервер баз данных можно держать на том же хосте, что и веб-сервер. Под Windows доступно множество различных баз данных.

PHP модули включают mysqli и pdo_mysql.

Дополнительно читайте » https://dev.mysql.com/downloads/windows/



Самостоятельная установка PHP в Windows

Выберите веб-сервер

IIS

IIS является встроенным в Windows. На сервере Windows используйте Server Manager для добавления роли IIS. Убедитесь, что функция роли CGI включена. На рабочем столе Windows используйте панель "Установка и удаление программ" для добавления IIS. В документации Microsoft есть » подробные инструкции. Для настольных веб-приложений и веб-разработки можно также использовать IIS/Express или рабочий стол PHP.

Пример #1 Командная строка для настройки IIS и PHP


@echo off

REM download .ZIP file of PHP build from http://windows.php.net/downloads/

REM path to directory you decompressed PHP .ZIP file into (no trailing \)
set phppath=c:\php


REM Clear current PHP handlers
%windir%\system32\inetsrv\appcmd clear config /section:system.webServer/fastCGI
REM The following command will generate an error message if PHP is not installed. This can be ignored.
%windir%\system32\inetsrv\appcmd set config /section:system.webServer/handlers /-[name='PHP_via_FastCGI']

REM Set up the PHP handler
%windir%\system32\inetsrv\appcmd set config /section:system.webServer/fastCGI /+[fullPath='%phppath%\php-cgi.exe']
%windir%\system32\inetsrv\appcmd set config /section:system.webServer/handlers /+[name='PHP_via_FastCGI',path='*.php',verb='*',modules='FastCgiModule',scriptProcessor='%phppath%\php-cgi.exe',resourceType='Unspecified']
%windir%\system32\inetsrv\appcmd set config /section:system.webServer/handlers /accessPolicy:Read,Script

REM Configure FastCGI Variables
%windir%\system32\inetsrv\appcmd set config -section:system.webServer/fastCgi /[fullPath='%phppath%\php-cgi.exe'].instanceMaxRequests:10000
%windir%\system32\inetsrv\appcmd.exe set config -section:system.webServer/fastCgi /+"[fullPath='%phppath%\php-cgi.exe'].environmentVariables.[name='PHP_FCGI_MAX_REQUESTS',value='10000']"
%windir%\system32\inetsrv\appcmd.exe set config -section:system.webServer/fastCgi /+"[fullPath='%phppath%\php-cgi.exe'].environmentVariables.[name='PHPRC',value='%phppath%\php.ini']"

Apache

Существует несколько версий Apache2 для Windows. Мы поддерживаем ApacheLounge, но другие варианты включают XAMPP, WampServer и BitNami, которые предоставляют средства автоматической установки. Вы можете использовать mod_php или mod_fastcgi для загрузки PHP на Apache. Если вы используете mod_php, необходимо использовать TS-build Apache, Visual C той же версии и тот же процессор (x86 или x64).

Выберите сборку

Скачайте PHP-релизы с » http://windows.php.net/download/. Все сборки оптимизированы (PGO), а выпуски QA и GA тщательно протестированы.

Есть 4 типа сборок PHP:

  • Thread-Safe(TS) - для одного процесса веб-служб, как Apache с mod_php

  • Non-Thread-Safe(NTS) - для служб IIS и других FastCGI веб-серверов (Apache с mod_fastcgi) рекомендуется и для сценариев командной строки

  • для x86 - для 32-разрядной версии

  • для x64 - для 64-разрядной версии



Сборка из исходных кодов

В этой главе рассказывается, как скомпилировать PHP из исходных кодов в Windows с помощью инструментов Microsoft. Чтобы скомпилировать PHP с помощью cygwin, обратитесь к Установка на Unix-системы.

Смотрите Wiki-документацию по адресу: » https://wiki.php.net/internals/windows/stepbystepbuild



Командная строка PHP в Microsoft Windows

Этот раздел содержит примечания и подсказки, относящиеся к запуску PHP из командной строки для Windows.

Замечание:

Сначала следует прочитать шаги ручной установки!

Запуск PHP из командной строки можно выполнить без внесения каких-либо изменений в Windows.

C:\php\php.exe -f "C:\PHP Scripts\script.php" -- -arg1 -arg2 -arg3

Но есть несколько шагов, которые помогут упростить этот процесс. Некоторые из этих шагов уже должны были быть предприняты, но они повторяются здесь, чтобы иметь возможность предоставить полную пошаговую последовательность.

    Замечание:

    И PATH, и PATHEXT являются важными переменными, изначально существовавшими в Windows, и следует позаботиться о том, чтобы не перезаписывать ни одну из переменных, а только добавлять к ним.

  • Добавьте расположение исполняемого файла PHP (php.exe, php-win.exe или php-cli.exe в зависимости от вашей версии PHP и предпочтений отображения) в переменную окружения PATH. Подробнее о том, как добавить каталог PHP в PATH, читайте в соответствующей записи часто задаваемых вопросов.

  • Добавьте расширение .PHP к переменной окружения PATHEXT. Это можно сделать одновременно с изменением переменной окружения PATH. Выполните те же действия, что и в ЧАВО, но измените переменную окружения PATHEXT, а не PATH.

    Замечание:

    Позиция, в которую вы помещаете .PHP, будет определять, какой скрипт или программа будет выполняться при совпадении имён файлов. Например, размещение .PHP перед .BAT приведёт к запуску вашего скрипта, а не пакетного файла, если существует пакетный файл с тем же именем.

  • Свяжите расширение .PHP с типом файла. Это делается с помощью следующей команды:

    assoc .php=phpfile
    

  • Свяжите тип файла phpfile с соответствующим исполняемым файлом PHP. Это делается с помощью следующей команды:

    ftype phpfile="C:\php\php.exe" -f "%1" -- %~2
    

Выполнение этих шагов позволит запускать скрипты PHP из любого каталога без необходимости вводить исполняемый файл PHP или расширение .PHP, и все параметры будут переданы скрипту для обработки.

В приведённом ниже примере описаны подробности о некоторых изменениях в реестре, которые можно сделать вручную.

Пример #1 Изменения в реестре

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:\\php\\php-win.exe,0"

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\phpfile\shell]
@="Open"

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\phpfile\shell\Open]
@="&Open"

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\phpfile\shell\Open\command]
@="\"C:\\php\\php.exe\" -f \"%1\" -- %~2"

С этими изменениями эту же команду можно записать как:

"C:\PHP Scripts\script" -arg1 -arg2 -arg3
или, если ваш путь "C:\PHP Scripts" находится в переменной окружения PATH:
script -arg1 -arg2 -arg3

Замечание:

Есть небольшая проблема, если вы собираетесь использовать эту технику и использовать свои скрипты PHP в качестве фильтра командной строки, как в примере ниже:

dir | "C:\PHP Scripts\script" -arg1 -arg2 -arg3
или
dir | script -arg1 -arg2 -arg3
Вы можете обнаружить, что сценарий просто зависает и ничего не выводится. Чтобы это заработало, необходимо внести ещё одно изменение в реестр.
Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\policies\Explorer]
"InheritConsoleHandles"=dword:00000001
Дополнительную информацию по этой проблеме можно найти в этой »  статье базы знаний Microsoft : 321788. В Windows 10 этот параметр изменён на противоположный, и стандартная установка Windows 10 поддерживает унаследованные дескрипторы консоли. Это »  сообщение на форуме Microsoft предоставляет объяснение.



Apache 2.x в Microsoft Windows

Этот раздел содержит примечания и подсказки к установке PHP, связанной с Apache 2.x на системах Microsoft Windows.

Замечание:

Сначала следует прочитать шаги ручной установки!

Крайне рекомендуется обратиться к »  Документации Apache, чтобы получить базовое представление о сервере Apache 2.x. Также подумайте о чтении »  Примечаний для Windows для Apache 2.x перед чтением этого руководства.

Загрузите последнюю версию » Apache 2.x и подходящую версию PHP. Следуйте шагам ручной установки и возвращайтесь, чтобы продолжить интеграцию PHP и Apache.

Существует три способа настроить PHP для работы с Apache 2.x в Windows. PHP можно запускать как обработчик, как CGI или под FastCGI.

Замечание: Помните, что при указании путей в конфигурационных файлах Apache под Windows, все обратные слеши, например, c:\directory\file.ext должны быть изменены на прямые: c:/directory/file.ext. Для путей с директориями также может понадобиться слеш в конце.

Установка в качестве обработчика Apache

Чтобы загрузить модуль PHP для Apache 2.x, необходимо вставить следующие строки в файл конфигурации Apache httpd.conf:

Пример #1 PHP и Apache 2.x в качестве обработчика

# до PHP 8.0.0 имя модуля было php7_module
LoadModule php_module "c:/php/php8apache2_4.dll"
<FilesMatch \.php$>
    SetHandler application/x-httpd-php
</FilesMatch>
# укажите путь до php.ini
PHPIniDir "C:/php"

Замечание: В приведённых выше примерах необходимо подставить фактический путь к PHP вместо C:/php/. Убедитесь, что файл, указанный в директиве LoadModule, находился в указанном месте. Используйте php7apache2_4.dll для PHP 7 или php8apache2_4.dll для PHP 8.

Запуск PHP как CGI

Настоятельно рекомендуется обратиться к » Документации Apache CGI для более полного понимания того, как запускать CGI в Apache.

Чтобы запустить PHP как CGI, файлы php-cgi должны быть помещены в каталог, обозначенный как каталог CGI с использованием директивы ScriptAlias.

Строку #! необходимо будет поместить в файлы PHP, которые указывают на расположение бинарного файла PHP:

Пример #2 PHP и Apache 2.x как CGI

#!C:/php/php.exe
<?php
  phpinfo();
?>

Внимание

Используя установку CGI, ваш сервер открыт перед несколькими возможными уязвимостями. Пожалуйста, ознакомьтесь с разделом "Безопасность CGI" чтобы узнать, как можно защитить себя от таких атак.

Запуск PHP под FastCGI

Запуск PHP под FastCGI имеет ряд преимуществ перед запуском как CGI. Настройка таким способом довольно проста:

Загрузите mod_fcgid с » https://www.apachelounge.com. Бинарные файлы Win32 доступны для загрузки с этого сайта. Установите модуль в соответствии с прилагаемой к нему инструкцией.

Настройте свой веб-сервер, как показано ниже, позаботившись о том, чтобы скорректировать все пути в соответствии с тем, как вы провели установку в своей конкретной системе:

Пример #3 Настройка Apache для запуска PHP как FastCGI

LoadModule fcgid_module modules/mod_fcgid.so
# Где находится ваш файл php.ini?
FcgidInitialEnv PHPRC        "c:/php"
<FilesMatch \.php$>
    SetHandler fcgid-script
</FilesMatch>
FcgidWrapper "c:/php/php-cgi.exe" .php
Файлы с расширением .php теперь будут исполняться обёрткой PHP FastCGI.



Стандартные проблемы PHP под Windows

Проверка прав на временную директорию

  1. В Проводнике нажмите правой кнопкой мыши на временной директории, выберите пункт "Свойства" и перейдите в закладку "Доступ".

  2. Для IIS, проверьте, что пользователь IIS_User имеет права на изменение для этой директории. Путь временной директории можно посмотреть в файле php.ini.




Установка на платформах Cloud Computing

Содержание

PHP устанавливается на облачных платформах.


Azure App Services

PHP часто устанавливается на облачный сервис Azure App Services (также известный как Microsoft Azure, Windows Azure и Azure Web Apps).

Azure App Services управляет пулом Windows Web Servers для хостинга ваших веб-приложений и представляет альтернативу созданию собственного веб-сервера на собственном Azure Compute VMs и других платформах.

PHP по умолчанию доступен для вашего веб-сайта в Azure App Services. Просто выберите на Azure Portal ваш сайт и выберите нужную версию PHP. Вы можете выбрать более свежую версию, чем заданная по умолчанию.

Таким образом, PHP и его модули будут работать в Azure App Services так же как и на любом другом сервере Windows. Большая часть базы знаний также портирована, смотрите Windows Troubleshooting Page Тем не менее, интерфейс управления для Azure App Services имеет отличия:

  • Azure portal: создание, настройка и удаление сайтов. » Azure Portal

  • Панель Kudu: [имя вашего сайта].azurewebsites.net. Тогда панель Kudu » https://[имя вашего сайта].scm.azurewebsites.net/. Панель Kudu даёт вам доступ к некоторым возможностям отладки, управлению файлами и модулями сайта. Модули сайта - это механизм Azure по добавлению программ, например превью сборок PHP, на ваш сайт.

  • Вы не сможете использовать IIS Manager, Server Manager или RDP.

PHP SDK позволяет программно использовать множество Azure Services. Смотри » Azure SDK для PHP.

Для более подробной информации, смотри » Azure PHP Developer Center

WinCache

WinCache по умолчанию разрешён в Azure App Services и рекомендуется его не отключать. Если вы установили собственную сборку PHP, вы должны разрешить WinCache.

Собственные сборки PHP

Вы можете загрузить собственную сборку PHP в D:\Home (C:\ НЕ ДОСТУПЕН для записи). После чего, на Azure Portal, задайте SCRIPT_PROCESSOR для .php равный абсолютному пути к php-cgi.exe из вашей сборки.



Amazon EC2

PHP устанавливается на » облачную платформу EC2.

Смотрите также » AWS SDK для PHP.




Менеджер процессов FastCGI (FPM)

Содержание

FPM (FastCGI Process Manager, менеджер процессов FastCGI) является альтернативной реализацией PHP FastCGI с несколькими дополнительными возможностями обычно используемыми для высоконагруженных сайтов.

Эти возможности включают в себя:

  • Продвинутое управление процессами с корректной (graceful) процедурой остановки и запуска;

  • Пулы, дающие возможность запуска воркеров с разными uid/gid/chroot/окружением, прослушивая разные порты и используя разные php.ini (замещение safe_mode);

  • Настраиваемое ведение журнала потоков вывода (stdout) и ошибок (stderr);

  • Аварийный перезапуск в случае внезапного разрушения opcode-кеша;

  • Поддержка ускоренной загрузки (accelerated upload);

  • "slowlog" - логирование необычно медленно выполняющихся скриптов (не только их имена, но также и их трассировки. Это достигается с помощью ptrace и других подобных утилит для чтения данных исполнения удалённых процессов);

  • fastcgi_finish_request() - специальная функция для завершения запроса и сброса всех буферов данных, причём процесс может продолжать выполнение каких-либо длительных действий (конвертирование видео, обработка статистики и т.п.);

  • Динамическое/по требованию/статическое порождение дочерних процессов;

  • Базовая и расширенная информация о состоянии (аналогично Apache mod_status) с поддержкой различных форматов, таких как json, xml и openmetrics;

  • Конфигурационный файл, основанный на php.ini.


Установка

Компиляция из исходников

Для того, чтобы включить FPM при сборке PHP, добавьте строку --enable-fpm

Существуют также несколько других опций конфигурации FPM (все опциональны):

  • --with-fpm-user - установить пользователя FPM (по умолчанию - nobody).

  • --with-fpm-group - установить группу FPM (по умолчанию - nobody).

  • --with-fpm-systemd - Включить интеграцию с systemd (по умолчанию - no).

  • --with-fpm-acl - Использовать списки управления доступом (ACL) POSIX (по умолчанию - no).

  • --with-fpm-apparmor - Активировать интеграцию с AppArmor (по умолчанию - no).

  • --with-fpm-selinux - Активировать интеграцию с SELinux (по умолчанию - no).

Список изменений

Версия Описание
8.2.0 Добавлена опция --with-fpm-selinux.
8.0.0 Добавлена опция --with-fpm-apparmor.



Настройка

FPM использует синтаксис php.ini для своего файла конфигурации php-fpm.conf и файлов конфигурации пулов.

Список глобальных директив php-fpm.conf

pid string

Путь к PID-файлу. По умолчанию: none.

error_log string

Путь к файлу журнала ошибок. По умолчанию: #INSTALL_PREFIX#/log/php-fpm.log. Если задано как "syslog", логирование будет производиться в syslogd, а не в локальный файл.

log_level string

Уровень журналирования ошибок. Возможные значения: alert, error, warning, notice, debug. По умолчанию: notice.

log_limit int

Ограничить журналирование для журналируемых линиях, что позволяет записывать сообщения длиной более 1024 символов без упаковки (wrapping). Значение по умолчанию: 1024. Доступно с PHP 7.3.0.

log_buffering bool

Экспериментальное журналирование без дополнительной буферизации. Значение по умолчанию: yes. Доступно с PHP 7.3.0.

syslog.facility string

Используется для указания, какой тип программ будет логировать сообщения. По умолчанию: daemon.

syslog.ident string

Предшествует любому сообщению. Если у вас запущено несколько экземпляры FPM, вы можете изменить значение по умолчанию на то, которое вам необходимо. По умолчанию: php-fpm.

emergency_restart_threshold int

При данном числе рабочих процессов, завершённых с SIGSEGV или SIGBUS за промежуток времени, установленный emergency_restart_interval FPM будет перезагружен. Значение 0 означает 'Off' (отключено). По умолчанию: 0 (Off).

emergency_restart_interval mixed

Интервал времени, используемый emergency_restart_interval, чтобы определить, когда FPM будет мягко перезагружен. Это полезно для избежания случайных повреждений общей памяти ускорителя (accelerator). Доступные единицы измерения: s(секунды), m(минуты), h(часы), или d(дни). Единица измерения по умолчанию: секунды. Значение по умолчанию: 0 (Off).

process_control_timeout mixed

Время, в течение которого дочерние процессы ждут ответа на сигналы мастер-процессу. Доступные единицы измерения: s(секунды), m(минуты), h(часы) или d(дни). Единица измерения по умолчанию: секунды. Значение по умолчанию: 0.

process.max int

Максимальное количество процессов, которое может породить FPM. Это сделано для того, чтобы контролировать глобальное количество процессов, когда используется большой пул динамического PM. Используйте с осторожностью. По умолчанию: 0.

process.priority int

Указывает приоритет (Unix nice(2)) мастер-процесса (только если установлено). Принимает значения от -19(максимальный приоритет) до 20(минимальный.) По умолчанию: не установлено.

daemonize bool

Запустить FPM в фоновом режиме. Установите значение 'no', чтобы запустить FPM в диспетчере для отладки. По умолчанию: yes.

rlimit_files int

Устанавливает rlimit открытых файловых дескрипторов для мастер-процесса. По умолчанию: Значение, определённое системой.

rlimit_core int

Устанавливает rlimit максимального размера ядра для мастер-процесса. По умолчанию 0.

events.mechanism string

Указывает, какой событийный механизм будет использован FPM. Возможны такие варианты: select, pool, epoll, kqueue (*BSD), port (Solaris). По умолчанию: не установлено (автоопределение).

systemd_interval int

Если FPM собран с интеграцией с systemd, указывает интервал, в секундах, между оповещениями systemd о своём состоянии. Для отключения задайте 0. По умолчанию: 10.

Список директив для пулов.

С помощью FPM вы можете запускать несколько пулов процессов с различными настройками. Эти параметры могут быть переданы пулу.

listen string

Адрес, который будет принимать FastCGI-запросы. Синтаксис: 'ip.add.re.ss:port', 'port', '/path/to/unix/socket'. Эта опция обязательна для каждого пула.

listen.backlog int

Устанавливает listen(2) backlog. Значение -1 означает максимум на системах BSD. Значение по умолчанию: -1 (FreeBSD или OpenBSD) или 511. (Linux и другие платформы).

listen.allowed_clients string

Список адресов IPv4 или IPv6 клиентов FastCGI, которым разрешено подключение. Эквивалент переменной окружения FCGI_WEB_SERVER_ADDRS в оригинальном PHP FastCGI (5.2.2+). Имеет смысл только с TCP-сокетом. Каждый адрес должен быть разделён запятой. Если оставить это значение пустым, соединения будут приниматься с любого IP-адреса. Значение по умолчанию: не задано (принимается любой ip-адрес).

listen.owner string

Задаёт права для unix-сокета, если они используются. В Linux для разрешения соединений к веб-серверу, должны быть установлены права на чтение/запись. Во многих основанных на BSD-системах возможность соединения не зависит от прав доступа. Значение по умолчанию: используется пользователь и группа, от имени которого запущен сервер, установлен режим 0660.

listen.group string

Смотрите listen.owner.

listen.mode string

Смотрите listen.owner.

listen.acl_users string

Если поддерживается список управления доступом (ACL) POSIX, вы можете настроить его с помощью этой опции. Если задано, то listen.owner и listen.group будут проигнорированы. Значение задаётся списком имён, разделённых запятой.

listen.acl_groups string

Смотрите listen.acl_users. Значение задаётся списком имён групп, разделённых запятой.

user string

Unix-пользователь FPM-процессов. Этот параметр является обязательным.

group string

Unix-группа FPM-процессов. Если не установлен, группа по умолчанию равняется имени пользователя.

pm string

Выбор того, как менеджер процессов будет контролировать создание дочерних процессов. Возможные значения: static, ondemand, dynamic. Этот параметр является обязательным.

static - фиксированное число дочерних процессов (pm.max_children).

ondemand - число процессов, порождающихся по требованию (когда появляются запросы, в отличие от опции dynamic, когда стартует определённое количество процессов, равное pm.start_servers, вместе с запуском службы.

dynamic - динамически изменяющееся число дочерних процессов, задаётся на основании следующих директив: pm.max_children, pm.start_servers, pm.min_spare_servers, pm.max_spare_servers.

pm.max_children int

Число дочерних процессов, которые будут созданы, когда pm установлен в static, или же максимальное число процессов, которые будут созданы, когда pm установлен в dynamic. Этот параметр является обязательным.

Этот параметр устанавливает ограничение на число одновременных запросов, которые будут обслуживаться. Эквивалент директивы ApacheMaxClients с mpm_prefork и переменной окружения среды PHP_FCGI_CHILDREN в в оригинальном PHP FastCGI.

pm.start_servers int

Число дочерних процессов, создаваемых при запуске. Используется, только когда pm установлен в dynamic. Значение по умолчанию: min_spare_servers + (max_spare_servers - min_spare_servers) / 2.

pm.min_spare_servers int

Желаемое минимальное число неактивных процессов сервера. Используется, только когда pm установлено в dynamic. Кроме того, это обязательный параметр в этом случае.

pm.max_spare_servers int

Желаемое максимальное число неактивных процессов сервера. Используется, только когда pm установлен в dynamic. Кроме того, это обязательный параметр в этом случае.

pm.max_spawn_rate int

Количество одновременных порождений дочерних процессов. Используется только тогда, когда у параметра pm установлено значение dynamic. Значение по умолчанию: 32

pm.process_idle_timeout mixed

Число секунд, по истечению которых простаивающий процесс будет завершён. Используется только если pm установлено как ondemand. Допустимые единицы: s(econds)(по умолчанию), m(inutes), h(ours) или d(ays). По умолчанию: 10s.

pm.max_requests int

Число запросов дочернего процесса, после которого процесс будет перезапущен. Это полезно для избежания утечек памяти при использовании сторонних библиотек. Для бесконечной обработки запросов укажите '0'. Эквивалент PHP_FCGI_MAX_REQUESTS. Значение по умолчанию: 0.

pm.status_listen string

Адрес, по которому будет приниматься запрос состояния FastCGI. Создаёт новый невидимый пул, который может независимо обрабатывать запросы. Полезно, если основной пул занят долго выполняющимися запросами, так как всё ещё можно получить страницу состояния FPM до завершения долго выполняющихся запросов. Синтаксис такой же, как и для директивы listen. Значение по умолчанию: none.

pm.status_path string

Ссылка, по которой можно посмотреть страницу состояния FPM. Значение должно начинаться со слеша (/). Если значение не установлено, то страница статуса отображаться не будет. Значение по умолчанию: none.

ping.path string

Ссылка на ping-страницу мониторинга FPM. Если значение не установлено, ping-страница отображаться не будет. Может быть использовано для тестирования извне, чтобы убедиться, что FPM жив и отвечает. Обратите внимание, что значение должно начинаться с косой черты (/).

ping.response string

Эта директива может быть использована на настройки ответа на ping-запрос. Ответ формируется как text/plain со кодом ответа 200. Значение по умолчанию: pong.

process.priority int

Задаёт приоритет nice(2) для работающего процесса (только если задан). Значение от -19 (высший приоритет) до 20 (самый низкий). Значение по умолчанию: не задано.

process.dumpable bool

Установить флаг процесса dumpable (PR_SET_DUMPABLE prctl), даже если the пользователь процесса или группа отличается от пользователя мастер-процесса. Это позволяет создавать дамп ядра процесса и выполнить ptrace процесса для пользователя пула. Значение по умолчанию: no. Доступно с PHP 7.0.29, 7.1.17 и 7.2.5.

prefix string

Задаёт префикс для вычисления пути

request_terminate_timeout mixed

Время ожидания обслуживания одного запроса, после чего рабочий процесс будет завершён. Этот вариант следует использовать, когда опция 'max_execution_time' в php.ini не останавливает выполнение скрипта по каким-то причинам. Значение '0' означает 'выключено'. Доступные единицы измерения: s(econds), m(inutes), h(ours) или d(ays). Значение по умолчанию: 0.

request_terminate_timeout_track_finished bool

Время ожидания, установленное с помощью request_terminate_timeout, не включается после fastcgi_finish_request или когда приложение завершено и вызываются внутренние функции завершения работы. Эта директива позволит безоговорочно применять ограничение времени ожидания даже в таких случаях. Значение по умолчанию: нет, начиная с версии PHP 7.3.0.

request_slowlog_timeout mixed

Время ожидания обслуживания одного запроса, после чего PHP backtrace будет сохранён в файл 'slowlog'. Значение '0' означает 'выключено'. Доступные единицы измерения: s(econds), m(inutes), h(ours) или d(ays). Значение по умолчанию: 0.

request_slowlog_trace_depth int

Глубина трассировки стека журнала slowlog. Значение по умолчанию: 20, начиная с PHP 7.2.0.

slowlog string

Лог-файл для медленных запросов. Значение по умолчанию: #INSTALL_PREFIX#/log/php-fpm.log.slow.

rlimit_files int

Устанавливает лимит дескрипторов открытых файлов rlimit для дочерних процессов в этом пуле. Значение по умолчанию: определяется значением системы.

rlimit_core int

Устанавливает максимальное количество используемых ядер rlimit для дочерних процессов в этом пуле. Возможные значения: 'unlimited' или целое число большее или равное 0. Значение по умолчанию: определяется значением системы.

chroot string

Директория chroot окружения при старте. Это значение должно быть определено как абсолютный путь. Если значение не установлено, chroot не используется.

chdir string

Chdir изменяет текущую директорию при старте. Это значение должно быть определено как абсолютный путь. Значение по умолчанию: текущая директория или / при использовании chroot.

catch_workers_output bool

Перенаправление STDOUT и STDERR рабочего процесса в главный лог ошибок. Если не установлен, STDOUT и STDERR будут перенаправлены в /dev/null в соответствии со спецификацией FastCGI. Значение по умолчанию: no.

decorate_workers_output bool

Включите оформление выхода (output decoration) для вывода worker-процесса когда опция catch_workers_output включена. Значение по умолчанию: yes. Доступно с PHP 7.3.0.

clear_env bool

Очищает окружение в worker-процессах FPM. Предотвращает попадание произвольных переменных окружения в worker-процессы FPM, очищая окружение у worker-процессах до того, как переменные окружения, указанные в этой конфигурации пула будут добавлены. По умолчанию: Yes.

security.limit_extensions string

Ограничивает модули, которые FPM будет анализировать. Это может предотвратить ошибки конфигурации на стороне веб-сервера. Вы должны ограничить FPM только расширениями .php для предотвращения выполнения PHP-кода злоумышленниками другими расширениями. По умолчанию: .php .phar

apparmor_hat string

Если AppArmor включён, позволяет изменить шапку. Значение по умолчанию: не установлено

access.log string

Лог-файл доступа. Значение по умолчанию: не установлено

access.format string

Формат лог-файла доступа. Значение по умолчанию: "%R - %u %t \"%m %r\" %s":

Допустимые значения
Заполнитель Описание
%C %CPU
%d длительность µs
%e fastcgi env
%f скрипт
%l длина содержимого
%m метод
%M память
%n название пула
%o вывод заголовка
%p PID
%q строка запроса
%Q GLUE между %q и %r
%r URI запроса
%R удалённый IP-адрес
%s статус
%T время
%t время
%u удалённый пользователь

Можно передать дополнительные переменные окружения и обновить настройки PHP для определённого пула. Для этого вам необходимо добавить следующие параметры в файл настройки пула.

Пример #1 Передача переменных окружения и настроек PHP пулу

env[HOSTNAME] = $HOSTNAME
env[PATH] = /usr/local/bin:/usr/bin:/bin
env[TMP] = /tmp
env[TMPDIR] = /tmp
env[TEMP] = /tmp

php_admin_value[sendmail_path] = /usr/sbin/sendmail -t -i -f www@my.domain.com
php_flag[display_errors] = off
php_admin_value[error_log] = /var/log/fpm-php.www.log
php_admin_flag[log_errors] = on
php_admin_value[memory_limit] = 32M
Настройки PHP, переданные через php_value или php_flag перезапишут их предыдущие значения. Пожалуйста, обратите внимание, что определения disable_functions или disable_classes не будут перезаписывать ранее определённые в php.ini значения, а добавят новые значения.

Настройки, определённые через php_admin_value и php_admin_flag, не могут быть перезаписаны через ini_set().

Настройки PHP можно устанавливать через веб-сервер.

Пример #2 Установка настроек PHP в nginx.conf

set $php_value "pcre.backtrack_limit=424242";
set $php_value "$php_value \n pcre.recursion_limit=99999";
fastcgi_param  PHP_VALUE $php_value;

fastcgi_param  PHP_ADMIN_VALUE "open_basedir=/var/www/htdocs";
Предостережение

Так как эти настройки передаются в php-fpm как FastCGI-заголовки, php-fpm не должен быть привязан к общедоступному адресу из мира. В противном случае любой сможет изменить настройки PHP. Смотрите также listen.allowed_clients.

Замечание: Пулы не являются механизмом безопасности, потому что они не обеспечивают полного разделения; например все пулы будут использовать один экземпляр OPcache.




Установка модулей PECL

Содержание


Введение в установку PECL

» PECL - это репозиторий модулей PHP, доступ к которым предоставляется через систему » PEAR. Эта часть руководства предназначена для демонстрации того, как вы можете получить и установить модули PECL.

Эти инструкции подразумевают, что /your/phpsrcdir/ является путём к каталогу с дистрибутивом исходного кода PHP, а extname - это имя модуля PECL, так что вносите соответствующие коррективы. Эти инструкции также подразумевают знакомство с » командой pear. Информация в руководстве PEAR для команды pear также применима для команды pecl.

Для того, чтобы модуль можно было использовать, он должен быть собран, установлен и загружен. Описанные ниже методы предоставляют различные рекомендации по поводу того, как собрать и установить модули, но без применения их автоматической загрузки. Модули могут быть загружены с помощью директивы extension в файле php.ini или путём использования функции dl().

В процессе сборки модулей PHP важно иметь нужные версии необходимых утилит (autoconf, automake, libtool и т.д.). Информацию об этих утилитах и их версиях можно посмотреть в разделе "» Инструкции по осуществлению анонимного доступа к Git".



Загрузка модулей PECL

Есть несколько вариантов для загрузки модулей PECL, в том числе:

  • Команда pecl install extname автоматически скачивает код модуля, поэтому в этом случае нет нужды в отдельной скачке этих файлов.
  • » https://pecl.php.net/ Веб-сайт PECL содержит информацию о различных модулях, предоставляемых командой разработчиков PHP. Информация, доступная на этом веб-сайте, включает в себя: лог изменений, новости релизов, требования и другие подобные детали.
  • pecl download extname Модули PECL, имеющие опубликованные релизы на сайте PECL, доступны для скачивания и установки с помощью » команды pecl. Можно также указать отдельные ревизии для установки.
  • git Многие модули PECL находятся на GitHub.
  • SVN Многие модули PECL, также, находятся в SVN. Веб-интерфейс для просмотра доступен по адресу » https://svn.php.net/pecl/. Для загрузки напрямую из SVN используется следующая последовательность команд:


    $ svn checkout http://svn.php.net/repository/pecl/extname/trunk extname

  • Загрузка для Windows На данный момент проект PHP не компилирует бинарные файлы Windows для модулей PECL.


Установка PHP-модуля в Windows

В Windows есть два способа загрузки PHP-модуля: скомпилировать его вместе с PHP или загрузить DLL. Загрузка заранее скомпилированного модуля является наиболее простым и предпочитаемым способом.

Для загрузки модуля, он должен присутствовать в вашей системе в виде ".dll" файла. Все модули автоматически и периодически компилируются командой PHP (смотрите следующий раздел для загрузки).

За инструкциями по компиляции модуля в PHP обратитесь к разделу "Сборка из исходников".

Для компиляции отдельного модуля (или DLL-файла), обратитесь к разделу " Сборка из исходников". Если DLL-файла нет ни в стандартной поставке PHP ни в PECL, возможно, вам придётся скомпилировать его вручную.

Где найти модуль?

PHP-модули обычно имеют имена вида "php_*.dll" (где звёздочка обозначает имя модуля) и располагаются в папке "PHP\ext".

PHP поставляет модули наиболее полезные большинству разработчиков. Такие модули называются "основными" ("core").

Однако, если вам требуется функционал, который не предоставляется ни одним из основных модулей, возможно, нужный вам модуль есть в » PECL. Библиотека модулей сообщества PHP (The PHP Extension Community Library, PECL) является хранилищем модулей PHP, предоставляя каталог и хостинг всех известных модулей для скачки и дальнейшей разработки модулей в PHP.

Если вы разработали какой-либо модуль для собственных нужд, возможно, вы захотите хранить его в PECL, так, чтобы другие также могли воспользоваться результатами вашего труда. Хорошим побочным эффектом будет неплохой шанс получить обратную связь, благодарности (надеемся, что так и будет), сообщения об ошибках и даже исправления/патчи. Пожалуйста, прочтите » публикация PECL; перед отправкой вашего модуля в PECL.

Какой модуль нужно загрузить?

Очень часто существует несколько версий модуля DLL:

  • Различные номера версий (по крайней мере первые два числа должны совпадать)
  • Различные настройки потокобезопасности
  • Различная архитектура процессора (x86, x64, ...)
  • Различные настройки отладки
  • и т.д.

Помните, что настройки ваших модулей должны совпадать со всеми настройками используемого вами бинарного файла PHP. Следующий PHP-скрипт выведет вам все настройки PHP:

Пример #1 Вызов phpinfo()

<?php
phpinfo
();
?>

Или запустите из командной строки:

drive:\\path\to\php\executable\php.exe -i

Загрузка модуля

Наиболее распространённым способом загрузки PHP-модуля является его включение в конфигурационном файле php.ini. Обратите внимание, что большинство модулей уже прописаны в вашем php.ini и для их активации вам просто нужно удалить точку с запятой.

Обратите внимание, что в PHP 7.2.0 и выше для указания модуля можно использовать не имя файла библиотеки, а название самого модуля. Данный подход рекомендуется для использования, так как он более простой и платформонезависимый. Однако вы всё ещё можете прямо указывать имя файла модуля.

;extension=php_extname.dll
extension=php_extname.dll
; В PHP 7.2 и выше лучше делать так:
extension=extname
zend_extension=another_extension

Однако, некоторые веб-серверы создают путаницу, т.к. они не используют php.ini, расположенный в дистрибутиве PHP, а используют свой собственный. Узнать, где находится, используемый сервером php.ini, можно посмотрев на выводимый путь в phpinfo():

Configuration File (php.ini) Path  C:\WINDOWS
Loaded Configuration File   C:\Program Files\PHP\5.2\php.ini

После активации модуля сохраните php.ini, перезагрузите веб-сервер и снова проверьте phpinfo(), в нем должен появиться отдельный раздел с новым модулем.

Решение проблем

Если модуль не появился в выводе phpinfo(), проверьте лог-файлы на наличие сообщений об ошибках.

Если вы используете PHP в командной строке (CLI), ошибки загрузки модуля будут доступны сразу же на экране.

Если вы используете PHP на веб-сервере, расположение и формат лог-файлов сильно зависит от используемого вами веб-сервера. Пожалуйста, обратитесь к документации вашего веб-сервера, т.к. в данном случае эта ситуация не управляется самим PHP.

Распространёнными проблемами являются расположение библиотеки DLL и DLL-файлов, от которых она зависит, значение " extension_dir" в php.ini, а также несовпадение настроек компиляции.

Если проблемой является несовпадение настроек компиляции, то возможно, вы скачали не тот DLL-файл. Попробуйте снова скачать модуль, на этот раз с правильными настройками. Ещё раз, информация функции phpinfo() сильно помогает в этом случае.



Компиляция разделяемых модулей с помощью команды pecl

PECL позволяет легко создавать разделяемые модули PHP. Используя » команду pecl, выполните следующее:


$ pecl install extname

Эта команда загрузит исходный код для модуля extname, скомпилирует и установит extname.so в вашу директорию extension_dir. Файл extname.so может быть затем загружен в php.ini

По умолчанию, команда pecl не будет устанавливать пакеты, отмеченные состоянием alpha или beta. Если нет доступных стабильных (stable) версий пакетов, вы можете установить beta-версию пакета, используя следующую команду:


$ pecl install extname-beta

Также, вы можете установить определённую версию, используя такой вариант:


$ pecl install extname-0.1

Замечание:

После подключения модуля в php.ini необходимо перезапустить веб-сервер для того, чтобы изменения вступили в силу.



Компиляция разделяемых модулей с помощью phpize

Иногда использование инсталлятора pecl не подходит. Это может быть связано с тем, что вы находитесь за файерволом или из-за того, что модуль, который вы хотите установить, недоступен в PECL-совместимом пакете (к примеру, модули из git, у которых ещё нет релизов). Если вам необходимо собрать такой модуль, вы можете использовать низкоуровневые утилиты для выполнения сборки вручную.

Команда phpize используется для подготовки окружения PHP-модуля. В следующем примере директория, где находятся исходные коды модуля, называется extname:

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

В случае успешной установки будет создан файл extname.so и помещён в PHP директорию модулей. Вам будет необходимо добавить строку extension=extname.so в php.ini перед использованием этого модуля.

Если в системе нет phpize, но существует возможность установки заранее скомпилированных пакетов (типа RPM), убедитесь, что установлена соответствующая версия пакета PHP для разработчиков, так как они часто содержат команду phpize с подходящими файлами заголовков для сборки PHP и его модулей.

Для дополнительной информации используйте команду phpize --help.



php-config

php-config - это простой скрипт командной строки для получения информации о конфигурации установленного PHP.

При компиляции модулей, если у вас установлено сразу несколько версий PHP, вы должны уточнить нужную версию с помощью опции --with-php-config во время конфигурирования сборки, указав путь до соответствующего php-config скрипта.

Список параметров командной строки доступных для php-config скрипта всегда можно получить запустив php-config с параметром -h:

Usage: /usr/local/bin/php-config [OPTION]
Options:
  --prefix            [...]
  --includes          [...]
  --ldflags           [...]
  --libs              [...]
  --extension-dir     [...]
  --include-dir       [...]
  --php-binary        [...]
  --php-sapis         [...]
  --configure-options [...]
  --version           [...]
  --vernum            [...]

Опции скрипта
Опция Описание
--prefix Директория, в которой установлен PHP, например, /usr/local
--includes Список -I опций со всеми подключаемыми файлами
--ldflags LD-флаги, с которыми был скомпилирован PHP
--libs Внешние библиотеки, с которыми был скомпилирован PHP
--extension-dir Директория, в которой по умолчанию ищутся модули
--include-dir Директория, куда по умолчанию устанавливаются заголовочные файлы
--php-binary Полный путь до исполняемых файлов php CLI или CGI
--php-sapis Показывает все доступные модули SAPI
--configure-options Конфигурационные опции для воссоздания настроек текущей установки PHP.
--version Версия PHP
--vernum Версия PHP в виде целого числа



Компиляция модулей PECL статически в PHP

Возможно, вы захотите собрать модуль PECL статично в ваш бинарный файл PHP. Для этого необходимо поместить код модуля в директорию php-src/ext/ и вызвать перегенерацию конфигурационных скриптов через систему сборки PHP.

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

В результате будет создана следующая директория:


/your/phpsrcdir/ext/extname

После этого, выполните заново сборку конфигурационного скрипта PHP и затем соберите PHP как обычно:


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

Замечание: Для запуска 'buildconf' скрипта вам понадобится autoconf версии 2.13 и automake версии 1.4+ (более новые версии autoconf могут работать, но это не поддерживается).

В зависимости от модуля будет использоваться одна из двух опций --enable-extname или --with-extname . Обычно, если модуль не требует подключения внешних библиотек, используется --enable. Чтобы узнать это, выполните следующую команду после buildconf:


$ ./configure --help | grep extname




Проблемы?

Содержание


Читайте FAQ

Некоторые проблемы возникают чаще других. Наиболее часто встречающиеся из них перечислены в разделе PHP FAQ этого руководства.



Другие проблемы

Если вы всё ещё не можете установить PHP, список рассылки, возможно, сможет помочь вам. Не забудьте сначала просмотреть архив, возможно, кто-то уже сталкивался с похожей проблемой и успешно её решил. Архив рассылки доступен на странице поддержки: » https://www.php.net/support.php Для подписки на список рассылки об установке PHP пришлите пустое сообщение на » php-install-subscribe@lists.php.net. Адрес списка рассылки: » php-install@lists.php.net.

Если вы хотите получить помощь из списка рассылки, пожалуйста, постарайтесь точно описать детали вашего окружения (такие как операционная система, версия PHP, используемый веб-сервер, используете ли вы PHP как CGI или модулем и т.д.), а также достаточное количество кода, чтобы другие смогли воспроизвести вашу проблему и попробовать решить её.



Сообщения о багах

Если вы думаете, что нашли ошибку в PHP, пожалуйста сообщите об этом. Возможно, разработчики PHP не знают об этой ошибке и пока вы не сообщите о ней, мало шансов что она будет исправлена. Вы можете сообщить об ошибке, используя систему отслеживания ошибок по адресу: » https://github.com/php/php-src/issues. Пожалуйста, не шлите сообщения об ошибках в список рассылки или на личные адреса разработчиков. Система отслеживания ошибок также пригодна и для запроса нововведений.

Прочитайте: » Как сообщать об ошибках перед тем как сообщать о них.




Конфигурация времени выполнения

Содержание


Файл конфигурации

Файл конфигурации (php.ini) считывается при запуске PHP. Для версий серверных модулей PHP это происходит только один раз при запуске веб-сервера. Для CGI и CLI версий это происходит при каждом вызове.

Поиск php.ini производится в следующих местах (по порядку поиска):

  • По месту расположения модуля SAPI (PHPIniDir директива Apache 2, -c параметр командной строки CGI и CLI)
  • Переменная среды PHPRC.
  • Местоположение файла php.ini может быть указано для различных версий PHP. Корневой ключ реестра зависит от разрядности операционной системы и установки PHP. Для 32-разрядного PHP на 32-разрядной Windows или 64-разрядного PHP и 64-разрядной Windows используйте [(HKEY_LOCAL_MACHINE\SOFTWARE\PHP]. Для 32-разрядного PHP на 64-разрядной Windows [HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\PHP]. Следующие ключи реестра исследуются при поиске для установок с совпадающей разрядностью: [HKEY_LOCAL_MACHINE\SOFTWARE\PHP\x.y.z], [HKEY_LOCAL_MACHINE\SOFTWARE\PHP\x.y] и [HKEY_LOCAL_MACHINE\SOFTWARE\PHP\x], где x, y и z подразумевают major, minor и release версии PHP. Для 32-разрядного PHP на 64-разрядной Windows ключи реестра будут другими: [HKEY_LOCAL_MACHINE\SOFTWARE\WOW6421Node\PHP\x.y.z], [HKEY_LOCAL_MACHINE\SOFTWARE\WOW6421Node\PHP\x.y] и [HKEY_LOCAL_MACHINE\SOFTWARE\WOW6421Node\PHP\x]. Если также имеется значение IniFilePath в любом из этих ключей, то местонахождение php.ini будет определено первым ключом по порядку (только для Windows).
  • [HKEY_LOCAL_MACHINE\SOFTWARE\PHP] или [HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\PHP], значение IniFilePath (только для Windows).
  • Текущая директория (исключая CLI).
  • Директория веб-сервера (для модулей SAPI) или директория PHP (иначе в Windows).
  • В директории Windows (C:\windows или C:\winnt) (для Windows) или --with-config-file-path с выбором при компиляции.

Если файл php-SAPI.ini существует (где SAPI - это тип интерфейса, который используется, например, php-cli.ini или php-apache.ini), то он используется вместо php.ini. Тип интерфейса между веб-сервером и PHP может быть определён с помощью функции php_sapi_name().

Замечание:

Веб-сервер Apache изменяет текущую директорию на корневую при запуске, в результате чего PHP считывает php.ini из корневой файловой системы, если файл существует.

В php.ini можно использовать переменные окружения, как показано ниже.

Пример #1 Переменные окружения php.ini

; PHP_MEMORY_LIMIT взята из переменных окружения
memory_limit = ${PHP_MEMORY_LIMIT}

Директивы php.ini, обрабатываемые модулями, описаны на соответствующих страницах модулей. Список директив ядра имеется в приложении. Не все директивы PHP документированы в этом руководстве: для ознакомления с полным списком директив доступных в вашей версии PHP, прочитайте комментарии вашего php.ini. Кроме того, вы можете найти полезной » последнюю версию php.ini из Git.

Пример #2 Пример php.ini

; любой текст в строке после точки с запятой (;) без кавычек игнорируется
[php] ; маркеры разделов (текст в квадратных скобках) также игнорируется
; Могут быть установлены следующие логические значения:
;    true, on, yes
; или false, off, no, none
register_globals = off
track_errors = yes

; вы можете заключать строки в двойные кавычки
include_path = ".:/usr/local/lib/php"

; обратный слеш обрабатывается так же, как любые другие символы
include_path = ".;c:\php\lib"

Возможно обращаться к существующим ini-переменным из ini-файлов. Пример: open_basedir = ${open_basedir} ":/new/dir".

Сканирование директорий

Существует возможность сконфигурировать PHP для сканирования директорий в поисках .ini-файлов после считывания php.ini. Это можно сделать на моменте компиляции, указав опцию --with-config-file-scan-dir. Сканирование директорий может быть переопределено во время исполнения установкой переменной среды PHP_INI_SCAN_DIR.

Можно сканировать несколько директорий, разделяя их разделителем, используемом в вашей операционной системе (; в Windows, NetWare и RISC OS; : на всех остальных платформах; в PHP есть константа PATH_SEPARATOR, которую можно использовать) Если PHP_INI_SCAN_DIR пуста, то PHP также будет сканировать директорию, заданную на этапе компиляции с помощью --with-config-file-scan-dir.

В каждой директории PHP сканирует все файлы заканчивающиеся на .ini в алфавитном порядке. Список всех загруженных файлов в том порядке, в котором они были загружены, доступен с помощью функции php_ini_scanned_files(), либо при запуске PHP с опцией --ini.

Допустим, что PHP сконфигурирован с --with-config-file-scan-dir=/etc/php.d,
и разделитель путей :...

$ php
  PHP загрузит все файлы /etc/php.d/*.ini как конфигурационные.

$ PHP_INI_SCAN_DIR=/usr/local/etc/php.d php
  PHP загрузит все файлы /usr/local/etc/php.d/*.ini как конфигурационные.

$ PHP_INI_SCAN_DIR=:/usr/local/etc/php.d php
  PHP загрузит все файлы /etc/php.d/*.ini, а потом
  /usr/local/etc/php.d/*.ini как конфигурационные.

$ PHP_INI_SCAN_DIR=/usr/local/etc/php.d: php
  PHP загрузит все файлы /usr/local/etc/php.d/*.ini, а потом
  /etc/php.d/*.ini как конфигурационные.


Файлы .user.ini

Включена поддержка INI-файлов в стиле .htaccess на уровне каталога. Эти файлы обрабатываются только CGI/FastCGI SAPI. Эта функция делает ненужным модуль PECL htscanner. Если вы используете PHP как модуль Apache, то для достижения того же эффекта, пользуйтесь файлами .htaccess.

В дополнение к основному файлу php.ini, PHP ищет INI-файлы в каждой директории, начиная с директории запрошенного PHP-файла и продолжает поиск до корневой директории (установленной в $_SERVER['DOCUMENT_ROOT']). Если PHP-файл находится вне корневой директории, то сканируется только его директория.

Только INI-настройки с режимами PHP_INI_PERDIR и PHP_INI_USER будут распознаны в INI-файлах в стиле .user.ini.

Две новых INI-директивы, user_ini.filename и user_ini.cache_ttl, контролируют использование пользовательских INI-файлов.

user_ini.filename устанавливает имя файла, по которому PHP производит поиск в каждой директории; если установлена пустая строка, то PHP поиск не производит. По умолчанию .user.ini.

user_ini.cache_ttl устанавливает насколько часто пользовательские INI-файлы будут обновляться. По умолчанию период обновления составляет 300 секунд (5 минут).



Где могут быть установлены параметры конфигурации

Эти режимы определяют, когда и где директива PHP может или не может быть установлена, и каждая директива в руководстве относится к одному из этих режимов. К примеру, некоторые настройки могут быть установлены с помощью PHP-скрипта, использующего ini_set(), тогда как другие могут требовать php.ini или httpd.conf.

К примеру, директива output_buffering соответствует PHP_INI_PERDIR, поэтому она не может быть установлена через ini_set(). Тем не менее, директива display_errors соответствует PHP_INI_ALL, поэтому она может быть установлена отовсюду, включая ini_set().

Определение режимов PHP_INI_*
Режим Описание
PHP_INI_USER Значение может быть установлено в пользовательских скриптах (с помощью ini_set()) или в реестре Windows. Значение может быть установлено в .user.ini
PHP_INI_PERDIR Значение может быть установлено в php.ini, .htaccess или httpd.conf
PHP_INI_SYSTEM Значение может быть установлено в php.ini или httpd.conf
PHP_INI_ALL Значение может быть установлено отовсюду



Как изменить настройки конфигурации

Запуск PHP как модуля Apache

Когда PHP используется как модуль Apache вы также можете менять настройки конфигурации, используя директивы в файлах конфигурации Apache (например, httpd.conf) и файлах .htaccess. Для этого вам необходимы "AllowOverride Options" или "AllowOverride All" привилегии.

Есть несколько директив Apache, которые позволяют вам изменить конфигурацию PHP посредством файлов конфигурации Apache. С директивами PHP_INI_ALL, PHP_INI_PERDIR и PHP_INI_SYSTEM можно ознакомиться в приложении Список директив php.ini.

php_value name value

Устанавливает значение указанной директивы. Может использоваться только с директивами типа PHP_INI_ALL и PHP_INI_PERDIR. Для очистки предыдущих установленных значений используйте значение none.

Замечание: Не используйте php_value для установки логических значений. Вместо этого необходимо использовать php_flag (смотрите ниже).

php_flag name on|off

Используется для установки директивам логических значений. Может быть использовано только с директивами типа PHP_INI_ALL и PHP_INI_PERDIR.

php_admin_value name value

Устанавливает значение указанной директивы. Не может быть использовано в файлах .htaccess. Директивы любого типа, установленные с помощью php_admin_value не могут быть переопределены через .htaccess или ini_set(). Чтобы очистить предыдущее значение используйте значение none.

php_admin_flag name on|off

Используется для установки директивам логических значений. Не может быть использовано в файлах .htaccess. Директивы любого типа, установленные с помощью php_admin_flag не могут быть переопределены через .htaccess или ini_set().

Пример #1 Пример конфигурации Apache

<IfModule mod_php5.c>
  php_value include_path ".:/usr/local/lib/php"
  php_admin_flag engine on
</IfModule>
<IfModule mod_php4.c>
  php_value include_path ".:/usr/local/lib/php"
  php_admin_flag engine on
</IfModule>

Предостережение

PHP-константы недоступны вне PHP. К примеру, в httpd.conf вы не можете использовать константы PHP такие как E_ALL или E_NOTICE, чтобы установить директиву error_reporting, так как они не будут иметь значения и будут приравниваться к 0. Используйте вместо этого соответствующие значения типа bitmask (битовая маска). Эти константы могут быть использованы в php.ini

Изменение конфигурации PHP через реестр Windows

При использовании PHP в Windows значения конфигурации могут быть изменены на уровне директории посредством реестра Windows. Значения конфигурации хранятся в ключе реестра HKLM\SOFTWARE\PHP\Per Directory Values, в подключах, включающих полный путь. К примеру, значения конфигурации для директории c:\inetpub\wwwroot могут храниться в ключе HKLM\SOFTWARE\PHP\Per Directory Values\c\inetpub\wwwroot. Настройки для директории будут действительны для любых скриптов, запущенных из этой директории или её поддиректории. Значения ключа должны иметь название конфигурационной директивы PHP и строковое значение. PHP-константы в значениях игнорируются. Однако только значения конфигурации, изменяемые в PHP_INI_USER могут быть установлены таким образом, значения же PHP_INI_PERDIR не могут, потому что эти значения конфигурации перечитываются для каждого запроса.

Другие интерфейсы в PHP

Независимо от того, как вы запускаете PHP, вы можете изменять некоторые значения во время выполнения ваших скриптов c помощью ini_set(). Для более детальной информации смотрите документацию на странице функции ini_set().

Если вам интересен полный список конфигурационных настроек вашей системы с текущими значениями, то вы можете запустить функцию phpinfo() и просмотреть результирующую страницу. Вы также можете получить доступ к значениям индивидуально сконфигурированных директив в процессе выполнения, используя ini_get() или get_cfg_var().





Справочник языка


Основы синтаксиса

Содержание


Теги PHP

Когда PHP обрабатывает файл, он ищет открывающие и закрывающие теги, такие как <?php и ?>, которые указывают PHP, когда начинать и заканчивать обработку кода между ними. Подобный способ обработки позволяет PHP внедряться во все виды различных документов, так как всё, что находится вне пары открывающих и закрывающих тегов, будет проигнорировано парсером PHP.

PHP включает в себя короткий echo-тег <?=, который является сокращением для более многословного <?php echo.

Пример #1 Открывающие и закрывающие теги PHP

1. <?php echo 'если вы хотите хранить код PHP в документах XHTML или XML,
то используйте эти теги'
; ?>

2. Вы можете использовать короткий 'echo'-тег чтобы <?= 'напечатать эту строку' ?>.
Этот тег эквивалентен такому коду
<?php echo 'напечатать эту строку' ?>.

3. <? echo 'этот код с короткими тегами, но он будет работать только если '.
'включена опция "short_open_tag"'; ?>

Короткие теги (третий пример) доступны по умолчанию, но их можно отключить с помощью директивы short_open_tag в конфигурационном файле php.ini или отключены по умолчанию, если PHP был скомпилирован с опцией --disable-short-tags.

Замечание:

Поскольку короткие теги можно отключить, рекомендуется использовать только обычные теги (<?php ?> и <?= ?>) для максимальной совместимости.

Если файл содержит только код PHP, предпочтительно опустить закрывающий тег в конце файла. Это помогает избежать добавления случайных символов пробела или перевода строки после закрывающего тега PHP, которые могут послужить причиной нежелательных эффектов, так как PHP начинает выводить данные в буфер при отсутствии намерения у программиста выводить какие-либо данные в этой точке скрипта.

<?php
echo "Hello world";

// ... ещё код

echo "Последнее выражение";

// Скрипт заканчивается тут без закрывающего тега PHP



Изолирование от HTML

Все, что находится вне пары открывающегося и закрывающегося тегов, игнорируется интерпретатором PHP, у которого есть возможность обрабатывать файлы со смешанным содержимым. Это позволяет PHP-коду быть встроенным в документы HTML, к примеру, для создания шаблонов.

<p>Это будет проигнорировано PHP и отображено браузером.</p>
<?php echo 'А это будет обработано.'; ?>
<p>Это тоже будет проигнорировано PHP и отображено браузером.</p>
Это работает так, как и ожидается, потому что когда интерпретатор PHP встречает закрывающие теги ?>, он просто начинает выводить все что найдёт (за исключением сразу следующего символа перевода строки - смотрите раздел разделение инструкций) пока не встретит другой открывающий тег за исключением случая с содержащимся внутри кода условным оператором, в котором интерпретатор определяет результат условия перед принятием решения что пропустить. Ознакомьтесь со следующим примером.

Использование структур с условиями

Пример #1 Продвинутое изолирование с использованием условий

<?php if ($expression == true): ?>
Это будет отображено, если выражение истинно.
<?php else: ?>
В ином случае будет отображено это.
<?php endif; ?>
В этом примере PHP пропускает блоки, где условие не соблюдается. Даже несмотря на то, что они находятся вне пары открывающих/закрывающих тегов, PHP пропустит их в соответствии с условием, так как интерпретатор PHP будет перепрыгивать через блоки, содержащиеся внутри условия, которое не соблюдается.

При выводе больших блоков текста выход из режима синтаксического разбора PHP обычно более эффективен, чем отправка текста с помощью функций echo или print.

Замечание:

Кроме того, если вы намереваетесь вставлять PHP-код в XML или XHTML, чтобы соответствовать XML стандартам, вам следует использовать форму <?php ?>.



Разделение инструкций

Как в C или Perl, PHP требует окончания инструкций точкой запятой в конце каждой инструкции. Закрывающий тег блока PHP-кода автоматически применяет точку с запятой; т.е. нет необходимости ставить точку с запятой в конце последней строки блока с PHP-кодом. Закрывающий тег блока "поглотит" немедленно следующий за ним переход на новую строку, если таковой будет обнаружен.

Пример #1 Пример, показывающий закрывающий тег, охватывающий завершающую новую строку

<?php echo "Какой-то текст"; ?>
Нет новой строки
<?= "А сейчас, новая строка" ?>

Результат выполнения данного примера:

Какой-то текстНет новой строки
А сейчас, новая строка

Примеры входа и выхода из парсера PHP:

<?php
echo 'Это тест';
?>

<?php echo 'Это тест' ?>

<?php echo 'Мы опустили последний закрывающий тег';

Замечание:

Закрывающий тег PHP-блока в конце файла не является обязательным, и в некоторых случаях его опускание довольно полезно, например, при использовании include или require, так, что нежелательные пробелы не останутся в конце файла и вы всё ещё сможете добавить http-заголовки после подключения к ответу сервера. Это также удобно при использовании буферизации вывода, где также нежелательно иметь пробелы в конце частей ответа, сгенерированного подключаемыми файлами.



Комментарии

PHP поддерживает комментарии в стиле 'C', 'C++' и оболочки Unix (стиль Perl). Например:

<?php
echo "Это тест"; // Это однострочный комментарий в стиле C++
/* Это многострочный комментарий
ещё одна строка комментария */
echo "Это ещё один тест";
echo
"Последний тест"; # Это комментарий в стиле оболочки Unix
?>

Однострочные комментарии идут только до конца строки или текущего блока PHP-кода, в зависимости от того, что идёт перед ними. Это означает, что HTML-код после // ... ?> или # ... ?> БУДЕТ напечатан: ?> завершает режим PHP и возвращает режим HTML, а // или # не могут повлиять на это.

<h1>Это <?php # echo "простой";?> пример</h1>
<p>Заголовок вверху выведет 'Это пример'.</p>

'C'-комментарии заканчиваются при первой же обнаруженной последовательности */. Убедитесь, что вы не вкладываете друг в друга 'C'-комментарии. Очень легко допустить эту ошибку при комментировании большого блока кода.

<?php
/*
echo "Это тест"; /* Этот комментарий вызовет проблему */
*/
?>




Типы

Содержание


Введение

У каждого выражения в PHP один из следующих встроенных типов в зависимости от его значения:

  • null
  • bool
  • int
  • float (floating-point number)
  • string
  • array
  • object
  • callable
  • resource

PHP – динамически типизированный язык, что означает, что по умолчанию нет необходимости указывать тип переменной, так как он будет определён во время выполнения. Однако можно статически типизировать некоторые аспекты языка, используя декларации типов.

Типы ограничивают тип операций, которые могут быть выполнены над ними. Однако, если выражение/переменная используется в операции, которую не поддерживает её тип, PHP попытается преобразовать значение в тип, который поддерживает операцию. Этот процесс зависит от контекста, в котором используется значение. Для получения дополнительной информации смотрите раздел Манипуляции с типами.

Подсказка

Таблицы сравнения типов также могут быть полезны, поскольку в них представлены различные примеры сравнения значений разных типов.

Замечание: Можно заставить выражение оцениваться с определённым типом, используя приведение типов. Переменная также может быть приведена к определённому типу с помощью функции settype().

Чтобы проверить значение и тип выражения, используйте функцию var_dump(). Чтобы получить тип выражения, используйте функцию get_debug_type(). Однако, чтобы проверить, является ли выражение определённым типом, используйте функции is_type.

<?php
$a_bool
= true; // логическое значение
$a_str = "foo"; // строка
$a_str2 = 'foo'; // строка
$an_int = 12; // целое число

echo get_debug_type($a_bool), "\n";
echo
get_debug_type($a_str), "\n";

// Если это целое число, увеличить на четыре
if (is_int($an_int)) {
$an_int += 4;
}
var_dump($an_int);

// Если $a_bool - это строка, вывести её
if (is_string($a_bool)) {
echo
"Строка: $a_bool";
}
?>

Результат выполнения данного примера в PHP 8:

bool
string
int(16)

Замечание: До PHP 8.0.0, где функция get_debug_type() недоступна, вместо неё можно использовать функцию gettype(). Однако она не использует канонические имена типов.



Система типов

В PHP используется система номинальных типов с сильным поведенческим отношением подтипизации. Отношение подтипизации проверяется во время компиляции, в то время как верификация типов проверяется динамически во время выполнения.

Система типов PHP поддерживает различные базовые типы, которые могут быть объединены вместе для создания более сложных типов. Некоторые из этих типов могут быть записаны как объявление типов.

Базовые типы

Некоторые базовые типы являются встроенными типами, которые тесно интегрированы с языком и не могут быть воспроизведены с помощью типов, определённых пользователем.

Список базовых типов:

Составные типы

Можно объединять простые типы в составные типы. PHP позволяет объединять типы следующими способами:

  • Пересечение классов-типов (интерфейсов и имён классов).
  • Объединение типов.

Пересечение типов

Пересечение типов принимает значения, удовлетворяющие не одному, а нескольким объявлениям типов классов. Отдельные типы, образующие пересечение типов, соединяются символом &. Поэтому пересечение типов, состоящее из типов T, U и V, будет записано как T&U&V.

Объединение типов

Объединение типов принимает значения нескольких различных типов, а не одного. Отдельные типы, образующие объединение типов, соединяются символом |. Поэтому объединение типов, состоящее из типов T, U и V, будет записано как T|U|V. Если один из типов является пересечением типов, то для записи в DNF его нужно заключить в скобки: T|(X&Y).

Псевдонимы типов

PHP поддерживает два псевдонима типов: mixed и iterable, которые соответствуют объединению типов object|resource|array|string|float|int|bool|null и Traversable|array соответственно.

Замечание: PHP не поддерживает определяемые пользователем псевдонимы типов.



NULL

Тип null - это единичный тип PHP, то есть он имеет только одно значение: null.

Неопределённые и unset() переменные преобразуются в значение null.

Синтаксис

Существует только одно значение типа null - регистронезависимая константа null.

<?php
$var
= NULL;
?>

Приведение к null

Внимание

Данная функциональность объявлена УСТАРЕВШЕЙ, начиная с PHP 7.2.0 и была УДАЛЕНА в версии PHP 8.0.0. Использовать эту функцию крайне не рекомендуется.

Приведение переменной к null с использованием (unset) $var не удаляет переменную и её значение. Данное выражение только возвращает null

Смотрите также



Логический тип

У логического типа (bool) только два значения, которые используются для выражения истинностного значения. Он может быть либо true, либо false.

Синтаксис

Для указания bool, используйте константы true или false. Они обе регистронезависимы.

<?php
$foo
= True; // присвоить $foo значение TRUE
?>

Обычно, некоторый оператор возвращает значение типа bool, которое потом передаётся управляющей конструкции.

<?php
// == это оператор, который проверяет
// эквивалентность и возвращает boolean
if ($action == "show_version") {
echo
"Версия 1.23";
}

// это необязательно...
if ($show_separators == TRUE) {
echo
"<hr>\n";
}

// ... потому что следующее имеет тот же самый смысл:
if ($show_separators) {
echo
"<hr>\n";
}
?>

Преобразование в логический тип

Для явного преобразования в bool, используйте приведение (bool). Обычно в этом нет необходимости, поскольку при использовании значения в логическом контексте оно автоматически интерпретируется как значение логического типа (bool). Дополнительную информацию смотрите на странице манипуляции с типами.

При преобразовании в bool, следующие значения рассматриваются как false:

  • само значение boolean false
  • integer 0 (ноль)
  • float 0.0 (ноль) и -0.0 (минус ноль)
  • пустая строка "" и строка "0"
  • массив без элементов
  • особый тип NULL (включая неустановленные переменные)
  • внутренние объекты, которые перегружают своё поведение приведения к логическому типу. Например: объекты SimpleXML, созданные из пустых элементов без атрибутов.

Все остальные значения считаются true (включая resource и NAN).

Внимание

-1 рассматривается как true, как и любое другое ненулевое (отрицательное или положительное) число!

<?php
var_dump
((bool) ""); // bool(false)
var_dump((bool) "0"); // 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)
?>


Целые числа

int - это число из множества ℤ = {..., -2, -1, 0, 1, 2, ...}.

Синтаксис

Целые числа (int) могут быть указаны в десятичной (основание 10), шестнадцатеричной (основание 16), восьмеричной (основание 8) или двоичной (основание 2) системе счисления. Для задания отрицательных целых (int) используется оператор отрицания

Для записи в восьмеричной системе счисления, необходимо поставить перед числом 0 (ноль). Начиная с PHP 8.1.0, восьмеричной нотации также может предшествовать 0o или 0O. Для записи в шестнадцатеричной системе счисления, необходимо поставить перед числом 0x. Для записи в двоичной системе счисления, необходимо поставить перед числом 0b

Начиная с PHP 7.4.0, целочисленные литералы могут содержать подчёркивания (_) между цифрами для лучшей читаемости литералов. Эти подчёркивания удаляются сканером PHP.

Пример #1 Целые числа

<?php
$a
= 1234; // десятичное число
$a = 0123; // восьмеричное число (эквивалентно 83 в десятичной системе)
$a = 0o123; // восьмеричное число (начиная с PHP 8.1.0)
$a = 0x1A; // шестнадцатеричное число (эквивалентно 26 в десятичной системе)
$a = 0b11111111; // двоичное число (эквивалентно 255 в десятичной системе)
$a = 1_234_567; // десятичное число (с PHP 7.4.0)
?>

Формально, структура целых чисел int принята в PHP 8.1.0 (ранее не допускались восьмеричные префиксы 0o или 0O, а до PHP 7.4.0 не допускалось подчёркивание):

десятичные        : [1-9][0-9]*(_[0-9]+)*
                  | 0

шестнадцатеричные : 0[xX][0-9a-fA-F]+(_[0-9a-fA-F]+)*

восьмеричные      : 0[oO]?[0-7]+(_[0-7]+)*

двоичные          : 0[bB][01]+(_[01]+)*

целые             : десятичные
                  | шестнадцатеричные
                  | восьмеричные
                  | двоичные

Размер типа int зависит от платформы, хотя, как правило, максимальное значение примерно равно 2 миллиардам (это 32-битное знаковое). 64-битные платформы обычно имеют максимальное значение около 9E18. PHP не поддерживает беззнаковые целые числа (int). Размер int может быть определён с помощью константы PHP_INT_SIZE, максимальное значение - с помощью константы PHP_INT_MAX, а с помощью константы PHP_INT_MIN можно определить минимальное значение.

Переполнение целых чисел

Если PHP обнаружил, что число превышает размер типа int, он будет интерпретировать его в качестве float. Аналогично, если результат операции лежит за границами типа int, он будет преобразован в float.

Пример #2 Переполнение целых на 32-битных системах

<?php
$large_number
= 2147483647;
var_dump($large_number); // int(2147483647)

$large_number = 2147483648;
var_dump($large_number); // float(2147483648)

$million = 1000000;
$large_number = 50000 * $million;
var_dump($large_number); // float(50000000000)
?>

Пример #3 Переполнение целых на 64-битных системах

<?php
$large_number
= 9223372036854775807;
var_dump($large_number); // int(9223372036854775807)

$large_number = 9223372036854775808;
var_dump($large_number); // float(9.2233720368548E+18)

$million = 1000000;
$large_number = 50000000000000 * $million;
var_dump($large_number); // float(5.0E+19)
?>

В PHP нет оператора деления целых чисел (int), для этого используйте функцию intdiv()>. Результатом 1/2 будет float 0.5. Если привести значение к int, оно будет округлено вниз, то есть будет отброшена дробная часть числа. Для большего контроля над округлением используйте функцию round().

<?php
var_dump
(25/7); // float(3.5714285714286)
var_dump((int) (25/7)); // int(3)
var_dump(round(25/7)); // float(4)
?>

Преобразование в целое

Для явного преобразования в int, используйте приведение (int) или (integer). Однако, в большинстве случаев, в приведении типа нет необходимости, так как значение будет автоматически преобразовано, если оператор, функция или управляющая структура требует аргумент типа int. Значение также может быть преобразовано в int с помощью функции intval().

Если resource преобразуется в int, то результатом будет уникальный номер ресурса, привязанный к resource во время исполнения PHP программы.

Смотрите также: Манипуляции с типами.

Из булевого типа

false преобразуется в 0 (ноль), а true - в 1 (единицу).

Из чисел с плавающей точкой

При преобразовании из float в int, число будет округлено в сторону нуля. Начиная с PHP 8.1.0, при неявном преобразовании неинтегрального числа с плавающей точкой (float) в целое число (int), которое теряет точность, выдаётся уведомление об устаревании.

<?php

function foo($value): int {
return
$value;
}

var_dump(foo(8.1)); // "Deprecated: Implicit conversion from float 8.1 to int loses precision" начиная с PHP 8.1.0
var_dump(foo(8.1)); // 8 до PHP 8.1.0
var_dump(foo(8.0)); // 8 в обоих случаях

var_dump((int)8.1); // 8 в обоих случаях
var_dump(intval(8.1)); // 8 в обоих случаях
?>

Если число с плавающей точкой превышает размеры int (обычно +/- 2.15e+9 = 2^31 на 32-битных системах и +/- 9.22e+18 = 2^63 на 64-битных системах, результат будет неопределённым, так как float не имеет достаточной точности, чтобы вернуть верный результат в виде целого числа (int). В этом случае не будет выведено ни предупреждения, ни даже замечания!

Замечание:

Значения NaN и Infinity при приведении к int становятся равными нулю, вместо неопределённого значения в зависимости от платформы.

Внимание

Никогда не приводите неизвестную дробь к int, так как это иногда может дать неожиданные результаты.

<?php
echo (int) ( (0.1+0.7) * 10 ); // выводит 7!
?>

Смотрите более подробно: предупреждение о точности чисел с плавающей точкой.

Из строк

Если строка содержит число или ведущую числовую последовательность, тогда она будет преобразована в соответствующее целое число, в противном случае она преобразуется в ноль (0).

Из NULL

Значение null всегда преобразуется в ноль (0).

Из других типов

Предостережение

Для других типов поведение преобразования в int не определено. Не полагайтесь на любое наблюдаемое поведение, так как оно может измениться без предупреждения.



Числа с плавающей точкой

Числа с плавающей точкой или числа с плавающей запятой (также известные как "float", "double" или "real") могут быть определены следующими синтаксисами:

<?php
$a
= 1.234;
$b = 1.2e3;
$c = 7E-10;
$d = 1_234.567; // начиная с PHP 7.4.0
?>

Формально, начиная с PHP 7.4.0 (ранее подчёркивание не разрешалось):

LNUM          [0-9]+(_[0-9]+)*
DNUM          ([0-9]*(_[0-9]+)*[\.]{LNUM}) | ({LNUM}[\.][0-9]*(_[0-9]+)*)
EXPONENT_DNUM (({LNUM} | {DNUM}) [eE][+-]? {LNUM})

Размер числа с плавающей точкой зависит от платформы, хотя максимум, как правило, составляет 1.8e308 с точностью около 14 десятичных цифр (64-битный формат IEEE).

Внимание

Точность чисел с плавающей точкой

Числа с плавающей точкой имеют ограниченную точность. Хотя это зависит от операционной системы, в PHP обычно используется формат двойной точности IEEE 754, дающий максимальную относительную ошибку округления порядка 1.11e-16. Неэлементарные арифметические операции могут давать большие ошибки, и, разумеется, необходимо принимать во внимание распространение ошибок при совместном использовании нескольких операций.

Кроме того, рациональные числа, которые могут быть точно представлены в виде чисел с плавающей точкой с основанием 10, например, 0.1 или 0.7, не имеют точного внутреннего представления в качестве чисел с плавающей точкой с основанием 2, вне зависимости от размера мантиссы. Поэтому они и не могут быть преобразованы в их внутреннюю двоичную форму без небольшой потери точности. Это может привести к неожиданным результатам: например, floor((0.1+0.7)*10) скорее всего вернёт 7 вместо ожидаемого 8, так как результат внутреннего представления будет чем-то вроде 7.9999999999999991118....

Так что никогда не доверяйте точности чисел с плавающей точкой до последней цифры и не проверяйте напрямую их равенство. Если вам действительно необходима высокая точность, используйте математические функции произвольной точности и gmp-функции.

"Простое" объяснение можно найти в » руководстве по числам с плавающей точкой, которое также называется "Why don’t my numbers add up?" ("Почему мои числа не складываются?")

Преобразование в число с плавающей точкой

Из строк

Если строка содержит число или ведущую числовую последовательность, тогда она будет преобразована в соответствующее значение с плавающей точкой, в противном случае она преобразуется в ноль (0).

Из других типов

Для значений других типов преобразование выполняется путём преобразования значения сначала в целое число (int), а затем в число с плавающей точкой ( float ). Смотрите Преобразование в целое число для получения дополнительной информации.

Замечание:

Поскольку определённые типы имеют неопределённое поведение при преобразовании в целое число (int), то же самое происходит и при преобразовании в число с плавающей точкой (float).

Сравнение чисел с плавающей точкой

Как указано выше, проверять числа с плавающей точкой на равенство проблематично из-за их внутреннего представления. Тем не менее, существуют способы для их сравнения, которые работают несмотря на все эти ограничения.

Для сравнения чисел с плавающей точкой используется верхняя граница относительной ошибки при округлении. Эта величина называется машинной эпсилон или единицей округления (unit roundoff) и представляет собой самую маленькую допустимую разницу при расчётах.

$a и $b равны до 5-ти знаков после точки.

<?php
$a
= 1.23456789;
$b = 1.23456780;
$epsilon = 0.00001;

if (
abs($a - $b) < $epsilon) {
echo
"true";
}
?>

NaN

Некоторые числовые операции могут возвращать значение, представляемое константой NAN. Данный результат означает неопределённое или непредставимое значение в операциях с плавающей точкой. Любое строгое или нестрогое сравнение данного значения с другим значением, кроме true, включая его самого, возвратит false.

Так как NAN представляет собой неограниченное количество различных значений, то NAN не следует сравнивать с другими значениями, включая её саму. Вместо этого, для определения её наличия необходимо использовать функцию is_nan().



Строки

Строка (тип string) - это набор символов, где символ - это то же самое, что и байт. Это значит, что PHP поддерживает ровно 256 различных символов, а также то, что в PHP нет встроенной поддержки Unicode. Смотрите также подробности реализации строкового типа.

Замечание: В 32-битных системах и в более ранних версиях PHP, строки (string) не могут быть более 2 ГБ (2147483647 байт).

Синтаксис

Строка может быть определена четырьмя различными способами:

Одинарные кавычки

Простейший способ определить строку - это заключить её в одинарные кавычки (символ ').

Чтобы использовать одинарную кавычку внутри строки, проэкранируйте её обратным слешем (\). Если необходимо написать сам обратный слеш, продублируйте его (\\). Все остальные случаи применения обратного слеша будут интерпретированы как обычные символы: это означает, что если вы попытаетесь использовать другие управляющие последовательности, такие как \r или \n, они будут выведены как есть вместо какого-либо особого поведения.

Замечание: В отличие от синтаксиса двойных кавычек и heredoc, переменные и управляющие последовательности для специальных символов, заключённых в одинарные кавычки, не обрабатываются.

<?php
echo 'это простая строка';

echo
'Также вы можете вставлять в строки
символ новой строки вот так,
это нормально'
;

// Выводит: Однажды Арнольд сказал: "I'll be back"
echo 'Однажды Арнольд сказал: "I\'ll be back"';

// Выводит: Вы удалили C:\*.*?
echo 'Вы удалили C:\\*.*?';

// Выводит: Вы удалили C:\*.*?
echo 'Вы удалили C:\*.*?';

// Выводит: Это не будет развёрнуто: \n новая строка
echo 'Это не будет развёрнуто: \n новая строка';

// Выводит: Переменные $expand также $either не разворачиваются
echo 'Переменные $expand также $either не разворачиваются';
?>

Двойные кавычки

Если строка заключена в двойные кавычки ("), PHP распознает следующие управляющие последовательности специальных символов:

Управляющие последовательности
Последовательность Значение
\n новая строка (LF или 0x0A (10) в ASCII)
\r возврат каретки (CR или 0x0D (13) в ASCII)
\t горизонтальная табуляция (HT или 0x09 (9) в ASCII)
\v вертикальная табуляция (VT или 0x0B (11) в ASCII)
\e escape-знак (ESC или 0x1B (27) в ASCII)
\f подача страницы (FF или 0x0C (12) в ASCII)
\\ обратная косая черта
\$ знак доллара
\" двойная кавычка
\[0-7]{1,3} последовательность символов, соответствующая регулярному выражению символа в восьмеричной системе счисления, который молча переполняется, чтобы поместиться в байт (т.е. "\400" === "\000")
\x[0-9A-Fa-f]{1,2} последовательность символов, соответствующая регулярному выражению символа в шестнадцатеричной системе счисления
\u{[0-9A-Fa-f]+} последовательность символов, соответствующая регулярному выражению символа Unicode, которая отображается в строка в представлении UTF-8

Как и в строке, заключённой в одинарные кавычки, экранирование любого другого символа выведет также и сам символ экранирования.

Но самым важным свойством строк в двойных кавычках является обработка переменных. Смотрите более подробно обработку строк.

Heredoc

Третий способ определения строк - это использование heredoc-синтаксиса: <<<. После этого оператора необходимо указать идентификатор, затем перевод строки. После этого идёт сама строка, а потом этот же идентификатор, закрывающий вставку.

Закрывающий идентификатор может иметь отступ с помощью пробела или табуляции, и в этом случае отступ будет удалён из всех строк в строке документа. До PHP 7.3.0 закрывающий идентификатор должен был находиться в самом начале новой строки.

Кроме того, закрывающий идентификатор должен соответствовать тем же правилам именования, что и любая другая метка в PHP: он должен содержать только буквенно-цифровые символы и подчёркивания и должен начинаться с нецифрового символа или символа подчёркивания.

Пример #1 Базовый пример использования Heredoc в PHP 7.3.0

<?php
// без отступов
echo <<<END
a
b
c
\n
END;

// 4 отступа
echo <<<END
a
b
c
END;

Результат выполнения данного примера в PHP 7.3:

      a
     b
    c

  a
 b
c

Если закрывающий идентификатор смещён дальше, чем любая строка тела, будет выброшено ParseError:

Пример #2 Закрывающий идентификатор не должен иметь отступ больше, чем любая строка тела

<?php
echo <<<END
a
b
c
END;

Результат выполнения данного примера в PHP 7.3:

PHP Parse error:  Invalid body indentation level (expecting an indentation level of at least 3) in example.php on line 4

Если у закрывающего идентификатора есть отступ, табуляции также могут использоваться, однако табуляции и пробелы не должны смешиваться в отношении отступа закрывающего идентификатора и отступа тела (вплоть до закрывающего идентификатора). В любом из этих случаев будет выброшено ParseError. Эти ограничения на пробелы были включены, потому что смешивание табуляции и пробелов для отступов вредно для разбора.

Пример #3 Другой отступ для закрывающего идентификатора тела (пробелов)

<?php
// Весь следующий код не работает.

// Другой отступ для закрывающего идентификатора (табов) тела (пробелов)
{
echo <<<END
a
END;
}

// смешивание пробелов и табуляции в теле
{
echo <<<END
a
END;
}

// смешивание пробелов и табуляции в закрывающем идентификаторе
{
echo <<<END
a
END;
}

Результат выполнения данного примера в PHP 7.3:

PHP Parse error:  Invalid indentation - tabs and spaces cannot be mixed in example.php line 8

За закрывающим идентификатором основной строки не обязательно ставить точку с запятой или новую строку. Например, начиная с PHP 7.3.0 разрешён следующий код:

Пример #4 Продолжение выражения после закрывающего идентификатора

<?php
$values
= [<<<END
a
b
c
END, 'd e f'];
var_dump($values);

Результат выполнения данного примера в PHP 7.3:

array(2) {
  [0] =>
  string(11) "a
  b
    c"
  [1] =>
  string(5) "d e f"
}
Внимание

Если закрывающий идентификатор был найден в начале строки, то независимо от того, был ли он частью другого слова, его можно рассматривать как закрывающий идентификатор и выбросить ParseError.

Пример #5 Закрывающий идентификатор в теле текста имеет тенденцию вызывать ParseError

<?php
$values
= [<<<END
a
b
END ING
END
, 'd e f'];

Результат выполнения данного примера в PHP 7.3:

PHP Parse error:  syntax error, unexpected identifier "ING", expecting "]" in example.php on line 6

Чтобы избежать этой проблемы, безопасно следуйте простому правилу: не выбирайте закрывающий идентификатор, который появляется в теле текста.

Внимание

До PHP 7.3.0 очень важно отметить, что строка с закрывающим идентификатором не должна содержать других символов, за исключением точки с запятой (;). Это означает, что идентификатор не должен вводиться с отступом и что не может быть никаких пробелов или знаков табуляции до или после точки с запятой. Важно также понимать, что первым символом перед закрывающим идентификатором должен быть символ новой строки, определённый в вашей операционной системе. Например, в UNIX системах, включая macOS, это \n. После закрывающего идентификатора также сразу должна начинаться новая строка.

Если это правило нарушено и закрывающий идентификатор не является "чистым", считается, что закрывающий идентификатор отсутствует и PHP продолжит его поиск дальше. Если в этом случае верный закрывающий идентификатор так и не будет найден, то это вызовет ошибку парсинга с номером строки в конце скрипта.

Пример #6 Пример неправильного синтаксиса, до PHP 7.3.0

<?php
class foo {
public
$bar = <<<EOT
bar
EOT;
// отступ перед закрывающим идентификатором недопустим
}
?>

Пример #7 Пример правильного синтаксиса, даже до PHP 7.3.0

<?php
class foo {
public
$bar = <<<EOT
bar
EOT;
}
?>

Heredoc, содержащий переменные, не может использоваться для инициализации свойств класса.

Heredoc-текст ведёт себя так же, как и строка в двойных кавычках, при этом их не имея. Это означает, что вам нет необходимости экранировать кавычки в heredoc, но вы по-прежнему можете использовать вышеперечисленные управляющие последовательности. Переменные обрабатываются, но с применением сложных переменных внутри heredoc нужно быть также внимательным, как и при работе со строками.

Пример #8 Пример определения heredoc-строки

<?php
$str
= <<<EOD
Пример строки,
охватывающей несколько строк,
с использованием heredoc-синтаксиса.
EOD;

/* Более сложный пример с переменными. */
class foo
{
var
$foo;
var
$bar;

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

$foo = new foo();
$name = 'Имярек';

echo <<<EOT
Меня зовут "$name". Я печатаю $foo->foo.
Теперь я вывожу
{$foo->bar[1]}.
Это должно вывести заглавную букву 'A': \x41
EOT;
?>

Результат выполнения данного примера:

Меня зовут "Имярек". Я печатаю Foo.
Теперь, я вывожу Bar2.
Это должно вывести заглавную букву 'A': A

Также возможно использовать heredoc-синтаксис для передачи данных через аргументы функции:

Пример #9 Пример применения heredoc в аргументах

<?php
var_dump
(array(<<<EOD
foobar!
EOD
));
?>

Можно инициализировать статические переменные и свойства/константы класса с помощью синтаксиса heredoc:

Пример #10 Использование heredoc для инциализации статических переменных

<?php
// Статические переменные
function foo()
{
static
$bar = <<<LABEL
Здесь ничего нет...
LABEL;
}

// Константы/свойства класса
class foo
{
const
BAR = <<<FOOBAR
Пример использования константы
FOOBAR;

public
$baz = <<<FOOBAR
Пример использования поля
FOOBAR;
}
?>

Можно также окружать идентификатор Heredoc двойными кавычками:

Пример #11 Использование двойных кавычек в heredoc

<?php
echo <<<"FOOBAR"
Привет, мир!
FOOBAR;
?>

Nowdoc

Nowdoc - это то же самое для строк в одинарных кавычках, что и heredoc для строк в двойных кавычках. Nowdoc похож на heredoc, но внутри него не осуществляется никаких подстановок. Эта конструкция идеальна для внедрения PHP-кода или других больших блоков текста без необходимости его экранирования. В этом он немного похож на SGML-конструкцию <![CDATA[ ]]> тем, что объявляет блок текста, не предназначенный для обработки.

Nowdoc указывается той же последовательностью <<<, что используется в heredoc, но последующий за ней идентификатор заключается в одинарные кавычки, например, <<<'EOT'. Все условия, действующие для идентификаторов heredoc также действительны и для nowdoc, особенно те, что относятся к закрывающему идентификатору.

Пример #12 Пример использования nowdoc

<?php
echo <<<'EOD'
Пример текста,
занимающего несколько строк,
с помощью синтаксиса nowdoc. Обратные слеши всегда обрабатываются буквально,
например, \\ и \'.
EOD;

Результат выполнения данного примера:

Пример текста,
занимающего несколько строк,
с помощью синтаксиса nowdoc. Обратные слеши всегда обрабатываются буквально,
например, \\ и \'.

Пример #13 Nowdoc пример цитирования строки с переменными

<?php
/* Более сложный пример с переменными. */
class foo
{
public
$foo;
public
$bar;

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

$foo = new foo();
$name = 'Имярек';

echo <<<'EOT'
Меня зовут "$name". Я печатаю $foo->foo.
Теперь я печатаю {$foo->bar[1]}.
Это не должно вывести заглавную 'A': \x41
EOT;
?>

Результат выполнения данного примера:

Меня зовут "$name". Я печатаю $foo->foo.
Теперь я печатаю {$foo->bar[1]}.
Это не должно вывести заглавную 'A': \x41

Пример #14 Пример использования статичных данных

<?php
class foo {
public
$bar = <<<'EOT'
bar
EOT;
}
?>

Обработка переменных

Если строка указывается в двойных кавычках, либо при помощи heredoc, переменные внутри неё обрабатываются.

Существует два типа синтаксиса: простой и сложный. Простой синтаксис более лёгок и удобен. Он даёт возможность обработки переменной, значения массива (array) или свойства объекта (object) с минимумом усилий.

Сложный синтаксис может быть определён по фигурным скобкам, окружающим выражение.

Простой синтаксис

Если интерпретатор встречает знак доллара ($), он захватывает так много символов, сколько возможно, чтобы сформировать правильное имя переменной. Если вы хотите точно определить конец имени, заключайте имя переменной в фигурные скобки.

<?php
$juice
= "apple";

echo
"He drank some $juice juice.".PHP_EOL;

// Некорректно. 's' - верный символ для имени переменной, но переменная имеет имя $juice.
echo "He drank some juice made of $juices.";

// Корректно. Строго указан конец имени переменной с помощью скобок:
echo "He drank some juice made of ${juice}s.";
?>

Результат выполнения данного примера:

He drank some apple juice.
He drank some juice made of .
He drank some juice made of apples.

Аналогично могут быть обработаны элемент массива (array) или свойство объекта (object). В индексах массива закрывающая квадратная скобка (]) обозначает конец определения индекса. Для свойств объекта применяются те же правила, что и для простых переменных.

Пример #15 Пример простого синтаксиса

<?php
$juices
= array("apple", "orange", "koolaid1" => "purple");

echo
"He drank some $juices[0] juice.".PHP_EOL;
echo
"He drank some $juices[1] juice.".PHP_EOL;
echo
"He drank some $juices[koolaid1] juice.".PHP_EOL;

class
people {
public
$john = "John Smith";
public
$jane = "Jane Smith";
public
$robert = "Robert Paulsen";

public
$smith = "Smith";
}

$people = new people();

echo
"$people->john drank some $juices[0] juice.".PHP_EOL;
echo
"$people->john then said hello to $people->jane.".PHP_EOL;
echo
"$people->john's wife greeted $people->robert.".PHP_EOL;
echo
"$people->robert greeted the two $people->smiths."; // Не сработает
?>

Результат выполнения данного примера:

He drank some apple juice.
He drank some orange juice.
He drank some purple juice.
John Smith drank some apple juice.
John Smith then said hello to Jane Smith.
John Smith's wife greeted Robert Paulsen.
Robert Paulsen greeted the two .

В PHP 7.1.0 добавлена поддержка отрицательных числовых индексов.

Пример #16 Отрицательные числовые индексы

<?php
$string
= 'string';
echo
"Символ с индексом -2 равен $string[-2].", PHP_EOL;
$string[-3] = 'o';
echo
"Изменение символа на позиции -3 на 'o' даёт следующую строку: $string.", PHP_EOL;
?>

Результат выполнения данного примера:

Символ с индексом -2 равен n.
Изменение символа на позиции -3 на 'o' даёт следующую строку: strong

Для чего-либо более сложного, используйте сложный синтаксис.

Сложный (фигурный) синтаксис

Он называется сложным не потому, что труден в понимании, а потому что позволяет использовать сложные выражения.

Любая скалярная переменная, элемент массива или свойство объекта, отображаемое в строку, может быть представлена в строке этим синтаксисом. Выражение записывается так же, как и вне строки, а затем заключается в { и }. Поскольку { не может быть экранирован, этот синтаксис будет распознаваться только когда $ следует непосредственно за {. Используйте {\$, чтобы напечатать {$. Несколько поясняющих примеров:

<?php
// Показываем все ошибки
error_reporting(E_ALL);

$great = 'здорово';

// Не работает, выводит: Это { здорово}
echo "Это { $great}";

// Работает, выводит: Это здорово
echo "Это {$great}";

// Работает
echo "Этот квадрат шириной {$square->width}00 сантиметров.";

// Работает, ключи, заключённые в кавычки, работают только с синтаксисом фигурных скобок
echo "Это работает: {$arr['key']}";

// Работает
echo "Это работает: {$arr[4][3]}";

// Это неверно по той же причине, что и $foo[bar] вне
// строки. Другими словами, это по-прежнему будет работать,
// но поскольку PHP сначала ищет константу foo, это вызовет
// ошибку уровня E_NOTICE (неопределённая константа).
echo "Это неправильно: {$arr[foo][3]}";

// Работает. При использовании многомерных массивов внутри
// строк всегда используйте фигурные скобки
echo "Это работает: {$arr['foo'][3]}";

// Работает.
echo "Это работает: " . $arr['foo'][3];

echo
"Это тоже работает: {$obj->values[3]->name}";

echo
"Это значение переменной по имени $name: {${$name}}";

echo
"Это значение переменной по имени, которое возвращает функция getName(): {${getName()}}";

echo
"Это значение переменной по имени, которое возвращает \$object->getName(): {${$object->getName()}}";

// Не работает, выводит: Это то, что возвращает getName(): {getName()}
echo "Это то, что возвращает getName(): {getName()}";

// Не работает, выводит: C:\folder\{fantastic}.txt
echo "C:\folder\{$great}.txt"

// Работает, выводит: C:\folder\fantastic.txt
echo "C:\\folder\\{$great}.txt"
?>

С помощью этого синтаксиса также возможен доступ к свойствам объекта внутри строк.

<?php
class foo {
var
$bar = 'I am bar.';
}

$foo = new foo();
$bar = 'bar';
$baz = array('foo', 'bar', 'baz', 'quux');
echo
"{$foo->$bar}\n";
echo
"{$foo->{$baz[1]}}\n";
?>

Результат выполнения данного примера:

I am bar.
I am bar.

Замечание:

Значение, к которому осуществляется доступ из функций, вызовов методов, статических переменных класса и констант класса внутри {$}, будет интерпретироваться как имя переменной в области, в которой определена строка. Использование одинарных фигурных скобок ({}) не будет работать для доступа к значениям функций, методов, констант классов или статических переменных класса.

<?php
// Показываем все ошибки
error_reporting(E_ALL);

class
beers {
const
softdrink = 'rootbeer';
public static
$ale = 'ipa';
}

$rootbeer = 'A & W';
$ipa = 'Alexander Keith\'s';

// Это работает, выводит: Я бы хотел A & W
echo "Я бы хотел {${beers::softdrink}}\n";

// Это тоже работает, выводит: Я бы хотел Alexander Keith's
echo "Я бы хотел {${beers::$ale}}\n";
?>

Доступ к символу в строке и его изменение

Символы в строках можно использовать и модифицировать, определив их смещение относительно начала строки, начиная с нуля, в квадратных скобках после строки, например, $str[42]. Думайте о строке для этой цели, как о массиве символов. Если нужно получить или заменить более 1 символа, можно использовать функции substr() и substr_replace().

Замечание: Начиная с PHP 7.1.0, поддерживаются отрицательные значения смещения. Они задают смещение с конца строки. Ранее отрицательные смещение вызывали ошибку уровня E_NOTICE при чтении (возвращая пустую строку) либо E_WARNING при записи (оставляя строку без изменений).

Замечание: До PHP 8.0.0 для доступа к символу в строке (string) также можно было использовать фигурные скобки, например, $str{42}, для той же цели. Синтаксис фигурных скобок устарел в PHP 7.4.0 и больше не поддерживается в PHP 8.0.0.

Внимание

Попытка записи в смещение за границами строки дополнит строку пробелами до этого смещения. Нецелые типы будет преобразованы в целые. Неверный тип смещения вызовет ошибку уровня E_WARNING. Используется только первый символ присваемой строки. Начиная с PHP 7.1.0, присвоение пустой строки вызовет фатальную ошибку. Ранее в таком случае присваивался нулевой байт (NULL).

Внимание

Строки в PHP внутренне представляют из себя массивы байт. Как результат, доступ или изменение строки по смещению небезопасно с точки зрения многобайтной кодировки, и должно выполняться только со строками в однобайтных кодировках, таких как, например, ISO-8859-1.

Замечание: Начиная с PHP 7.1.0, использование пустого индекса вызывает фатальную ошибку, ранее в подобном случае строка преобразовывалась в массив без предупреждения.

Пример #17 Несколько примеров строк

<?php
// Получение первого символа строки
$str = 'This is a test.';
$first = $str[0];

// Получение третьего символа строки
$third = $str[2];

// Получение последнего символа строки
$str = 'This is still a test.';
$last = $str[strlen($str)-1];

// Изменение последнего символа строки
$str = 'Look at the sea';
$str[strlen($str)-1] = 'e';

?>

Смещение в строке должно задаваться либо целым числом, либо строкой, содержащей цифры, иначе будет выдаваться предупреждение.

Пример #18 Пример недопустимого смещения строки

<?php
$str
= 'abc';

var_dump($str['1']);
var_dump(isset($str['1']));

var_dump($str['1.0']);
var_dump(isset($str['1.0']));

var_dump($str['x']);
var_dump(isset($str['x']));

var_dump($str['1x']);
var_dump(isset($str['1x']));
?>

Результат выполнения данного примера:

string(1) "b"
bool(true)

Warning: Illegal string offset '1.0' in /tmp/t.php on line 7
string(1) "b"
bool(false)

Warning: Illegal string offset 'x' in /tmp/t.php on line 9
string(1) "a"
bool(false)
string(1) "b"
bool(false)

Замечание:

Попытка доступа к переменным других типов (исключая массивы или объекты, реализующие определённые интерфейсы) с помощью [] или {} молча вернёт null.

Замечание:

Доступ к символам в строковых литералах можно получить с помощью синтаксиса [] или {}.

Замечание:

Доступ к символам в строковых литералах с использованием синтаксиса {} объявлен устаревшим в PHP 7.4. Функционал удалён в PHP 8.0.

Полезные функции и операторы

Строки могут быть объединены при помощи оператора '.' (точка). Обратите внимание, оператор сложения '+' здесь не работает. Дополнительную информацию смотрите в разделе Строковые операторы.

Для модификации строк существует множество полезных функций.

Основные функции описаны в разделе строковых функций, а для расширенного поиска и замены - функции Perl-совместимых регулярных выражений.

Также существуют функции для работы с URL, и функции шифрования/дешифрования строк (Sodium и Hash).

Наконец, смотрите также функции символьных типов.

Преобразование в строку

Значение может быть преобразовано в строку с помощью приведения (string), либо функции strval(). В выражениях, где необходима строка, преобразование происходит автоматически. Это происходит, когда вы используете функции echo или print, либо когда значение переменной сравнивается со строкой. Прочтение разделов руководства Типы и Манипуляции с типами сделает следующее более понятным. Смотрите также settype().

Значение bool true преобразуется в строку "1", а значение false преобразуется в "" (пустую строку). Это позволяет преобразовывать значения в обе стороны - из булева типа в строковый и наоборот.

Целое (int) или число с плавающей точкой (float) преобразуется в строку, представленную числом, состоящим из его цифр (включая показатель степени для чисел с плавающей точкой). Числа с плавающей точкой могут быть преобразованы с помощью экспоненциального представления (4.1E+6).

Замечание:

Начиная с PHP 8.0.0, символом десятичной точки всегда является точка ("."). До PHP 8.0.0 символ десятичной точки определялся в локали скрипта (категория LC_NUMERIC). Смотрите функцию setlocale()

Массивы всегда преобразуются в строку "Array", так что вы не можете отобразить содержимое массива (array), используя echo или print, чтобы узнать, что он содержит. Чтобы просмотреть отдельный элемент, используйте что-нибудь вроде echo $arr['foo']. Смотрите ниже советы о том, как отобразить/просмотреть все содержимое.

Для преобразования переменной типа "Object" в тип string используется магический метод __toString.

Тип ресурс (resource) всегда преобразуется в строку (string) вида "Resource id #1", где 1 является номером ресурса привязанного к resource во время выполнения. И хотя не стоит точно полагаться на эту строку, которая может быть изменена в будущем, она всегда будет уникальной для текущего запуска скрипта (т.е. веб-запроса или CLI-процесса) и не может использоваться повторно для другого ресурса. Если вы хотите получить тип ресурса, используйте get_resource_type().

Значение null всегда преобразуется в пустую строку.

Как вы могли видеть выше, прямое преобразование в строку массивов, объектов или ресурсов не даёт никакой полезной информации о самих значениях, кроме их типов. Более подходящий способ вывода значений для отладки - использовать функции print_r() и var_dump().

Большинство значений в PHP может быть преобразовано в строку для постоянного хранения. Этот метод называется сериализацией и может быть выполнен при помощи функции serialize().

Подробности реализации строкового типа

Строковый тип (string) в PHP реализован в виде массива байт и целого числа, содержащего длину буфера. Он не содержит никакой информации о способе преобразования этих байт в символы, предоставляя эту задачу программисту. Нет никаких ограничений на содержимое строки, например, байт со значением 0 ("NUL"-байт) может располагаться где угодно (однако, стоит учитывать, что некоторые функции, как сказано в этом руководстве, не являются "бинарно-безопасными", т.е. они могут передавать строки библиотекам, которые игнорируют данные после NUL-байта).

Данная природа строкового типа объясняет почему в PHP нет отдельного типа "byte" - строки играют эту роль. Функции, возвращающие нетекстовые данные - например, произвольный поток данных, считываемый из сетевого сокета - тем не менее возвращают строки.

Принимая во внимание тот факт, что PHP не диктует определённую кодировку для строк, можно задать вопрос, как в таком случае кодируются строковые литералы. Например, строка "á" эквивалентна "\xE1" (ISO-8859-1), "\xC3\xA1" (UTF-8, форма нормализации C), "\x61\xCC\x81" (UTF-8, форма нормализации D) или какому-либо другому возможному представлению? Ответом является следующее: строка будет закодирована тем образом, которым она записана в файле скрипта. Таким образом, если скрипт записан в кодировке ISO-8859-1, то и строка будет закодирована в ISO-8859-1 и т.д. Однако, это правило не применяется при включённом режиме Zend Multibyte: в этом случае скрипт может быть записан в любой кодировке (которая указывается ясно или определяется автоматически), а затем конвертируются в определённую внутреннюю кодировку, которая и будет впоследствии использована для строковых литералов. Учтите, что на кодировку скрипта (или на внутреннюю кодировку, если включён режим Zend Multibyte) накладываются некоторые ограничения: практически всегда данная кодировка должна быть надмножеством ASCII, например, UTF-8 или ISO-8859-1. Учтите также, что кодировки, зависящие от состояния, где одни и те же значения байт могут быть использованы в начальном и не начальном состоянии сдвига, могут вызвать проблемы.

Разумеется, чтобы приносить пользу, строковые функции должны сделать некоторые предположения о кодировке строки. К несчастью, среди PHP-функций довольно большое разнообразие подходов к этому вопросу:

  • Некоторые функции предполагают, что строка закодирована в какой-либо однобайтовой кодировке, однако, для корректной работы им не требуется интерпретировать байты как определённые символы. Под эту категорию попадают, например, substr(), strpos(), strlen() и strcmp(). Другой способ мышления об этих функциях представляет собой оперирование буферами памяти, т.е. они работают непосредственно с байтами и их смещениями.
  • Другие функции ожидают передачу кодировку в виде параметра, возможно, предполагая некоторую кодировку по умолчанию, если параметр с кодировкой не был указан. Такой функцией является htmlentities() и большинство функций из модуля mbstring.
  • Другие функции используют текущие установки локали (смотрите setlocale()), но оперируют побайтово.
  • Наконец, есть функции, подразумевающие, что строка использует определённую кодировку, обычно UTF-8. Сюда попадают большинство функций из модулей intl и PCRE (в последнем случае, только при указании модификатора u).

В конечном счёте, написание корректных программ, работающих с Unicode, означает осторожное избегание функций, которые не работают с Unicode и, скорее всего, испортят данные, и использование вместо них корректных функций, обычно из модулей intl и mbstring. Однако, использование функций, способных работать с Unicode, является самым началом. Вне зависимости от тех функций, которые предоставляет язык, необходимо знать спецификацию самого Unicode. Например, если программа предполагает существование в языке только строчных и заглавных букв, то она делает большую ошибку.



Числовые строки

В PHP, строка (string) считается числовой, если её можно интерпретировать как целое (int) число или как число с плавающей точкой (float).

Формально с PHP 8.0.0:

WHITESPACES      \s*
LNUM             [0-9]+
DNUM             ([0-9]*)[\.]{LNUM}) | ({LNUM}[\.][0-9]*)
EXPONENT_DNUM    (({LNUM} | {DNUM}) [eE][+-]? {LNUM})
INT_NUM_STRING   {WHITESPACES} [+-]? {LNUM} {WHITESPACES}
FLOAT_NUM_STRING {WHITESPACES} [+-]? ({DNUM} | {EXPONENT_DNUM}) {WHITESPACES}
NUM_STRING       ({INT_NUM_STRING} | {FLOAT_NUM_STRING})

В PHP также присутствует концепция префиксной числовой строки. Это строка, которая начинается как числовая и продолжается любыми другими символами.

Замечание:

Любая строка, содержащая букву E (без учёта регистра), ограниченную цифрами, будет восприниматься как число, выраженное в научной нотации. Это может привести к неожиданным результатам.

<?php
var_dump
("0D1" == "000"); // false, "0D1" не является научной нотацией
var_dump("0E1" == "000"); // true, "0E1" - это 0 * (10 ^ 1) или 0
var_dump("2E1" == "020"); // true, "2E1" - это 2 * (10 ^ 1) или 20
?>

Строки, используемые в числовых контекстах

Когда строку необходимо использовать в качестве числа (например арифметические операции, декларация целочисленного типа, и т.д.), используется следующий алгоритм действий:

  1. Если строка числовая, представляет целое число и не превышает максимально допустимого значения для типа int (определённого в PHP_INT_MAX), то она приводится к типу int. Иначе она приводится к типу float.
  2. Если в заданном контексте дозволительно использовать префиксную числовую строку, то, если начало строки представляет целое число и не превышает максимально допустимого значения для типа int (определённого в PHP_INT_MAX), то она приводится к типу int. Иначе она приводится к типу float. Также, в этом случае, выдаётся ошибка уровня E_WARNING.
  3. Если строка не числовая - выбрасывается исключение TypeError.

Поведение до PHP 8.0.0

До PHP 8.0.0, строка считалась числовой только в случае, если она начиналась с пробельных символов. Если она завершалась пробельными символами - она считалась префиксной числовой.

До PHP 8.0.0, когда строку необходимо использовать как число, использовался тот же алгоритм, что и описан выше, но с некоторыми отличиями:

  • Использование префиксной числовой строки вызывало ошибку уровня E_NOTICE, а не E_WARNING.
  • Если строка не являлась числовой, вызывалась ошибка уровня E_WARNING, а сама строка приводилась к числу 0.
До PHP 7.1.0 не вызывалась ошибка уровня ни E_NOTICE, ни E_WARNING.

<?php
$foo
= 1 + "10.5"; // $foo считается за число с плавающей точкой (11.5)
$foo = 1 + "-1.3e3"; // $foo считается за число с плавающей точкой (-1299)
$foo = 1 + "bob-1.3e3"; // TypeError начиная с PHP 8.0.0. В более ранних версиях $foo считалось за целое число (1)
$foo = 1 + "bob3"; // TypeError начиная с PHP 8.0.0, В более ранних версиях $foo считалось за целое число (1)
$foo = 1 + "10 Small Pigs"; // $foo - целое (11). В PHP 8.0.0 создаётся ошибка уровня E_WARNING, а в более ранних версиях уровня E_NOTICE
$foo = 4 + "10.2 Little Piggies"; // $foo - число с плавающей точкой (14.2). В PHP 8.0.0 создаётся ошибка уровня E_WARNING, а в более ранних версиях уровня E_NOTICE
$foo = "10.0 pigs " + 1; // $foo - число с плавающей точкой (11). В PHP 8.0.0 создаётся ошибка уровня E_WARNING, а в более ранних версиях уровня E_NOTICE
$foo = "10.0 pigs " + 1.0; // $foo - число с плавающей точкой (11). В PHP 8.0.0 создаётся ошибка уровня E_WARNING, а в более ранних версиях уровня E_NOTICE
?>


Массивы

На самом деле массив в PHP - это упорядоченное отображение, которое устанавливает соответствие между значением и ключом. Этот тип оптимизирован в нескольких направлениях, поэтому вы можете использовать его как собственно массив, список (вектор), хеш-таблицу (являющуюся реализацией карты), словарь, коллекцию, стек, очередь и, возможно, что-то ещё. Так как значением массива может быть другой массив PHP, можно также создавать деревья и многомерные массивы.

Объяснение этих структур данных выходит за рамки данного справочного руководства, но вы найдёте как минимум один пример по каждой из них. За дополнительной информацией вы можете обратиться к соответствующей литературе по этой обширной теме.

Синтаксис

Определение при помощи array()

Массив (тип array) может быть создан языковой конструкцией array(). В качестве параметров она принимает любое количество разделённых запятыми пар key => value (ключ => значение).

array(
    key  => value,
    key2 => value2,
    key3 => value3,
    ...
)

Запятая после последнего элемента массива необязательна и может быть опущена. Обычно это делается для однострочных массивов, то есть array(1, 2) предпочтительней array(1, 2, ). Для многострочных массивов с другой стороны обычно используется завершающая запятая, так как позволяет легче добавлять новые элементы в конец массива.

Замечание:

Существует короткий синтаксис массива, который заменяет array() на [].

Пример #1 Простой массив

<?php
$array
= array(
"foo" => "bar",
"bar" => "foo",
);

// Использование синтаксиса короткого массива
$array = [
"foo" => "bar",
"bar" => "foo",
];
?>

key может быть либо типа int, либо типа string. value может быть любого типа.

Дополнительно с ключом key будут сделаны следующие преобразования:

  • Строки (string), содержащие целое число (int) (исключая случаи, когда число предваряется знаком +) будут преобразованы к типу int. Например, ключ со значением "8" будет в действительности сохранён со значением 8. С другой стороны, значение "08" не будет преобразовано, так как оно не является корректным десятичным целым.
  • Числа с плавающей точкой (float) также будут преобразованы к типу int, то есть дробная часть будет отброшена. Например, ключ со значением 8.7 будет в действительности сохранён со значением 8.
  • Тип bool также преобразовываются к типу int. Например, ключ со значением true будет сохранён со значением 1 и ключ со значением false будет сохранён со значением 0.
  • Тип null будет преобразован к пустой строке. Например, ключ со значением null будет в действительности сохранён со значением "".
  • Массивы (array) и объекты (object) не могут использоваться в качестве ключей. При подобном использовании будет генерироваться предупреждение: Недопустимый тип смещения (Illegal offset type).

Если несколько элементов в объявлении массива используют одинаковый ключ, то только последний будет использоваться, а все другие будут перезаписаны.

Пример #2 Пример преобразования типов и перезаписи элементов

<?php
$array
= array(
1 => "a",
"1" => "b",
1.5 => "c",
true => "d",
);
var_dump($array);
?>

Результат выполнения данного примера:

array(1) {
  [1]=>
  string(1) "d"
}

Так как все ключи в вышеприведённом примере преобразуются к 1, значение будет перезаписано на каждый новый элемент и останется только последнее присвоенное значение "d".

Массивы в PHP могут содержать ключи типов int и string одновременно, так как PHP не делает различия между индексированными и ассоциативными массивами.

Пример #3 Смешанные ключи типов int и string

<?php
$array
= array(
"foo" => "bar",
"bar" => "foo",
100 => -100,
-
100 => 100,
);
var_dump($array);
?>

Результат выполнения данного примера:

array(4) {
  ["foo"]=>
  string(3) "bar"
  ["bar"]=>
  string(3) "foo"
  [100]=>
  int(-100)
  [-100]=>
  int(100)
}

Параметр key является необязательным. Если он не указан, PHP будет использовать предыдущее наибольшее значение ключа типа int, увеличенное на 1.

Пример #4 Индексированные массивы без ключа

<?php
$array
= array("foo", "bar", "hallo", "world");
var_dump($array);
?>

Результат выполнения данного примера:

array(4) {
  [0]=>
  string(3) "foo"
  [1]=>
  string(3) "bar"
  [2]=>
  string(5) "hallo"
  [3]=>
  string(5) "world"
}

Возможно указать ключ только для некоторых элементов и пропустить для других:

Пример #5 Ключи для некоторых элементов

<?php
$array
= array(
"a",
"b",
6 => "c",
"d",
);
var_dump($array);
?>

Результат выполнения данного примера:

array(4) {
  [0]=>
  string(1) "a"
  [1]=>
  string(1) "b"
  [6]=>
  string(1) "c"
  [7]=>
  string(1) "d"
}

Как вы видите последнее значение "d" было присвоено ключу 7. Это произошло потому, что самое большое значение ключа целого типа перед этим было 6.

Пример #6 Расширенный пример преобразования типов и перезаписи элементов

<?php
$array
= array(
1 => 'a',
'1' => 'b', // значение "b" перезапишет значение "a"
1.5 => 'c', // значение "c" перезапишет значение "b"
-1 => 'd',
'01' => 'e', // поскольку это не целочисленная строка, она НЕ перезапишет ключ для 1
'1.5' => 'f', // поскольку это не целочисленная строка, она НЕ перезапишет ключ для 1
true => 'g', // значение "g" перезапишет значение "c"
false => 'h',
'' => 'i',
null => 'j', // значение "j" перезапишет значение "i"
'k', // значение "k" присваивается ключу 2. Потому что самый большой целочисленный ключ до этого был 1
2 => 'l', // значение "l" перезапишет значение "k"
);

var_dump($array);
?>

Результат выполнения данного примера:

array(7) {
  [1]=>
  string(1) "g"
  [-1]=>
  string(1) "d"
  ["01"]=>
  string(1) "e"
  ["1.5"]=>
  string(1) "f"
  [0]=>
  string(1) "h"
  [""]=>
  string(1) "j"
  [2]=>
  string(1) "l"
}

Этот пример включает все вариации преобразования ключей и перезаписи элементов

Доступ к элементам массива с помощью квадратных скобок

Доступ к элементам массива может быть осуществлён с помощью синтаксиса array[key].

Пример #7 Доступ к элементам массива

<?php
$array
= array(
"foo" => "bar",
42 => 24,
"multi" => array(
"dimensional" => array(
"array" => "foo"
)
)
);

var_dump($array["foo"]);
var_dump($array[42]);
var_dump($array["multi"]["dimensional"]["array"]);
?>

Результат выполнения данного примера:

string(3) "bar"
int(24)
string(3) "foo"

Замечание:

До PHP 8.0.0 квадратные и фигурные скобки могли использоваться взаимозаменяемо для доступа к элементам массива (например, в примере выше $array[42] и $array{42} делали то же самое). Синтаксис фигурных скобок устарел в PHP 7.4.0 и больше не поддерживается в PHP 8.0.0.

Пример #8 Разыменование массива

<?php
function getArray() {
return array(
1, 2, 3);
}

$secondElement = getArray()[1];
?>

Замечание:

Попытка доступа к неопределённому ключу в массиве - это то же самое, что и попытка доступа к любой другой неопределённой переменной: будет сгенерирована ошибка уровня E_WARNING (ошибка уровня E_NOTICE до PHP 8.0.0), и результат будет null.

Замечание:

Попытка разыменовать не массив, а скалярное значение, не являющееся строкой (string), отдаст null, в то время как разыменовывание строки (string) трактует её как индексированный массив. При такой попытке до PHP 7.4.0 не выдаётся сообщение об ошибке. Начиная с PHP 7.4.0, выдаётся ошибка E_NOTICE; с PHP 8.0.0 выдаётся ошибка E_WARNING.

Создание/модификация с помощью синтаксиса квадратных скобок

Существующий массив может быть изменён путём явной установкой значений в нем.

Это выполняется присвоением значений массиву (array) с указанием в скобках ключа. Кроме того, ключ можно опустить, в результате получится пустая пара скобок ([]).

    $arr[key] = value;
    $arr[] = value;
    // key может быть int или string
    // value может быть любым значением любого типа

Если массив $arr ещё не существует или для него задано значение null или false, он будет создан. Таким образом, это ещё один способ определить массив array. Однако такой способ применять не рекомендуется, так как если переменная $arr уже содержит некоторое значение (например, значение типа string из переменной запроса), то это значение останется на месте и [] может на самом деле означать доступ к символу в строке. Лучше инициализировать переменную путём явного присваивания значения.

Замечание: Начиная с PHP 7.1.0, используя в оператор "пустой индекс" на строке, приведёт к фатальной ошибке. Ранее, в этом случае, строка молча преобразовывалась в массив.

Замечание: Начиная с PHP 8.1.0, создание нового массива с помощью значения false устарело. Создание нового массива из null и неопределённого значения по-прежнему разрешено.

Для изменения определённого значения просто присвойте новое значение элементу, используя его ключ. Если вы хотите удалить пару ключ/значение, вам необходимо использовать функцию unset().

<?php
$arr
= array(5 => 1, 12 => 2);

$arr[] = 56; // В этом месте скрипта это
// то же самое, что и $arr[13] = 56;

$arr["x"] = 42; // Это добавляет к массиву новый
// элемент с ключом "x"

unset($arr[5]); // Это удаляет элемент из массива

unset($arr); // Это удаляет массив полностью
?>

Замечание:

Как уже говорилось выше, если ключ не был указан, то будет взят максимальный из существующих целочисленных (int) индексов, и новым ключом будет это максимальное значение (в крайнем случае 0) плюс 1. Если целочисленных (int) индексов ещё нет, то ключом будет 0 (ноль).

Учтите, что максимальное целое значение ключа не обязательно существует в массиве в данный момент. Оно могло просто существовать в массиве какое-то время, с тех пор как он был переиндексирован в последний раз. Следующий пример это иллюстрирует:

<?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
)

Деструктуризация массива

Массивы могут быть деструктурированы с помощью языковых конструкций [] (начиная с PHP 7.1.0) или list(). Эти конструкции могут быть использованы для деструктуризации массива на отдельные переменные.

<?php
$source_array
= ['foo', 'bar', 'baz'];
[
$foo, $bar, $baz] = $source_array;
echo
$foo; // выведет "foo"
echo $bar; // выведет "bar"
echo $baz; // выведет "baz"
?>

Деструктуризация массива может быть использована в конструкции foreach для деструктуризации многомерного массива во время итерации по нему.

<?php
$source_array
= [
[
1, 'John'],
[
2, 'Jane'],
];
foreach (
$source_array as [$id, $name]) {
// логика работы с $id и $name
}
?>

Элементы массива будут игнорироваться, если переменная не указана. Деструктуризация массива всегда начинается с индекса 0.

<?php
$source_array
= ['foo', 'bar', 'baz'];

// Присваивание элементу с индексом 2 переменной $baz
[, , $baz] = $source_array;

echo
$baz; // выведет "baz"
?>

Начиная с PHP 7.1.0, ассоциативные массивы также могут быть деструктурированы. Это позволяет легче выбирать нужный элемент в массивах с числовым индексом, так как индекс может быть указан явно.

<?php
$source_array
= ['foo' => 1, 'bar' => 2, 'baz' => 3];

// Присваивание элементу с индексом 'baz' переменной $three
['baz' => $three] = $source_array;

echo
$three; // выведет 3

$source_array = ['foo', 'bar', 'baz'];

// Присваивание элементу с индексом 2 переменной $baz
[2 => $baz] = $source_array;

echo
$baz; // выведет "baz"
?>

Деструктуризация массива может быть использована для простой замены двух переменных местами.

<?php
$a
= 1;
$b = 2;
[
$b, $a] = [$a, $b];
echo
$a; // выведет 2
echo $b; // выведет 1
?>

Замечание:

Оператор ... не поддерживается в присваиваниях.

Замечание:

Попытка получить доступ к ключу массива, который не был определён, аналогична обращению к любой другой неопределённой переменной: будет выдано сообщение об ошибке уровня E_WARNING (ошибка уровня E_NOTICE до PHP 8.0.0), а результатом будет null.

Полезные функции

Для работы с массивами существует достаточное количество полезных функций. Смотрите раздел функции для работы с массивами.

Замечание:

Функция unset() позволяет удалять ключи массива. Обратите внимание, что массив НЕ будет переиндексирован. Если вы действительно хотите поведения в стиле "удалить и сдвинуть", можно переиндексировать массив используя array_values().

<?php
$a
= array(1 => 'один', 2 => 'два', 3 => 'три');
unset(
$a[2]);
/* даст массив, представленный так:
$a = array(1 => 'один', 3 => 'три');
а НЕ так:
$a = array(1 => 'один', 2 => 'три');
*/

$b = array_values($a);
// Теперь $b это array(0 => 'один', 1 => 'три')
?>

Управляющая конструкция foreach существует специально для массивов. Она предоставляет возможность легко пройтись по массиву.

Что можно и нельзя делать с массивами

Почему $foo[bar] неверно?

Всегда заключайте в кавычки строковый литерал в индексе ассоциативного массива. К примеру, пишите $foo['bar'], а не $foo[bar]. Но почему? Часто в старых скриптах можно встретить следующий синтаксис:

<?php
$foo
[bar] = 'враг';
echo
$foo[bar];
// и т.д.
?>

Это неверно, хотя и работает. Причина в том, что этот код содержит неопределённую константу (bar), а не строку ('bar' - обратите внимание на кавычки). Это работает, потому что PHP автоматически преобразует "голую строку" (не заключённую в кавычки строку, которая не соответствует ни одному из известных символов языка) в строку со значением этой "голой строки". Например, если константа с именем bar не определена, то PHP заменит bar на строку 'bar' и использует её.

Внимание

Резервный вариант для обработки неопределённой константы как пустой строки вызывает ошибку уровня E_NOTICE. Начиная с PHP 7.2.0 поведение объявлено устаревшим и вызывает ошибку уровня E_WARNING. Начиная с PHP 8.0.0, удалено и выбрасывает исключение Error.

Замечание: Это не означает, что нужно всегда заключать ключ в кавычки. Нет необходимости заключать в кавычки константы или переменные, поскольку это помешает 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
// Показываем все ошибки
error_reporting(E_ALL);

$arr = array('fruit' => 'apple', 'veggie' => 'carrot');

// Верно
print $arr['fruit']; // apple
print $arr['veggie']; // carrot

// Неверно. Это работает, но из-за неопределённой константы с
// именем fruit также вызывает ошибку PHP уровня E_NOTICE
//
// Notice: Use of undefined constant fruit - assumed 'fruit' in...
print $arr[fruit]; // apple

// Давайте определим константу, чтобы продемонстрировать, что
// происходит. Мы присвоим константе с именем fruit значение 'veggie'.
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 известны также и константы:

<?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 и т.д.

Так что же в этом плохого?

Когда-нибудь в будущем команда разработчиков PHP возможно пожелает добавить ещё одну константу или ключевое слово, либо константа из другого кода может вмешаться и тогда у вас могут возникнуть проблемы. Например, вы уже не можете использовать таким образом слова empty и default, поскольку они являются зарезервированными ключевыми словами.

Замечание: Повторим, внутри строки (string), заключённой в двойные кавычки, корректно не окружать индексы массива кавычками, поэтому "$foo[bar]" является верной записью. Более подробно почему - смотрите вышеприведённые примеры, а также раздел по обработке переменных в строках.

Преобразование в массив

Для любого из типов int, float, string, bool и resource, преобразование значения в массив даёт результатом массив с одним элементом (с индексом 0), являющимся скалярным значением, с которого вы начали. Другими словами, (array)$scalarValue - это точно то же самое, что и array($scalarValue).

Если вы преобразуете в массив объект (object), вы получите в качестве элементов массива свойства (переменные-члены) этого объекта. Ключами будут имена переменных-членов, с некоторыми примечательными исключениями: целочисленные свойства станут недоступны; к закрытым полям класса (private) спереди будет дописано имя класса; к защищённым полям класса (protected) спереди будет добавлен символ '*'. Эти добавленные значения с обоих сторон также имеют NUL байты. Неинициализированные типизированные свойства автоматически отбрасываются.

<?php
class A {
private
$B;
protected
$C;
public
$D;
function
__construct()
{
$this->{1} = null;
}
}
var_export((array) new A());
?>

Результат выполнения данного примера:

array (
  '' . "\0" . 'A' . "\0" . 'B' => NULL,
  '' . "\0" . '*' . "\0" . 'C' => NULL,
  'D' => NULL,
  1 => NULL,
)

Это может вызвать несколько неожиданное поведение:

<?php
class A {
private
$A; // Это станет '\0A\0A'
}
class
B extends A {
private
$A; // Это станет '\0B\0A'
public $AA; // Это станет 'AA'
}
var_dump((array) new B());
?>

Результат выполнения данного примера:

array(3) {
  ["BA"]=>
  NULL
  ["AA"]=>
  NULL
  ["AA"]=>
  NULL
}

Вышеприведённый код покажет 2 ключа с именем 'AA', хотя один из них на самом деле имеет имя '\0A\0A'.

Если вы преобразуете в массив значение null, вы получите пустой массив.

Сравнение

Массивы можно сравнивать при помощи функции array_diff() и операторов массивов.

Распаковка массива

Массив с префиксом ... будет распакован во время определения массива. Только массивы и объекты, которые реализуют интерфейс Traversable, могут быть распакованы. Распаковка массива с помощью ... доступна, начиная с PHP 7.4.0.

Массив можно распаковывать несколько раз и добавлять обычные элементы до или после оператора ...:

Пример #9 Простая распаковка массива

<?php
// Использование короткого синтаксиса массива.
// Также работает с синтаксисом array().
$arr1 = [1, 2, 3];
$arr2 = [...$arr1]; // [1, 2, 3]
$arr3 = [0, ...$arr1]; // [0, 1, 2, 3]
$arr4 = [...$arr1, ...$arr2, 111]; // [1, 2, 3, 1, 2, 3, 111]
$arr5 = [...$arr1, ...$arr1]; // [1, 2, 3, 1, 2, 3]
function getArr() {
return [
'a', 'b'];
}
$arr6 = [...getArr(), 'c' => 'd']; // ['a', 'b', 'c' => 'd']
?>

Распаковка массива с помощью оператора ... следует семантике функции array_merge(). То есть более поздние строковые ключи перезаписывают более ранние, а целочисленные ключи перенумеровываются:

Пример #10 Распаковка массива с дублирующим ключом

<?php
// строковый ключ
$arr1 = ["a" => 1];
$arr2 = ["a" => 2];
$arr3 = ["a" => 0, ...$arr1, ...$arr2];
var_dump($arr3); // ["a" => 2]
// целочисленный ключ
$arr4 = [1, 2, 3];
$arr5 = [4, 5, 6];
$arr6 = [...$arr4, ...$arr5];
var_dump($arr6); // [1, 2, 3, 4, 5, 6]
// Который [0 => 1, 1 => 2, 2 => 3, 3 => 4, 4 => 5, 5 => 6]
// где исходные целочисленные ключи не были сохранены.
?>

Замечание:

Ключи, которые не являются ни целыми числами, ни строками, вызывают ошибку TypeError. Такие ключи могут быть сгенерированы только объектом Traversable.

Замечание:

До PHP 8.1 распаковка массива со строковым ключом не поддерживалась:

<?php
$arr1
= [1, 2, 3];
$arr2 = ['a' => 4];
$arr3 = [...$arr1, ...$arr2];
// Ошибка: невозможно распаковать массив со строковыми ключами в example.php:5
$arr4 = [1, 2, 3];
$arr5 = [4, 5];
$arr6 = [...$arr4, ...$arr5]; // работает. [1, 2, 3, 4, 5]
?>

Примеры

Тип массив в PHP является очень гибким, вот несколько примеров:

<?php
// это
$a = array( 'color' => 'red',
'taste' => 'sweet',
'shape' => 'round',
'name' => 'apple',
4 // ключом будет 0
);

$b = array('a', 'b', 'c');

// . . .полностью соответствует
$a = array();
$a['color'] = 'red';
$a['taste'] = 'sweet';
$a['shape'] = 'round';
$a['name'] = 'apple';
$a[] = 4; // ключом будет 0

$b = array();
$b[] = 'a';
$b[] = 'b';
$b[] = 'c';

// после выполнения этого кода, $a будет массивом
// array('color' => 'red', 'taste' => 'sweet', 'shape' => 'round',
// 'name' => 'apple', 0 => 4), а $b будет
// array(0 => 'a', 1 => 'b', 2 => 'c'), или просто array('a', 'b', 'c').
?>

Пример #11 Использование 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();
?>

Пример #12 Коллекция

<?php
$colors
= array('red', 'blue', 'green', 'yellow');

foreach (
$colors as $color) {
echo
"Вам нравится $color?\n";
}

?>

Результат выполнения данного примера:

Вам нравится red?
Вам нравится blue?
Вам нравится green?
Вам нравится yellow?

Изменение значений массива напрямую возможно путём передачи их по ссылке.

Пример #13 Изменение элемента в цикле

<?php
foreach ($colors as &$color) {
$color = strtoupper($color);
}
unset(
$color); /* это нужно для того, чтобы последующие записи в
$color не меняли последний элемент массива */

print_r($colors);
?>

Результат выполнения данного примера:

Array
(
    [0] => RED
    [1] => BLUE
    [2] => GREEN
    [3] => YELLOW
)

Следующий пример создаёт массив, начинающийся с единицы.

Пример #14 Индекс, начинающийся с единицы

<?php
$firstquarter
= array(1 => 'Январь', 'Февраль', 'Март');
print_r($firstquarter);
?>

Результат выполнения данного примера:

Array
(
    [1] => 'Январь'
    [2] => 'Февраль'
    [3] => 'Март'
)

Пример #15 Заполнение массива

<?php
// заполняем массив всеми элементами из директории
$handle = opendir('.');
while (
false !== ($file = readdir($handle))) {
$files[] = $file;
}
closedir($handle);
?>

Массивы упорядочены. Вы можете изменять порядок элементов, используя различные функции сортировки. Для дополнительной информации смотрите раздел функции для работы с массивами. Вы можете подсчитать количество элементов в массиве с помощью функции count().

Пример #16 Сортировка массива

<?php
sort
($files);
print_r($files);
?>

Поскольку значение массива может быть чем угодно, им также может быть другой массив. Таким образом вы можете создавать рекурсивные и многомерные массивы.

Пример #17 Рекурсивные и многомерные массивы

<?php
$fruits
= array ( "fruits" => array ( "a" => "апельсин",
"b" => "банан",
"c" => "яблоко"
),
"numbers" => array ( 1,
2,
3,
4,
5,
6
),
"holes" => array ( "первая",
5 => "вторая",
"третья"
)
);

// Несколько примеров доступа к значениям предыдущего массива
echo $fruits["holes"][5]; // напечатает "вторая"
echo $fruits["fruits"]["a"]; // напечатает "апельсин"
unset($fruits["holes"][0]); // удалит "первая"

// Создаст новый многомерный массив
$juices["apple"]["green"] = "good";
?>

Обратите внимание, что при присваивании массива всегда происходит копирование значения. Чтобы скопировать массив по ссылке, вам нужно использовать оператор ссылки.

<?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
"Код foo.";
}
}

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

Полное рассмотрение производится в разделе Классы и Объекты.

Преобразование в объект

Если object преобразуется в object, объект не изменится. Если значение другого типа преобразуется в object, создаётся новый экземпляр встроенного класса stdClass. Если значение было null, новый экземпляр будет пустым. Массивы преобразуются в object с именами полей, названными согласно ключам массива и соответствующими им значениям. Обратите внимание, что в этом случае до PHP 7.2.0 числовые ключи не будут доступны, пока не проитерировать объект.

<?php
$obj
= (object) array('1' => 'foo');
var_dump(isset($obj->{'1'})); // выводит 'bool(true)', начиная с PHP 7.2.0; 'bool(false)' ранее
var_dump(key($obj)); // выводит 'string(1) "1"', начиная с PHP 7.2.0; 'int(1)' ранее
?>

При преобразовании любого другого значения, оно будет помещено в поле с именем scalar соответствующему типу.

<?php
$obj
= (object) 'привет';
echo
$obj->scalar; // выведет 'привет'
?>


Перечисления

(PHP 8 >= 8.1.0)

Основы перечислений

Перечисления - это ограничивающий слой над классами и константами классов, предназначенный для предоставления способа определения закрытого набора возможных значений для типа.

<?php
enum Suit
{
case
Hearts;
case
Diamonds;
case
Clubs;
case
Spades;
}

function
do_stuff(Suit $s)
{
// ...
}

do_stuff(Suit::Spades);
?>

Полное описание смотрите в главе о перечислениях.

Casting

Если перечисление (enum) преобразуется в объект (object), оно не изменяется. Если перечисление (enum) преобразуется в массив (array), то создаётся массив с одним ключом name (для простых перечислений) или массив с двумя ключами name и value (для типизированных перечислений). Все остальные приведения типов приведут к ошибке.



Ресурс

Resource - это специальная переменная, содержащая ссылку на внешний ресурс. Ресурсы создаются и используются специальными функциями. Полный перечень этих функций и соответствующих типов ресурсов (resource) смотрите в приложении.

Смотрите также описание функции get_resource_type().

Преобразование в ресурс

Поскольку тип resource содержит специальные указатели на открытые файлы, соединения с базой данных, области изображения и тому подобное, преобразование в этот тип не имеет смысла.

Освобождение ресурсов

Благодаря системе подсчёта ссылок, введённой в Zend Engine, определение отсутствия ссылок на ресурс происходит автоматически, после чего он освобождается сборщиком мусора. Поэтому очень редко требуется освобождать память вручную.

Замечание: Постоянные соединения с базами данных являются исключением из этого правила. Они не уничтожаются сборщиком мусора. Подробнее смотрите в разделе о постоянных соединениях.



Функции обратного вызова (callback-функции)

Callback-функции могут быть обозначены объявлением типа callable.

Некоторые функции, такие как call_user_func() или usort(), принимают определённые пользователем callback-функции в качестве параметра. Callback-функции могут быть как простыми функциями, так и методами объектов, включая статические методы классов.

Передача

В PHP функции передаются по имени в виде строки. Можно использовать любые встроенные, либо созданные пользователем функции, за исключением конструкций языка, таких как: array(), echo, empty(), eval(), exit(), isset(), list(), print или unset().

Метод созданного объекта (object) передаётся как массив, содержащий объект по индексу 0 и имя метода по индексу 1. Доступ к закрытым и защищённым методам разрешён изнутри класса.

Статические методы класса также могут быть вызваны без создания экземпляра объекта класса путём передачи имени класса вместо объекта в элементе массива с индексом 0 или выполнения 'ClassName::methodName'.

Помимо обычных пользовательских функций, в качестве callback-функции можно передавать анонимные функции и стрелочные функции.

Замечание:

Начиная с PHP 8.1.0, у Callback-функций как объектов первого класса та же семантика, что и у этого метода.

Как правило, любой объект, реализующий __invoke(), также может быть передан в параметр callback.

Пример #1 Пример callback-функции

<?php

// Пример callback-функции
function my_callback_function() {
echo
'Привет, мир!';
}

// Пример callback-метода
class MyClass {
static function
myCallbackMethod() {
echo
'Привет, мир!';
}
}

// Тип 1: Простой callback
call_user_func('my_callback_function');

// Тип 2: Вызов статического метода класса
call_user_func(array('MyClass', 'myCallbackMethod'));

// Тип 3: Вызов метода класса
$obj = new MyClass();
call_user_func(array($obj, 'myCallbackMethod'));

// Тип 4: Вызов статического метода класса
call_user_func('MyClass::myCallbackMethod');

// Тип 5: Вызов относительного статического метода
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, устарело, начиная с PHP 8.2.0

// Тип 6: Объекты, реализующие __invoke, могут быть использованы как callback
class C {
public function
__invoke($name) {
echo
'Привет ', $name, "\n";
}
}

$c = new C();
call_user_func($c, 'PHP!');
?>

Пример #2 Пример callback-функции с использованием замыкания

<?php
// Наше замыкание
$double = function($a) {
return
$a * 2;
};

// Диапазон чисел
$numbers = range(1, 5);

// Использование замыкания в качестве callback-функции
// для удвоения каждого элемента в нашем диапазоне
$new_numbers = array_map($double, $numbers);

print
implode(' ', $new_numbers);
?>

Результат выполнения данного примера:

2 4 6 8 10

Замечание:

Callback-функции, зарегистрированные такими функциями как call_user_func() и call_user_func_array(), не будут вызваны при наличии не пойманного исключения, брошенного в предыдущей callback-функции.



Mixed

Тип mixed принимает любое значение. Он эквивалентен объединённому типу object|resource|array|string|float|int|bool|null. Доступно, начиная с PHP 8.0.0.

mixed - это, говоря языком теории типов, высший тип. Это означает, что все остальные типы являются его подтипами.



Void

void - это объявление типа только для возвращаемого значения, указывающее на то, что функция не возвращает значение, но функция всё равно может завершиться. Поэтому он не может быть частью объявления объединённых типов. Доступно, начиная с PHP 7.1.0.

Замечание: Даже если тип возвращаемого значения функции void, она всё равно вернёт значение и это значение всегда будет null.



Never

never - это объявление типа только для возвращаемого значения, указывающий на то, что функция не завершается. Это означает, что она либо вызывает exit(), либо выбрасывает исключение, либо является бесконечным циклом. Поэтому он не может быть частью объявления объединённых типов. Доступно, начиная с PHP 8.1.0.

never - это, говоря языком теории типов, нижний тип. Это означает, что он является подтипом любого другого типа и может заменить любой другой тип возвращаемого значения при наследовании.



Относительные типы классов

Эти объявления типов можно использовать только внутри классов.

self

Значение должно быть instanceof того же класса, что и класс, в котором используется объявление типа.

parent

Значение должно быть instanceof родителем класса, в котором используется объявление типа.

static

static - это тип только для возвращаемого значения, который требует, чтобы возвращаемое значение было instanceof того же класса, что и класс, в котором вызывается метод. Доступен, начиная с PHP 8.0.0.



Литералы

Литералы - это типы, которые проверяют не только тип значения, но и само значение. PHP поддерживает два литерала: false, начиная с PHP 8.0.0 и true, начиная с PHP 8.2.0.

Внимание

До PHP 8.2.0 тип false можно было использовать только как часть объединённого типа.

Замечание: Невозможно определить пользовательские литералы. Вместо этого используйте перечисления.



Итерируемые

Iterable - это встроенный во время компиляции псевдотип для array|Traversable. С момента своего появления в PHP 7.1.0 и до PHP 8.2.0, тип iterable был встроенным псевдо-типом, который действовал как вышеупомянутый псевдотип и мог быть использован в качестве объявления типа. Тип iterable можно использовать в foreach и с конструкцией yield from внутри генератора.

Замечание:

Функции, объявляющие iterable в качестве типа возвращаемого значения, также могут быть генераторами.

Пример #1 Пример использования типа возвращаемого значения iterable

<?php

function gen(): iterable {
yield
1;
yield
2;
yield
3;
}

?>



Объявление типов

Объявления типов могут использоваться для аргументов функций, возвращаемых значений и, начиная с PHP 7.4.0, для свойств класса. Они используются во время исполнения для проверки, что значение имеет точно тот тип, который для них указан. В противном случае будет выброшено исключение TypeError.

Все типы, которые поддерживает PHP, за исключением ресурсов (resource), могут быть использованы в объявлении типов в пользовательском коде. На этой странице приведён журнал изменений доступности различных типов и документация по их использованию в объявлениях типов.

Замечание:

Когда класс реализует метод интерфейса или повторно реализует метод, который уже был определён родительским классом, он должен быть совместим с вышеупомянутым определением. Метод является совместимым, если он следует правилам вариантности.

Список изменений

Версия Описание
8.2.0 Добавлена поддержка типов DNF.
8.2.0 Добавлена поддержка типа true.
8.2.0 Типы null и false теперь можно использовать автономно.
8.1.0 Добавлена поддержка пересечений типов.
8.1.0 Возврат по ссылке из функции с типом возвращаемого значения void устарел.
8.1.0 Добавлена поддержка типа возвращаемого значения never.
8.0.0 Добавлена поддержка типа возвращаемого значения mixed.
8.0.0 Добавлена поддержка типа возвращаемого значения static.
8.0.0 Добавлена поддержка объединения типов.
7.4.0 Добавлена поддержка типизации свойств классов.
7.2.0 Добавлена поддержка типа возвращаемого значения object.
7.1.0 Добавлена поддержка типа возвращаемого значения iterable.
7.1.0 Добавлена поддержка типа возвращаемого значения void.
7.1.0 Добавлена поддержка типа возвращаемого значения nullable.

Примечание по использованию основных типов

У основных типов прямолинейное поведение с некоторыми незначительными оговорками, которые описаны в этом разделе.

Скалярные типы

Внимание

Псевдонимы имён для скалярных типов (bool, int, float, string) не поддерживаются. Вместо этого они рассматриваются как имена классов или интерфейсов. К примеру, при использовании в качестве типа boolean, ожидается, что значение представляет собой instanceof класса или интерфейса boolean, а не значение типа bool:

<?php
function test(boolean $param) {}
test(true);
?>

Результат выполнения данного примера в PHP 8:

Warning: "boolean" will be interpreted as a class name. Did you mean "bool"? Write "\boolean" to suppress this warning in /in/9YrUX on line 2

Fatal error: Uncaught TypeError: test(): Argument #1 ($param) must be of type boolean, bool given, called in - on line 3 and defined in -:2
Stack trace:
#0 -(3): test(true)
#1 {main}
  thrown in - on line 2

void

Замечание:

Возврат по ссылке из функции void устарел начиная с PHP 8.1.0, поскольку такая функция противоречива. Ранее при её вызове выдавалась ошибка уровня E_NOTICE: Только ссылки на переменные должны возвращаться по ссылке.

<?php
function &test(): void {}
?>

Тип Callable

Этот тип не может использоваться в качестве объявления типа свойства класса.

Замечание: Невозможно указать сигнатуру функции.

Объявление типов в параметрах передачи по ссылкам

Если у параметра, передаваемого по ссылке, объявляется тип возвращаемого значения, тип переменной проверяется только при входе в функцию, в начале вызова, но не при возврате функции. Это значит, что функция может изменить тип ссылки на переменную.

Пример #1 Типизированные параметры, передаваемые по ссылке

<?php
function array_baz(array &$param)
{
$param = 1;
}
$var = [];
array_baz($var);
var_dump($var);
array_baz($var);
?>

Результатом выполнения данного примера будет что-то подобное:

int(1)

Fatal error: Uncaught TypeError: array_baz(): Argument #1 ($param) must be of type array, int given, called in - on line 9 and defined in -:2
Stack trace:
#0 -(9): array_baz(1)
#1 {main}
  thrown in - on line 2

Примечание по использованию составных типов

На объявления составных типов распространяется пара ограничений и во время компиляции будет выполняться проверка избыточности для предотвращения простых ошибок.

Предостережение

До PHP 8.2.0 и появления типов DNF было невозможно комбинировать пересечение типов с объединением типов.

Объединение типов

Внимание

Невозможно объединить два типа false и true с помощью объединения типов. Вместо этого используйте bool.

Предостережение

До PHP 8.2.0, поскольку false и null не могли использоваться как отдельные типы, объединение типов, состоящее только из этих типов, было недопустимо. К ним относятся следующие типы: false, false|null и ?false.

Синтаксический сахар типа Nullable

Объявление одного базового типа может быть помечено как nullable путём префиксации типа вопросительным знаком (?). Таким образом, ?T и T|null идентичны.

Замечание: Этот синтаксис поддерживается начиная с PHP 7.1.0 и предшествует поддержке объединения типов.

Замечание:

Также можно добиться nullable аргументов, указав null значением по умолчанию. Это не рекомендуется, поскольку если значение по умолчанию будет изменено в дочернем классе, возникнет нарушение совместимости типов, так как в объявление типа нужно будет добавить тип null.

Пример #2 Старый способ указания nullable аргументов

<?php
class C {}

function
f(C $c = null) {
var_dump($c);
}

f(new C);
f(null);
?>

Результат выполнения данного примера:

object(C)#1 (0) {
}
NULL

Дублирующие и избыточные типы

Чтобы отловить простые ошибки в объявлениях составных типов, избыточные типы, которые могут быть обнаружены без выполнения загрузки класса, приведут к ошибке времени компиляции. К ним относятся:

  • Каждый разрешённый тип имени может встречаться только один раз. Такие типы, как int|string|INT или Countable&Traversable&COUNTABLE приведут к ошибке.
  • Использование типа mixed приводит к ошибке.
  • Для объединения типов:
    • Если используется тип bool, то false или true не могут быть использованы дополнительно.
    • Если используется тип object, типы классов не могут быть использованы дополнительно.
    • Если используется тип iterable, то array и Traversable не могут быть использованы дополнительно.
  • Для пересечения типов:
    • Использование типа, который не является типом класса, приводит к ошибке.
    • Использование self, parent или static приведёт к ошибке.
  • Для DNF типов:
    • Если используется более общий тип, то более ограничительный тип является избыточным.
    • Использование двух одинаковых пересечений типов.

Замечание: Это не гарантирует, что тип является "минимальным", поскольку для этого пришлось бы загрузить все используемые типы классов.

Например, если A и B являются псевдонимами классов, то A|B остаётся корректным объединением типов, даже если его можно свести либо к A, либо к B. Аналогично, если класс B extends A {}, то A|B также является корректным объединением типов, даже если его можно свести к просто A.

<?php
function foo(): int|INT {} // Запрещено
function foo(): bool|false {} // Запрещено
function foo(): int&Traversable {} // Запрещено
function foo(): self&Traversable {} // Запрещено

use A as B;
function
foo(): A|B {} // Запрещено ("use" является частью разрешения имён)
function foo(): A&B {} // Запрещено ("use" является частью разрешения имён)

class_alias('X', 'Y');
function
foo(): X|Y {} // Разрешено (избыточность известна только во время выполнения)
function foo(): X&Y {} // Разрешено (избыточность известна только во время выполнения)
?>

Примеры

Пример #3 Пример объявления типа класса

<?php
class C {}
class
D extends C {}

// Не наследует C.
class E {}

function
f(C $c) {
echo
get_class($c)."\n";
}

f(new C);
f(new D);
f(new E);
?>

Результат выполнения данного примера в PHP 8:

C
D

Fatal error: Uncaught TypeError: f(): Argument #1 ($c) must be of type C, E given, called in /in/gLonb on line 14 and defined in /in/gLonb:8
Stack trace:
#0 -(14): f(Object(E))
#1 {main}
  thrown in - on line 8

Пример #4 Пример объявления типа интерфейса

<?php
interface I { public function f(); }
class
C implements I { public function f() {} }

// Не реализует I.
class E {}

function
f(I $i) {
echo
get_class($i)."\n";
}

f(new C);
f(new E);
?>

Результат выполнения данного примера в PHP 8:

C

Fatal error: Uncaught TypeError: f(): Argument #1 ($i) must be of type I, E given, called in - on line 13 and defined in -:8
Stack trace:
#0 -(13): f(Object(E))
#1 {main}
  thrown in - on line 8

Пример #5 Пример объявления типа возвращаемого значения

<?php
function sum($a, $b): float {
return
$a + $b;
}

// Обратите внимание, что будет возвращено значение float.
var_dump(sum(1, 2));
?>

Результат выполнения данного примера:

float(3)

Пример #6 Возвращение объекта

<?php
class C {}

function
getC(): C {
return new
C;
}

var_dump(getC());
?>

Результат выполнения данного примера:

object(C)#1 (0) {
}

Пример #7 Объявление аргумента с типом Nullable

<?php
class C {}

function
f(?C $c) {
var_dump($c);
}

f(new C);
f(null);
?>

Результат выполнения данного примера:

object(C)#1 (0) {
}
NULL

Пример #8 Объявление типа возвращаемого значения Nullable

<?php
function get_item(): ?string {
if (isset(
$_GET['item'])) {
return
$_GET['item'];
} else {
return
null;
}
}
?>

Пример #9 Объявление типа свойства класса

<?php
class User {
public static
string $foo = 'foo';

public
int $id;
public
string $username;

public function
__construct(int $id, string $username) {
$this->id = $id;
$this->username = $username;
}
}
?>

Строгая типизация

По умолчанию, PHP будет преобразовывать значения неправильного типа в ожидаемые. К примеру, если в функцию передать параметр типа int в аргумент, объявленный как string, то он преобразуется в string.

Можно включить режим строгой типизации на уровне файла. В этом режиме, тип значения должен строго соответствовать объявленному, иначе будет выброшено исключение TypeError. Единственным исключением из этого правила является передача значения типа int туда, где ожидается float.

Внимание

На вызовы из внутренних функций, действие strict_types не распространяется.

Для включения строгой типизации используется оператор declare с объявлением strict_types:

Замечание:

Строгая типизация применяется к вызовам функций, сделанным изнутри файла с включённой строгой типизацией, а не к функциям, объявленным в этом файле. Если из файла без включённой строгой типизации вызывается функция, которая была определена в файле со строгой типизацией, то будут использованы его предпочтения по типизации - т.е. правила строгой типизации будут проигнорированы и для значений будет применяться приведение типов.

Замечание:

Строгая типизация определяется только для объявлений скалярных типов.

Пример #10 Строгая типизация для значений аргументов

<?php
declare(strict_types=1);

function
sum(int $a, int $b) {
return
$a + $b;
}

var_dump(sum(1, 2));
var_dump(sum(1.5, 2.5));
?>

Результат выполнения данного примера в PHP 8:

int(3)

Fatal error: Uncaught TypeError: sum(): Argument #1 ($a) must be of type int, float given, called in - on line 9 and defined in -:4
Stack trace:
#0 -(9): sum(1.5, 2.5)
#1 {main}
  thrown in - on line 4

Пример #11 Приведение типов для значений аргументов

<?php
function sum(int $a, int $b) {
return
$a + $b;
}

var_dump(sum(1, 2));

// Переданные значения будут приведены к целым числам: обратите внимание на вывод ниже!
var_dump(sum(1.5, 2.5));
?>

Результат выполнения данного примера:

int(3)
int(3)

Пример #12 Строгая типизация для возвращаемых значений

<?php
declare(strict_types=1);

function
sum($a, $b): int {
return
$a + $b;
}

var_dump(sum(1, 2));
var_dump(sum(1, 2.5));
?>

Результат выполнения данного примера:

int(3)

Fatal error: Uncaught TypeError: sum(): Return value must be of type int, float returned in -:5
Stack trace:
#0 -(9): sum(1, 2.5)
#1 {main}
  thrown in - on line 5


Манипуляции с типами

PHP не требует явного определения типа при объявлении переменной. В этом случае тип переменной определяется значением, которое она хранит. То есть, если переменной $var присваивается значение типа строка (string), то $var изменит тип на строку (string). Если после этого переменной $var будет присвоено значение типа целое число (int), то она изменит тип на целое число (int).

В определённых контекстах PHP может попытаться автоматически преобразовать тип значения в другой. Существуют следующие различные контексты:

  • Числовой контекст
  • Строчный контекст
  • Логический контекст
  • Контекст целых чисел и строк
  • Сравнительный контекст
  • Контекст функций

Замечание: Когда значение нужно интерпретировать как другой тип, само значение не меняет тип.

Чтобы принудительно установить тип переменной, смотрите раздел Приведение типа. Чтобы изменить тип переменной, смотрите описание функции settype().

Числовой контекст

Контекст при использовании арифметического оператора.

В данном контексте, если один из операндов является числом с плавающей точкой (float) (или не интерпретируется как целое число (int)), оба операнда интерпретируются как число с плавающей точкой (float) и результатом будет число с плавающей точкой (float). В противном случае операнды будут интерпретированы как целое число (int) и результатом также будет целое число (int). Начиная с PHP 8.0.0, если один из операндов не может быть интерпретирован, выбрасывается ошибка TypeError.

Строчный контекст

Контекст при использовании функций echo, print, интерполяции строк или строкового оператора конкатенации.

В данном контексте значение будет интерпретироваться как строка (string). Если значение не может быть интерпретировано, выбрасывается ошибка TypeError. До версии PHP 7.4.0 выдавалась ошибка уровня E_RECOVERABLE_ERROR.

Логический контекст

Контекст при использовании условных операторов, тернарного оператора или логического оператора.

В данном контексте значение будет интерпретироваться как логическое значение (bool).

Контекст целых чисел и строк

Контекст при использовании побитовых операторов.

В данном контексте, если у всех операндов тип строка (string), результат также будет строкой (string). В противном случае операнды будут интерпретированы как целое число (int) и результат также будет целым числом (int). Начиная с PHP 8.0.0, если один из операндов не может быть интерпретирован, то будет выброшена ошибка TypeError.

Сравнительный контекст

Контекст при использовании оператора сравнения.

Преобразования типов, которые происходят в этом контексте, объясняются в таблице сравнения различных типов раздела Операторы сравнения.

Контекст функций

Контекст, когда значение передаётся типизированному параметру, свойству или возвращается из функции, в которой объявлен тип возвращаемого значения.

В этом контексте значение должно быть значением данного типа. Существуют два исключения, первое: если тип значения – целое число (int), а объявленный тип - число с плавающей точкой (float), то целое число преобразуется в число с плавающей точкой. Второй: если объявленный тип является скалярным типом, значение преобразуется в скалярный тип и режим строгой типизации активен (по умолчанию), значение может быть преобразовано в допустимое скалярное значение. Описание такого поведения смотрите ниже.

Внимание

Встроенные функции автоматически подставляют null к скалярным типам, это поведение УСТАРЕЛО в PHP 8.1.0.

Принудительная типизация с простым объявлением типов

  • Объявление типа bool: значение интерпретируется как логическое значение (bool).
  • Объявление типа int: значение интерпретируется как целое число (int), если преобразование хорошо определено. Например, строка является числовой строкой.
  • Объявление типа float: значение интерпретируется как число с плавающей точкой (float) если преобразование хорошо определено. Например, строка является числовой строкой.
  • Объявление типа string: значение интерпретируется как строка (string).

Принудительная типизация с объединением типов

При выключенном strict_types, объявления скалярных типов подвергаются ограниченному неявному приведению типов. Если точный тип значения не является частью объединения, то целевой тип выбирается в следующем порядке предпочтения:

  1. int
  2. float
  3. string
  4. bool
Если тип и существует в объединении и значение может быть приведено к этому типу в соответствии с существующей семантикой проверки типов PHP, то выбирается этот тип. В противном случае выбирается следующий тип.

Предостережение

В качестве исключения, если значение является строкой, а целое число (int) и число с плавающей точкой (float) являются частью объединения, предпочтительный тип определяется существующей семантикой числовой строки. Например, для "42" выбирается целое число (int), а для "42.0" выбирается число с плавающей точкой (float).

Замечание:

Типы, не входящие в приведённый выше список предпочтений, не являются объектами для неявного приведения. В частности, не происходит неявного приведения к типам null, false и true.

Пример #1 Пример принудительного включения типов в состав объединения

<?php
// int|string
42 --> 42 // точный тип
"42" --> "42" // точный тип
new ObjectWithToString --> "Результат __toString()"
// объект не совместим с int, переход к string
42.0 --> 42 // float совместимый с int
42.1 --> 42 // float совместимый с int
1e100 --> "1.0E+100" // float слишком велик для типа int, переход к string
INF --> "INF" // float слишком велик для типа int, переход к string
true --> 1 // bool совместимый с int
[] --> TypeError // массив не совместим с int или string

// int|float|bool
"45" --> 45 // int числовая строка
"45.0" --> 45.0 // float числовая строка

"45X" --> true // не числовая строка, переход к bool
"" --> false // не числовая строка, переход к bool
"X" --> true // не числовая строка, переход к bool
[] --> TypeError // массив не совместимый с int, float или bool
?>

Приведение типов

Приведение типа преобразует значение к выбранному типу, записывая тип в круглых скобках перед преобразуемым значением.

<?php
$foo
= 10; // $foo - это целое число
$bar = (bool) $foo; // $bar - это логическое значение
?>

Допускаются следующие приведения типов:

  • (int) - приведение типа к целому числу (int)
  • (bool) - приведение типа к логическому значению (bool)
  • (float) - приведение типа к числу с плавающей точкой (float)
  • (string) - приведение типа к строке (string)
  • (array) - приведение типа к массиву (array)
  • (object) - приведение типа к объекту (object)
  • (unset) - приведение типа к NULL

Замечание:

(integer) является псевдонимом приведения типа (int). (boolean) является псевдонимом приведения типа (bool). (binary) является псевдонимом приведения типа (string). (double) и (real) являются псевдонимами приведения типа (float). Эти приведения не используют каноническое имя типа и не рекомендуются.

Внимание

Псевдоним приведения типа (real) устарел, начиная с PHP 8.0.0.

Внимание

Приведение типа (unset) устарело, начиная с версии PHP 7.2.0. Обратите внимание, что приведение (unset) равносильно присвоению переменной или вызову значения NULL. Приведение (unset) удалено в PHP 8.0.0.

Предостережение

Приведение типа (binary) и префикс b существуют для прямой поддержки. В настоящее время (binary) и (string) идентичны, однако это может измениться и на это не следует полагаться.

Замечание:

Пробелы игнорируются в круглых скобках при приведении типа. Таким образом, следующие два приведения типов эквивалентны:

<?php
$foo
= (int) $bar;
$foo = ( int ) $bar;
?>

Приведение строк (string) и переменных к бинарным строкам (string):

<?php
$binary
= (binary) $string;
$binary = b"binary string";
?>

Замечание: Вместо приведения переменной к типу строка (string) можно также заключить переменную в двойные кавычки.

<?php
$foo
= 10; // $foo является целым числом
$str = "$foo"; // $str является строкой
$fst = (string) $foo; // $fst также является строкой

// Выводит, что "они одинаковые"
if ($fst === $str) {
echo
"они одинаковые";
}
?>

Может быть неочевидно, что именно произойдёт при преобразовании между определёнными типами. Для получения дополнительной информации смотрите эти разделы:

Замечание: Поскольку PHP поддерживает индексацию в строках (string) с помощью смещения, используя тот же синтаксис, что и индексация в массивах (array), следующий пример справедлив для всех версий PHP:

<?php
$a
= 'car'; // $a является строкой
$a[0] = 'b'; // $a по-прежнему является строкой
echo $a; // bar
?>
Дополнительную информацию смотрите в разделе Доступ к символу в строке и его изменение.




Переменные

Содержание


Основы

Переменные в PHP представлены знаком доллара с последующим именем переменной. Имя переменной чувствительно к регистру.

Имена переменных соответствуют тем же правилам, что и остальные наименования в PHP. Правильное имя переменной должно начинаться с буквы или символа подчёркивания и состоять из букв, цифр и символов подчёркивания в любом количестве. Это можно отобразить регулярным выражением: ^[a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*$

Замечание: Под буквами здесь подразумеваются символы a-z, A-Z и байты от 128 до 255 (0x80-0xff).

Замечание: $this - это специальная переменная, которой нельзя ничего присваивать. До PHP 7.1.0 было возможно косвенное присвоение (например, с использованием переменных переменных).

Подсказка

Смотрите также Руководство по именованию.

Для информации о функциях работы с переменными обращайтесь к разделу функций работы с переменными.

<?php
$var
= 'Боб';
$Var = 'Джо';
echo
"$var, $Var"; // выведет "Боб, Джо"

$4site = 'ещё нет'; // неверно; начинается с цифры
$_4site = 'ещё нет'; // верно; начинается с символа подчёркивания
$täyte = 'mansikka'; // верно; 'ä' это (Расширенный) ASCII 228.
?>

По умолчанию переменные всегда присваиваются по значению. То есть, когда вы присваиваете выражение переменной, все значение оригинального выражения копируется в эту переменную. Это означает, к примеру, что после того как одной переменной присвоено значение другой, изменение одной из них не влияет на другую. Дополнительную информацию об этом способе присвоения смотрите в разделе Выражения.

PHP также предлагает иной способ присвоения значений переменным: присвоение по ссылке. Это означает, что новая переменная просто ссылается (иначе говоря, "становится псевдонимом" или "указывает") на оригинальную переменную. Изменения в новой переменной отражаются на оригинале, и наоборот.

Для присвоения по ссылке, просто добавьте амперсанд (&) к началу имени присваиваемой (исходной) переменной. Например, следующий фрагмент кода дважды выводит 'Меня зовут Боб':

<?php
$foo
= 'Боб'; // Присваивает $foo значение 'Боб'
$bar = &$foo; // Ссылка на $foo через $bar.
$bar = "Меня зовут $bar"; // Изменение $bar...
echo $bar;
echo
$foo; // меняет и $foo.
?>

Важно отметить, что по ссылке могут быть присвоены только именованные переменные.

<?php
$foo
= 25;
$bar = &$foo; // Это верное присвоение.
$bar = &(24 * 7); // Неверно; ссылка на неименованное выражение.

function test()
{
return
25;
}

$bar = &test(); // Неверно.
?>

Хорошей практикой считается инициализировать переменные, хотя в PHP это и не является обязательным требованием. Неинициализированные переменные принимают значение по умолчанию в зависимости от их типа, который определяется из контекста их первого использования: булевы принимают значение false, целые числа и числа с плавающей точкой - ноль, строки (например, при использовании в echo) - пустую строку, а массивы становятся пустыми массивами.

Пример #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); выведет '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/ru/reserved.classes.php)
// Выведет: object(stdClass)#1 (1) { ["foo"]=> string(3) "bar" }
$unset_obj->foo = 'bar';
var_dump($unset_obj);
?>

Полагаться на значения по умолчанию неинициализированных переменных довольно проблематично при включении файла в другой файл, использующий переменную с таким же именем. В случае работы с неинициализированной переменной вызывается ошибка уровня E_WARNING (до PHP 8.0.0 выбрасывалась ошибка уровня E_NOTICE), за исключением случая добавления элементов в неинициализированный массив. Для обнаружения инициализации переменной может быть использована языковая конструкция isset().



Предопределённые переменные

Любому запускаемому скрипту PHP предоставляет большое количество предопределённых переменных. Однако многие из этих переменных не могут быть полностью задокументированы, поскольку они зависят от запускающего скрипт сервера, его версии и настроек, а также других факторов. Некоторые из этих переменных недоступны, когда PHP запущен из командной строки. Смотрите список зарезервированных предопределённых переменных для получения дополнительной информации.

PHP предоставляет дополнительный набор предопределённых массивов, содержащих переменные сервера (если они доступны), окружения и пользовательского ввода. Эти массивы являются особыми, поскольку они становятся глобальными автоматически - то есть, автоматически доступны в любой области видимости. По этой причине они также известны как 'автоглобальные' или 'суперглобальные' переменные. (В PHP нет механизма определяемых пользователем суперглобальных переменных.) Смотрите список суперглобальных переменных для получения дополнительной информации.

Замечание: Переменные переменных

Суперглобальные переменные не могут быть переменными переменных внутри функций или методов класса.

Если некоторые из переменных в variables_order не установлены, соответствующие им предопределённые массивы также останутся пустыми.



Область видимости переменной

Область видимости переменной - это контекст, в котором эта переменная определена. В большинстве случаев все переменные PHP имеют только одну область видимости. Эта единая область видимости охватывает также включаемые (include) и требуемые (require) файлы. Например:

<?php
$a
= 1;
include
'b.inc';
?>

Здесь переменная $a будет доступна внутри включённого скрипта b.inc. Однако определение (тело) пользовательской функции задаёт локальную область видимости данной функции. Любая используемая внутри функции переменная по умолчанию ограничена локальной областью видимости функции. Например:

<?php
$a
= 1; /* глобальная область видимости */

function test()
{
echo
$a; /* ссылка на переменную в локальной области видимости */
}

test();
?>

Этот скрипт не сгенерирует никакого вывода, поскольку выражение echo указывает на локальную версию переменной $a, а в пределах этой области видимости ей не было присвоено значение. Возможно вы заметили, что это немного отличается от языка C в том, что глобальные переменные в C автоматически доступны функциям, если только они не были перезаписаны локальным определением. Это может вызвать некоторые проблемы, поскольку люди могут нечаянно изменить глобальную переменную. В PHP, если глобальная переменная будет использоваться внутри функции, она должна быть объявлена глобальной внутри определения функции.

Ключевое слово global

Сначала пример использования global:

Пример #1 Использование global

<?php
$a
= 1;
$b = 2;

function
Sum()
{
global
$a, $b;

$b = $a + $b;
}

Sum();
echo
$b;
?>

Вышеприведённый скрипт выведет 3. После определения $a и $b внутри функции как global все ссылки на любую из этих переменных будут указывать на их глобальную версию. Не существует никаких ограничений на количество глобальных переменных, которые могут обрабатываться функцией.

Второй способ доступа к переменным глобальной области видимости - использование специального, определяемого PHP массива $GLOBALS. Предыдущий пример может быть переписан так:

Пример #2 Использование $GLOBALS вместо global

<?php
$a
= 1;
$b = 2;

function
Sum()
{
$GLOBALS['b'] = $GLOBALS['a'] + $GLOBALS['b'];
}

Sum();
echo
$b;
?>

$GLOBALS - это ассоциативный массив, ключом которого является имя, а значением - содержимое глобальной переменной. Обратите внимание, что $GLOBALS существует в любой области видимости, это объясняется тем, что $GLOBALS является суперглобальным. Ниже приведён пример, демонстрирующий возможности суперглобальных переменных:

Пример #3 Суперглобальные переменные и область видимости

<?php
function test_superglobal()
{
echo
$_POST['name'];
}
?>

Замечание:

Использование ключевого слова global вне функции не является ошибкой. Оно может быть использовано в файле, который включается внутри функции.

Использование статических (static) переменных

Другой важной особенностью области видимости переменной является статическая переменная. Статическая переменная существует только в локальной области видимости функции, но не теряет своего значения, когда выполнение программы выходит из этой области видимости. Рассмотрим следующий пример:

Пример #4 Демонстрация необходимости статических переменных

<?php
function test()
{
$a = 0;
echo
$a;
$a++;
}
?>

Эта функция довольно бесполезна, поскольку при каждом вызове она устанавливает $a в 0 и выводит 0. Инкремент переменной $a++ здесь не играет роли, так как при выходе из функции переменная $a исчезает. Чтобы написать полезную функцию подсчёта, которая не будет терять текущего значения счётчика, переменная $a объявляется как static:

Пример #5 Пример использования статических переменных

<?php
function test()
{
static
$a = 0;
echo
$a;
$a++;
}
?>

Теперь $a будет проинициализирована только при первом вызове функции, а каждый вызов функции test() будет выводить значение $a и инкрементировать его.

Статические переменные также дают возможность работать с рекурсивными функциями. Рекурсивной является функция, вызывающая саму себя. При написании рекурсивной функции нужно быть внимательным, поскольку есть вероятность сделать рекурсию бесконечной. Вы должны убедиться, что существует адекватный способ завершения рекурсии. Следующая простая функция рекурсивно считает до 10, используя для определения момента остановки статическую переменную $count:

Пример #6 Статические переменные и рекурсивные функции

<?php
function test()
{
static
$count = 0;

$count++;
echo
$count;
if (
$count < 10) {
test();
}
$count--;
}
?>

Статическим переменным можно присвоить значения, являющиеся результатом выражения, но нельзя использовать для этого функцию, так это вызовет ошибку разбора.

Пример #7 Объявление статических переменных

<?php
function foo() {
static
$int = 0; // верно
static $int = 1+2; // верно
static $int = sqrt(121); // неверно (поскольку это функция)

$int++;
echo
$int;
}
?>

Начиная с PHP 8.1.0, когда метод, использующий статические переменные, наследуется (но не переопределяется), унаследованный метод теперь будет использовать статические переменные совместно с родительским методом. Это означает, что статические переменные в методах теперь ведут себя так же, как статические свойства.

Пример #8 Использование статических переменных в унаследованных методах

<?php
class Foo {
public static function
counter() {
static
$counter = 0;
$counter++;
return
$counter;
}
}
class
Bar extends Foo {}
var_dump(Foo::counter()); // int(1)
var_dump(Foo::counter()); // int(2)
var_dump(Bar::counter()); // int(3), до PHP 8.1.0 int(1)
var_dump(Bar::counter()); // int(4), до PHP 8.1.0 int(2)
?>

Замечание:

Статические объявления вычисляются во время компиляции скрипта.

Ссылки с глобальными (global) и статическими (static) переменными

PHP использует модификаторы переменных static и global как ссылки. Например, реальная глобальная переменная, внедрённая в область видимости функции указанием ключевого слова global, в действительности создаёт ссылку на глобальную переменную. Это может привести к неожиданному поведению, как это показано в следующем примере:

<?php
function test_global_ref() {
global
$obj;
$new = new stdClass;
$obj = &$new;
}

function
test_global_noref() {
global
$obj;
$new = new stdClass;
$obj = $new;
}

test_global_ref();
var_dump($obj);
test_global_noref();
var_dump($obj);
?>

Результат выполнения данного примера:

NULL
object(stdClass)#1 (0) {
}

Аналогично ведёт себя и выражение static. Ссылки не хранятся статично:

<?php
function &get_instance_ref() {
static
$obj;

echo
'Статический объект: ';
var_dump($obj);
if (!isset(
$obj)) {
$new = new stdClass;
// Присвоить ссылку статической переменной
$obj = &$new;
}
if (!isset(
$obj->property)) {
$obj->property = 1;
} else {
$obj->property++;
}
return
$obj;
}

function &
get_instance_noref() {
static
$obj;

echo
'Статический объект: ';
var_dump($obj);
if (!isset(
$obj)) {
$new = new stdClass;
// Присвоить объект статической переменной
$obj = $new;
}
if (!isset(
$obj->property)) {
$obj->property = 1;
} else {
$obj->property++;
}
return
$obj;
}

$obj1 = get_instance_ref();
$still_obj1 = get_instance_ref();
echo
"\n";
$obj2 = get_instance_noref();
$still_obj2 = get_instance_noref();
?>

Результат выполнения данного примера:

Статический объект: NULL
Статический объект: NULL

Статический объект: NULL
Статический объект: object(stdClass)#3 (1) {
  ["property"]=>
  int(1)
}

Этот пример демонстрирует, что при присвоении ссылки статической переменной она не запоминается, когда вы вызываете функцию &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] для второго.

К свойствам класса также можно получить доступ динамически. Переменное имя свойства будет разрешено в том контексте, в котором произойдёт вызов к нему. Например, в случае выражения $foo->$bar, локальная область видимости будет просканирована на наличие переменной $bar, значение которой будет использовано в качестве имени свойства объекта $foo. Это также работает и в том случае, если $bar осуществляет доступ к элементу массива.

Фигурные скобки могут также использоваться, чтобы чётко разграничить имя свойства. Они наиболее полезны при получении доступа к значениям внутри свойства, которое содержит массив, когда имя свойства состоит из нескольких частей, либо когда имя свойства содержит символы, которые иначе не действительны (например, из функции json_decode() или из SimpleXML).

Пример #1 Пример переменного имени свойства

<?php
class foo {
var
$bar = 'I am bar.';
var
$arr = array('I am A.', 'I am B.', 'I am C.');
var
$r = 'I am r.';
}

$foo = new foo();
$bar = 'bar';
$baz = array('foo', 'bar', 'baz', 'quux');
echo
$foo->$bar . "\n";
echo
$foo->{$baz[1]} . "\n";

$start = 'b';
$end = 'ar';
echo
$foo->{$start . $end} . "\n";

$arr = 'arr';
echo
$foo->{$arr[1]} . "\n";

?>

Результат выполнения данного примера:


I am bar.
I am bar.
I am bar.
I am r.

Внимание

Обратите внимание, что переменные переменных не могут использоваться с суперглобальными массивами PHP. Переменная $this также является особой, на неё нельзя ссылаться динамически.



Переменные извне PHP

HTML-формы (GET и POST)

Когда происходит отправка данных формы PHP-скрипту, информация из этой формы автоматически становится доступной ему. Существует несколько способов получения этой информации, например:

Пример #1 Простая HTML-форма

<form action="foo.php" method="post">
    Имя:  <input type="text" name="username" /><br />
    Email: <input type="text" name="email" /><br />
    <input type="submit" name="submit" value="Отправь меня!" />
</form>

Есть только два способа получить доступ к данным из форм HTML. Доступные сейчас способы приведены ниже:

Пример #2 Доступ к данным из простой HTML-формы, отправленной через POST

<?php
echo $_POST['username'];
echo
$_REQUEST['username'];
?>

GET-форма используется аналогично, за исключением того, что вместо POST, вам нужно будет использовать соответствующую предопределённую переменную GET. GET относится также к QUERY_STRING (информация в URL после '?'). Так, например, http://www.example.com/test.php?id=3 содержит GET-данные, доступные как $_GET['id']. Смотрите также $_REQUEST.

Замечание:

Точки и пробелы в именах переменных преобразуется в знаки подчёркивания. Например, <input name="a.b" /> станет $_REQUEST["a_b"].

PHP также понимает массивы в контексте переменных формы (смотрите соответствующие ЧАВО). К примеру, вы можете сгруппировать связанные переменные вместе или использовать эту возможность для получения значений списка множественного выбора select. Например, давайте отправим форму самой себе, а после отправки отобразим данные:

Пример #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 />
Email: <input type="text" name="personal[email]" /><br />
Пиво: <br />
<select multiple name="beer[]">
<option value="warthog">Warthog</option>
<option value="guinness">Guinness</option>
<option value="stuttgarter">Stuttgarter Schwabenbräu</option>
</select><br />
<input type="submit" value="Отправь меня!" />
</form>

Замечание: Если внешнее имя переменной начинается с корректного синтаксиса массива, завершающие символы молча игнорируются. Например, <input name="foo[bar]baz"> станет $_REQUEST['foo']['bar'].

Имена переменных кнопки-изображения

При отправке формы вместо стандартной кнопки можно использовать изображение с помощью тега такого вида:

<input type="image" src="image.gif" name="sub" />

Когда пользователь щёлкнет где-нибудь на изображении, соответствующая форма будет передана на сервер с двумя дополнительными переменными - sub_x и sub_y. Они содержат координаты нажатия пользователя на изображение. Опытные программисты могут заметить, что на самом деле имена переменных, отправленных браузером, содержат точку, а не подчёркивание, но PHP автоматически преобразует точку в подчёркивание.

HTTP Cookies

PHP прозрачно поддерживает HTTP cookies как определено в » RFC 6265. Cookies - это механизм для хранения данных в удалённом браузере и, таким образом, отслеживания и идентификации вернувшихся пользователей. Вы можете установить cookies, используя функцию setcookie(). Cookies являются частью HTTP-заголовка, поэтому функция SetCookie должна вызываться до того, как браузеру будет отправлен какой бы то ни было вывод. Это то же ограничение, что и для функции header(). Данные, хранящиеся в cookie, доступны в соответствующих массивах данных cookie, таких как $_COOKIE и $_REQUEST. Подробности и примеры смотрите в справочной странице setcookie().

Замечание: Начиная с PHP 7.2.34, 7.3.23 и 7.4.11, соответственно, имена входящих cookie больше не декодируются из URL-закодированной строки из соображений безопасности.

Если вы хотите присвоить множество значений одной переменной cookie, вы можете присвоить их как массив. Например:

<?php
setcookie
("MyCookie[foo]", 'Testing 1', time()+3600);
setcookie("MyCookie[bar]", 'Testing 2', time()+3600);
?>

Это создаст две разные cookie, хотя в вашем скрипте MyCookie будет теперь одним массивом. Если вы хотите установить именно одну cookie со множеством значений, сначала рассмотрите возможность использования к значениям такие функции, как serialize() или explode().

Обратите внимание, что cookie заменит предыдущую cookie с тем же именем в вашем браузере, если только путь или домен не отличаются. Так, для приложения корзины покупок вы, возможно, захотите сохранить счётчик. То есть:

Пример #4 Пример использования setcookie()

<?php
if (isset($_COOKIE['count'])) {
$count = $_COOKIE['count'] + 1;
} else {
$count = 1;
}
setcookie('count', $count, time()+3600);
setcookie("Cart[$count]", $item, time()+3600);
?>

Точки в именах приходящих переменных

Как правило, PHP не меняет передаваемых скрипту имён переменных. Однако следует отметить, что точка не является корректным символом в имени переменной PHP. Поэтому рассмотрим такую запись:

<?php
$varname
.ext; /* неверное имя переменной */
?>
В данном случае интерпретатор видит переменную $varname, после которой идёт оператор конкатенации, а затем голая строка (то есть, не заключённая в кавычки строка, не соответствующая ни одному из ключевых или зарезервированных слов) 'ext'. Очевидно, что это не даст ожидаемого результата.

По этой причине важно отметить, что PHP будет автоматически заменять любые точки в именах, приходящих переменных на символы подчёркивания.

Определение типов переменных

Поскольку PHP определяет типы переменных и преобразует их (как правило) по мере необходимости, не всегда очевидно, какой тип имеет данная переменная в любой момент времени. PHP содержит несколько функций, позволяющих определить тип переменной, таких как: gettype(), is_array(), is_float(), is_int(), is_object() и is_string(). Смотрите также раздел Типы.

HTTP является текстовым протоколом, и большинство, если не всё, содержимое, которое приходит в суперглобальные массивы, например, $_POST и $_GET, останется в виде строк. PHP не будет преобразовывать значения в определённый тип. В приведённом ниже примере $_GET["var1"] будет содержать строку "null", а $_GET["var2"] - строку "123".

/index.php?var1=null&var2=123

Список изменений

Версия Описание
7.2.34, 7.3.23, 7.4.11 имена входящих cookie больше не декодируются из URL-закодированной строки из соображений безопасности.




Константы

Содержание

Константа - это идентификатор (имя) для простого значения. Как следует из названия, это значение не может измениться в ходе выполнения скрипта (кроме магических констант, которые на самом деле не являются константами). Константы чувствительны к регистру. По принятому соглашению, имена констант всегда пишутся в верхнем регистре.

Замечание:

До PHP 8.0.0 константы, определённые с помощью функции define(), могли быть нечувствительными к регистру.

Имя константы должно соответствовать тем же правилам именования, что и другие имена в PHP. Правильное имя начинается с буквы или символа подчёркивания, за которым следует любое количество букв, цифр и символов подчёркивания. Регулярное выражение для проверки правильности имени константы выглядит так: ^[a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*$

Возможно определить константы с помощью функции define() зарезервированными или даже некорректными именами, значения которых могут быть получены только с помощью constant(). Однако, делать это не рекомендуется.

Подсказка

Смотрите также Руководство по именованию.

Пример #1 Правильные и неправильные имена констант

<?php

// Правильные имена констант
define("FOO", "что-то");
define("FOO2", "что-то ещё");
define("FOO_BAR", "что-то большее");

// Неправильные имена констант
define("2FOO", "что-то");

// Это верное объявление, но лучше его не использовать:
// PHP однажды может зарегистрировать волшебную константу,
// которая нарушит работу скрипта
define("__FOO__", "что-то");

?>

Замечание: Понятие "буквы" здесь - это символы a-z, A-Z, и другие символы с ASCII-кодами от 128 до 255 (0x80-0xff).

Как и superglobals, константы доступны из любой области видимости. Константы можно использовать из любого места скрипта независимо от области видимости. Подробную информацию об областях видимости можно найти здесь.

Замечание: Начиная с PHP 7.1.0, константе класса можно объявлять видимость защищённая или закрытая, делая её доступной только в иерархической области видимости класса, в котором она определена.


Синтаксис

Константа может быть определена с помощью ключевого слова const или с помощью функции define(). В то время как define() позволяет задать константу через выражение, конструкция const ограничена как описано в следующем параграфе. После того, как константа определена, её значение не может быть изменено или аннулировано.

При использовании ключевого слова const допускаются только скалярные выражения (bool, int, float и string) и константы array, содержащие только скалярные выражения. Можно определить константы с типом resource, но не рекомендуется, так как это может привести к неожиданным результатам.

Получить значение константы можно, указав её имя. В отличие от переменных, вам не нужно предварять имя константы символом $. Также можно использовать функцию constant() для получения значения константы, если вы формируете имя константы динамически. Используйте функцию get_defined_constants() для получения списка всех определённых констант.

Замечание: Константы и (глобальные) переменные находятся в разных пространствах имён. Это означает, что, например, true и $TRUE в целом отличаются.

Если используется неопределённая константа, выбрасывается Error. До PHP 8.0.0 неопределённые константы интерпретировались как простое слово string, то есть (CONSTANT vs "CONSTANT"). Этот резервный вариант объявлен устаревшим с PHP 7.2.0, при этом будет сгенерирована ошибка уровня E_WARNING. До PHP 7.2.0 вместо этого выдавалась ошибка уровня E_NOTICE. Смотрите также главу руководства, которая разъясняет, почему $foo[bar] - это неправильно (если bar не является константой). Это не относится к (полностью) определённым константам, которые всегда будут выбрасывать Error, если они не определены.

Замечание: Чтобы проверить, установлена ли константа, используйте функцию defined().

Различия между константами и переменными:

  • У констант нет приставки в виде знака доллара ($);
  • Константы могут быть определены и доступны в любом месте без учёта области видимости;
  • Константы не могут быть переопределены или удалены после первоначального объявления; и
  • Константы могут иметь только скалярные значения или массивы.

Пример #1 Определение констант

<?php
define
("CONSTANT", "Здравствуй, мир.");
echo
CONSTANT; // выводит "Здравствуй, мир."
echo Constant; // Выбросит ошибку: Неопределённая константа "Constant"
// До PHP 8.0.0 выводит "Constant" и выдаёт предупреждение.
?>

Пример #2 Определение констант с помощью ключевого слова const

<?php
// Простое скалярное значение
const CONSTANT = 'Здравствуй, мир.';

echo
CONSTANT;

// Скалярное выражение
const ANOTHER_CONST = CONSTANT . ' Прощай, мир.';
echo
ANOTHER_CONST;

const
ANIMALS = array('dog', 'cat', 'bird');
echo
ANIMALS[1]; // выводит "cat"

// Массивы в константе
define('ANIMALS', array(
'dog',
'cat',
'bird'
));
echo
ANIMALS[1]; // выводит "cat"
?>

Замечание:

В отличие от определения констант с помощью функции define(), константы, объявленные с помощью ключевого слова const должны быть объявлены в самой верхней области видимости, потому что они определяются при компилировании скрипта. Это означает, что их нельзя объявлять внутри функций, циклов, выражений if и блоков try/ catch.

Смотрите также



Предопределённые константы

PHP предоставляет большой список предопределённых констант для каждого выполняемого скрипта. Многие из этих констант определяются различными модулями и будут присутствовать только в том случае, если эти модули доступны в результате динамической загрузки или в результате статической сборки.



Магические константы

Есть девять магических констант, которые меняют своё значение в зависимости от контекста, в котором они используются. Например, значение __LINE__ зависит от строки в скрипте, на которой эта константа указана. Все магические константы разрешаются во время компиляции, в отличие от обычных констант, которые разрешаются во время выполнения. Специальные константы нечувствительны к регистру и их список приведён ниже:

Магические константы PHP
Имя Описание
__LINE__ Текущий номер строки в файле.
__FILE__ Полный путь и имя текущего файла с развёрнутыми симлинками. Если используется внутри подключаемого файла, то возвращается имя данного файла.
__DIR__ Директория файла. Если используется внутри подключаемого файла, то возвращается директория этого файла. Это эквивалентно вызову dirname(__FILE__). Возвращаемое имя директории не оканчивается на слеш, за исключением корневой директории.
__FUNCTION__ Имя функции или {closure} в случае анонимной функции.
__CLASS__ Имя класса. Это имя содержит название пространства имён, в котором класс был объявлен (например, Foo\Bar). При использовании в методах трейтов __CLASS__ является именем класса, в котором эти методы используется.
__TRAIT__ Имя трейта. Это имя содержит название пространства имён, в котором трейт был объявлен (например, Foo\Bar).
__METHOD__ Имя метода класса.
__NAMESPACE__ Имя текущего пространства имён.
ClassName::class Полное имя класса.




Выражения

Выражения - это самые важные строительные элементы 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 поддерживает четыре типа скалярных значений: целочисленные (int), с плавающей точкой (float), строковые значения (string) и булевы (bool) значения (скалярными являются значения, которые вы не можете 'разбить' на меньшие части, в отличие, например, от массивов). PHP поддерживает также два комбинированных (не скалярных) типа: массивы и объекты. Любое значение такого типа может присваиваться переменной или возвращаться функцией.

Однако PHP, как и многие другие языки, понимает гораздо больше выражений. PHP - это язык, ориентированный на выражения и рассматривающий почти все как выражение. Вернёмся к примеру, с которым мы уже имели дело: $a = 5. Легко заметить, что здесь присутствуют два значения - значение целочисленной константы 5 и значение переменной $a, также принимающей значение 5. Но на самом деле здесь присутствует и ещё одно значение - значение самого присвоения. Само присвоение вычисляется в присвоенное значение, в данном случае - в 5. На практике это означает, что $a = 5, независимо от того, что оно делает, является выражением со значением 5. Таким образом, запись $b = ($a = 5) равносильна записи $a = 5; $b = 5; (точка с запятой обозначает конец выражения). Поскольку операции присвоения анализируются справа налево, вы также можете написать $b = $a = 5.

Другой хороший пример ориентированности на выражения - префиксный и постфиксный инкремент и декремент. Пользователи PHP и многих других языков возможно уже знакомы с формой записи variable++ и variable--. Это операторы инкремента и декремента. Также как и C, PHP поддерживает два типа инкремента - префиксный и постфиксный. Они оба инкрементируют значение переменной и эффект их действия на неё одинаков. Разница состоит в значении выражения инкремента. Префиксный инкремент, записываемый как ++$variable, вычисляется в инкрементированное значение (PHP инкрементирует переменную до того как прочесть её значение, отсюда название 'пре-инкремент'). Постфиксный инкремент, записываемый как $variable++, вычисляется в первоначальное значение переменной $variable до её приращения (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,
которая в итоге также становится равной 24. */
?>

Некоторые выражения могут рассматриваться как инструкции. В данном случае инструкция имеет вид 'expr ;' - выражение с последующей точкой с запятой. В записи $b = $a = 5;, $a = 5 - это верное выражение, но само по себе не инструкция. Тогда как $b = $a = 5; является верной инструкцией.

Последнее, что стоит упомянуть, это истинность значения выражений. Во многих случаях, как правило, в условных операторах и циклах, вас может интересовать не конкретное значение выражения, а только его истинность (значение true или false). Константы true и false (регистронезависимые) - это два возможных булевых значения. При необходимости выражение автоматически преобразуется в булев тип. Подробнее о том, как это происходит, смотрите в разделе о приведении типов.

PHP предоставляет полную и мощную реализацию выражений, и их полное документирование выходит за рамки этого руководства. Вышеприведённые примеры должны дать вам представление о том, что они из себя представляют и как вы сами можете создавать полезные выражения. Далее, для обозначения любого верного выражения PHP в этой документации мы будем использовать сокращение expr.



Операторы

Содержание

Оператором называется нечто, принимающее одно или более значений (или выражений, если говорить на жаргоне программирования), и вычисляющее новое значение (таким образом, вся конструкция может рассматриваться как выражение).

Операторы можно сгруппировать по количеству принимаемых ими значений. Унарные операторы принимают только одно значение, например, ! (оператор логического отрицания) или ++ (инкремент). Бинарные операторы принимают два значения; это, например, знакомые всем арифметические операторы + (плюс) и - (минус), большинство поддерживаемых в PHP операторов входят именно в эту категорию. Ну и, наконец, есть всего один тернарный оператор, ? :, принимающий три значения, обычно его так и называют -- "тернарный оператор" (хотя, возможно, более точным названием было бы "условный оператор").

Полный список PHP-операторов вы можете найти в разделе "Порядок выполнения операторов". В этом разделе также описан порядок выполнения операторов и их ассоциативность, которые точно определяют, как вычисляются выражения с несколькими разными операторами.


Приоритет оператора

Приоритет оператора определяет, насколько "тесно" он связывает между собой два выражения. Например, выражение 1 + 5 * 3 вычисляется как 16, а не 18, поскольку оператор умножения ("*") имеет более высокий приоритет, чем оператор сложения ("+"). Круглые скобки могут использоваться для принудительного указания порядка выполнения операторов. Например, выражение (1 + 5) * 3 вычисляется как 18.

Если операторы имеют равный приоритет, то будут ли они выполняться справа налево или слева направо определяется их ассоциативностью. К примеру, "-" является лево-ассоциативным оператором. Следовательно 1 - 2 - 3 сгруппируется как (1 - 2) - 3 и пересчитается в -4. С другой стороны "=" - право-ассоциативный оператор, так что $a = $b = $c сгруппируется как $a = ($b = $c).

Неассоциативные операторы с одинаковым приоритетом не могут использоваться совместно. К примеру 1 < 2 > 1 не будет работать в PHP. Выражение 1 <= 1 == 1, с другой стороны, будет, поскольку == имеет более низкий приоритет чем <=.

Ассоциативность имеет смысл только для двоичных (и тернарных) операторов. Унарные операторы являются префиксными или постфиксными, поэтому это понятие не применимо. Например, !!$a можно сгруппировать только как !(!$a).

Использование скобок, кроме случаев когда они строго необходимы, может улучшить читаемость кода, группируя явно, а не полагаясь на приоритеты и ассоциативность.

В следующей таблице приведён список операторов, отсортированный по убыванию их приоритетов. Операторы, размещённые в одной строке имеют одинаковый приоритет и порядок их выполнения определяется исходя из их ассоциативности.

Порядок выполнения операторов
Ассоциативность Оператор Дополнительная информация
(н/а) clone new clone и new
правая ** арифметические операторы
(н/а) + - ++ -- ~ (int) (float) (string) (array) (object) (bool) @ арифметические операторы (унарные + и -), инкремент/декремент, побитовые операторы, приведение типов и оператор управления ошибками
левая instanceof типы
(н/а) ! логические операторы
левая * / % арифметические операторы
левая + - . арифметические операторы (бинарные + и -), операторы, работающие с массивами и строковые операторы (. до PHP 8.0.0)
левая << >> побитовые операторы
левая . строковые операторы (начиная с PHP 8.0.0)
неассоциативна < <= > >= операторы сравнения
неассоциативна == != === !== <> <=> операторы сравнения
левая & побитовые операторы и ссылки
левая ^ побитовые операторы
левая | побитовые операторы
левая && логические операторы
левая || логические операторы
правая ?? операторы сравнения с null
неассоциативна ? : тернарный оператор (лево-ассоциативный до PHP 8.0.0)
правая = += -= *= **= /= .= %= &= |= ^= <<= >>= ??= операторы присваивания
(н/а) yield from yield from
(н/а) yield yield
(н/а) print print
левая and логические операторы
левая xor логические операторы
левая or логические операторы

Пример #1 Ассоциативность

<?php
$a
= 3 * 3 % 5; // (3 * 3) % 5 = 4
// ассоциативность тернарных операторов отличается от C/C++
$a = true ? 0 : true ? 1 : 2; // (true ? 0 : true) ? 1 : 2 = 2 (до PHP 8.0.0)

$a = 1;
$b = 2;
$a = $b += 3; // $a = ($b += 3) -> $a = 5, $b = 5
?>

Приоритет и ассоциативность оператора определяет только то, как группируется выражение, а не порядок его вычисления. Обычно PHP не указывает, в каком порядке вычисляются выражения и кода, который предполагает специфичный порядок вычисления следует избегать, потому, что поведение может меняться в разных версиях PHP или в зависимости от окружающего кода.

Пример #2 Неопределённый порядок вычисления

<?php
$a
= 1;
echo
$a + $a++; // может вывести как 2 так и 3

$i = 1;
$array[$i] = $i++; // может установить индекс как 1, так 2
?>

Пример #3 +, - и . имеют одинаковый приоритет (до PHP 8.0.0)

<?php
$x
= 4;
// следующий код может выдать неожиданный результат:
echo "x минус 1 равно " . $x-1 . ", ну я надеюсь\n";
// поскольку он вычисляется таким образом (до PHP 8.0.0):
echo (("x минус один равно " . $x) - 1) . ", ну я надеюсь\n";
// требуемый приоритет следует задать скобками:
echo "x минус 1 равно " . ($x-1) . ", ну я надеюсь\n";
?>

Результат выполнения данного примера:

-1, ну я надеюсь
-1, ну я надеюсь
x минус один равно 3, ну я надеюсь

Замечание:

Несмотря на то, что = имеет более низкий приоритет, чем большинство других операторов, PHP всё же позволяет делать так: if (!$a = foo()), в этом примере результат выполнения foo() будет присвоен $a.

Список изменений

Версия Описание
8.0.0 Объединение строк (.) теперь имеет более низкий приоритет, чем арифметическое сложение/вычитание (+ и -) и побитовый сдвиг влево/вправо (<< и >>); ранее он имел тот же приоритет, что и + и -, и более высокий приоритет, чем << и >>.
8.0.0 Тернарный оператор (? :) теперь неассоциативен; ранее он был лево-ассоциативным.
7.4.0 Опираясь на приоритет конкатенации строк (.) относительно арифметического сложения/вычитания (+ или -) или побитового сдвига влево/вправо (<< или >>), т.е. их совместное использование в выражении без скобок не рекомендуется.
7.4.0 Не рекомендуется полагаться на лево-ассоциативность тернарного оператора (? :), т.е. вложение нескольких тернарных операторов без скобок.


Арифметические операторы

Помните школьные основы арифметики? Описанные ниже операторы работают так же.

Арифметические операции
Пример Название Результат
+$a Идентичность Конвертация $a в int или float, что более подходит.
-$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 в степень $b.

Операция деления ("/") возвращает число с плавающей точкой, кроме случая, когда оба значения являются целыми числами (или строками, которые преобразуются в целые числа), которые делятся нацело - в этом случае возвращается целое значение. Для целочисленного деления используйте intdiv().

При делении по модулю операнды преобразуются в целые числа (int) (путём удаления дробной части) до начала операции. Для деления по модулю чисел с плавающей точкой используйте fmod().

Результат операции остатка от деления % будет иметь тот же знак, что и делимое — то есть, результат $a % $b будет иметь тот же знак, что и $a. Например:

<?php

echo (5 % 3)."\n"; // выводит 2
echo (5 % -3)."\n"; // выводит 2
echo (-5 % 3)."\n"; // выводит -2
echo (-5 % -3)."\n"; // выводит -2

?>

Смотрите также



Оператор присваивания

Базовый оператор присваивания обозначается как "=". На первый взгляд может показаться, что это оператор "равно". На самом деле это не так. В действительности оператор присваивания означает, что левый операнд получает значение правого выражения, (то есть устанавливается значением).

Результатом выполнения оператора присваивания является само присвоенное значение. Таким образом, результат выполнения "$a = 3" будет равен 3. Это позволяет делать трюки наподобие:

<?php

$a
= ($b = 4) + 5; // $a теперь равно 9, а $b было присвоено 4.

?>

В дополнение к базовому оператору присваивания имеются "комбинированные операторы" для всех бинарных арифметических операций, операций объединения массивов и строковых операций, которые позволяют использовать некоторое значение в выражении, а затем установить его как результат данного выражения. Например:

<?php

$a
= 3;
$a += 5; // устанавливает $a в 8, как если бы мы написали: $a = $a + 5;
$b = "Привет";
$b .= "-привет!"; // устанавливает $b в "Привет-привет!", как и $b = $b . "-привет!";

?>

Обратите внимание, что присвоение копирует оригинальную переменную в новую (присвоение по значению), таким образом все последующие изменения одной из переменных никак не отразятся на другой. Это также следует учитывать, если вам надо скопировать что-то типа большого массива в длинном цикле.

Исключением из обычного для PHP способа присваивания по значению являются объекты (object), которые присваиваются по ссылке. Принудительно скопировать объекты по значению можно с помощью специального ключевого слова clone.

Присваивание по ссылке

Присваивание по ссылке также поддерживается, для него используется синтаксис $var = &$othervar;. Присваивание по ссылке означает, что обе переменные указывают на одни и те же данные и никакого копирования не происходит.

Пример #1 Присваивание по ссылке

<?php
$a
= 3;
$b = &$a; // $b - это ссылка на $a

print "$a\n"; // печатает 3
print "$b\n"; // печатает 3

$a = 4; // меняем $a

print "$a\n"; // печатает 4
print "$b\n"; // также печатает 4, так как $b является ссылкой на $a,
// а значение переменной $a успело измениться
?>

Оператор new автоматически возвращает ссылку, поэтому присвоение результата операции new по ссылке является ошибкой.

<?php
class C {}

$o = &new C;
?>

Результат выполнения данного примера:

Parse error: syntax error, unexpected 'new' (T_NEW) in …

Для получения более полной информации о ссылках и их возможностях обратитесь к разделу Подробно о ссылках.

Операторы арифметического присваивания

Пример Эквивалент Операция
$a += $b $a = $a + $b Сложение
$a -= $b $a = $a - $b Вычитание
$a *= $b $a = $a * $b Умножение
$a /= $b $a = $a / $b Деление
$a %= $b $a = $a % $b Модуль
$a **= $b $a = $a ** $b Возведение в степень

Операторы побитового присваивания

Пример Эквивалент Операция
$a &= $b $a = $a & $b Побитовое И
$a |= $b $a = $a | $b Побитовое ИЛИ
$a ^= $b $a = $a ^ $b Побитовое исключающее ИЛИ (Xor)
$a <<= $b $a = $a << $b Побитовый сдвиг влево
$a >>= $b $a = $a >> $b Побитовый сдвиг вправо

Другие операторы присваивания

Пример Эквивалент Операция
$a .= $b $a = $a . $b Конкатенация строк
$a ??= $b $a = $a ?? $b Объединение с Null


Побитовые операторы

Побитовые операторы позволяют считывать и устанавливать конкретные биты целых чисел.

Побитовые операторы
Пример Название Результат
$a & $b И Устанавливаются только те биты, которые установлены и в $a, и в $b.
$a | $b Или Устанавливаются те биты, которые установлены в $a или в $b.
$a ^ $b Исключающее или Устанавливаются только те биты, которые установлены либо только в $a, либо только в $b, но не в обоих одновременно.
~ $a Отрицание Устанавливаются те биты, которые не установлены в $a, и наоборот.
$a << $b Сдвиг влево Все биты переменной $a сдвигаются на $b позиций влево (каждая позиция подразумевает "умножение на 2")
$a >> $b Сдвиг вправо Все биты переменной $a сдвигаются на $b позиций вправо (каждая позиция подразумевает "деление на 2")

Побитовый сдвиг в PHP - это арифметическая операция. Биты, сдвинутые за границы числа, отбрасываются. Сдвиг влево дополняет число нулями справа, сдвигая в то же время знаковый бит числа влево, что означает что знак операнда не сохраняется. Сдвиг вправо сохраняет копию сдвинутого знакового бита слева, что означает что знак операнда сохраняется.

Используйте скобки для обеспечения необходимого приоритета операторов. Например, $a & $b == true сначала проверяет на равенство, а потом выполняет побитовое и; тогда как ($a & $b) == true сначала выполняет побитовое и, а потом выполняет проверку на равенство.

Если оба операнда для &, | и ^ строки, то операция будет производиться с кодами ASCII всех символов строки и в результате вернёт строку. Во всех остальных случаях, оба операнда будут преобразованы к целому и результатом будет целое число.

Если операнд для ~ строка, то операция будет производиться с кодами ASCII всех символов строки и в результате вернёт строку, в ином случае как операнд, так и результат, будут считаться целыми.

Оба операнда и результат выполнения << и >> всегда считаются за целое.

      Опция настроек PHP error_reporting использует побитовые значения, обеспечивая
      реальную демонстрацию удаления значений битов. Чтобы показать все ошибки, кроме
      замечаний, инструкции в файле php.ini предлагают использовать:
      E_ALL & ~E_NOTICE
     

      Начинаем со значения E_ALL:
      00000000000000000111011111111111
      Затем берём значение E_NOTICE...
      00000000000000000000000000001000
      ... и инвертируем его с помощью ~:
      11111111111111111111111111110111
      Наконец, используем побитовое И (&), чтобы установить только те биты,
      которые установлены в единицу в обоих значениях:
      00000000000000000111011111110111
     

      Другой способ достичь этого - использовать ИСКЛЮЧАЮЩЕЕ ИЛИ (XOR, ^),
      чтобы получить только те биты, которые установлены в единицу
      либо только в одном, либо только в другом значении:
      E_ALL ^ E_NOTICE
     

      Опция error_reporting также может быть использована для демонстрации
      установки битов. Показать только ошибки и обрабатываемые ошибки можно
      следующим образом:
      E_ERROR | E_RECOVERABLE_ERROR
     

      Здесь мы комбинируем E_ERROR
      00000000000000000000000000000001
      и
      00000000000000000001000000000000
      с помощью оператора ИЛИ (|),
      чтобы получить биты, установленные хотя бы в одном операнде:
      00000000000000000001000000000001
     

Пример #1 Побитовыми операции И, ИЛИ и ИСКЛЮЧАЮЩЕЕ ИЛИ (AND, OR и XOR) над целыми числами

<?php
/*
* Не обращайте внимания на этот верхний раздел кода,
* это просто форматирование для более ясного вывода.
*/

$format = '(%1$2d = %1$04b) = (%2$2d = %2$04b)'
. ' %3$s (%4$2d = %4$04b)' . "\n";

echo <<<EOH
---------- ----------- -- ----------
результат значение оп тест
---------- ----------- -- ----------
EOH;


/*
* Вот сами примеры.
*/

$values = array(0, 1, 2, 4, 8);
$test = 1 + 4;

echo
"\n Побитовое И (AND) \n";
foreach (
$values as $value) {
$result = $value & $test;
printf($format, $result, $value, '&', $test);
}

echo
"\n Побитовое (включающее) ИЛИ (OR) \n";
foreach (
$values as $value) {
$result = $value | $test;
printf($format, $result, $value, '|', $test);
}

echo
"\n Побитовое ИСКЛЮЧАЮЩЕЕ ИЛИ (XOR) \n";
foreach (
$values as $value) {
$result = $value ^ $test;
printf($format, $result, $value, '^', $test);
}
?>

Результат выполнения данного примера:

 ----------   ----------- -- ----------
 результат      значение      оп тест
 ----------   ----------- -- ----------
 Побитовое И (AND)
( 0 = 0000) = ( 0 = 0000) & ( 5 = 0101)
( 1 = 0001) = ( 1 = 0001) & ( 5 = 0101)
( 0 = 0000) = ( 2 = 0010) & ( 5 = 0101)
( 4 = 0100) = ( 4 = 0100) & ( 5 = 0101)
( 0 = 0000) = ( 8 = 1000) & ( 5 = 0101)

 Побитовое (включающее) ИЛИ (OR)
( 5 = 0101) = ( 0 = 0000) | ( 5 = 0101)
( 5 = 0101) = ( 1 = 0001) | ( 5 = 0101)
( 7 = 0111) = ( 2 = 0010) | ( 5 = 0101)
( 5 = 0101) = ( 4 = 0100) | ( 5 = 0101)
(13 = 1101) = ( 8 = 1000) | ( 5 = 0101)

 Побитовое ИСКЛЮЧАЮЩЕЕ ИЛИ (XOR)
( 5 = 0101) = ( 0 = 0000) ^ ( 5 = 0101)
( 4 = 0100) = ( 1 = 0001) ^ ( 5 = 0101)
( 7 = 0111) = ( 2 = 0010) ^ ( 5 = 0101)
( 1 = 0001) = ( 4 = 0100) ^ ( 5 = 0101)
(13 = 1101) = ( 8 = 1000) ^ ( 5 = 0101)

Пример #2 Побитовая операция ИСКЛЮЧАЮЩЕЕ ИЛИ (XOR) над строками

<?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
?>

Пример #3 Побитовый сдвиг над целыми числами

<?php
/*
* Несколько примеров.
*/

echo "\n--- СДВИГ ВПРАВО НАД ПОЛОЖИТЕЛЬНЫМИ ЦЕЛЫМИ ЧИСЛАМИ ---\n";

$val = 4;
$places = 1;
$res = $val >> $places;
p($res, $val, '>>', $places, 'слева была вставлена копия знакового бита');

$val = 4;
$places = 2;
$res = $val >> $places;
p($res, $val, '>>', $places);

$val = 4;
$places = 3;
$res = $val >> $places;
p($res, $val, '>>', $places, 'биты были выдвинуты за правый край');

$val = 4;
$places = 4;
$res = $val >> $places;
p($res, $val, '>>', $places, 'то же, что и выше; нельзя сдвинуть дальше 0');


echo
"\n--- СДВИГ ВПРАВО НАД ОТРИЦАТЕЛЬНЫМИ ЦЕЛЫМИ ЧИСЛАМИ ---\n";

$val = -4;
$places = 1;
$res = $val >> $places;
p($res, $val, '>>', $places, 'слева была вставлена копия знакового бита');

$val = -4;
$places = 2;
$res = $val >> $places;
p($res, $val, '>>', $places, 'биты были выдвинуты за правый край');

$val = -4;
$places = 3;
$res = $val >> $places;
p($res, $val, '>>', $places, 'то же, что и выше; нельзя сдвинуть дальше -1');


echo
"\n--- СДВИГ ВЛЕВО НАД ПОЛОЖИТЕЛЬНЫМИ ЦЕЛЫМИ ЧИСЛАМИ ---\n";

$val = 4;
$places = 1;
$res = $val << $places;
p($res, $val, '<<', $places, 'правый край был дополнен нулями');

$val = 4;
$places = (PHP_INT_SIZE * 8) - 4;
$res = $val << $places;
p($res, $val, '<<', $places);

$val = 4;
$places = (PHP_INT_SIZE * 8) - 3;
$res = $val << $places;
p($res, $val, '<<', $places, 'знаковые биты были выдвинуты');

$val = 4;
$places = (PHP_INT_SIZE * 8) - 2;
$res = $val << $places;
p($res, $val, '<<', $places, 'биты были выдвинуты за левый край');


echo
"\n--- СДВИГ ВЛЕВО НАД ОТРИЦАТЕЛЬНЫМИ ЦЕЛЫМИ ЧИСЛАМИ ---\n";

$val = -4;
$places = 1;
$res = $val << $places;
p($res, $val, '<<', $places, 'правый край был дополнен нулями');

$val = -4;
$places = (PHP_INT_SIZE * 8) - 3;
$res = $val << $places;
p($res, $val, '<<', $places);

$val = -4;
$places = (PHP_INT_SIZE * 8) - 2;
$res = $val << $places;
p($res, $val, '<<', $places, 'биты были выдвинуты за левый край, включая знаковый бит');


/*
* Не обращайте внимания на этот нижний раздел кода,
* это просто форматирование для более ясного вывода.
*/

function p($res, $val, $op, $places, $note = '') {
$format = '%0' . (PHP_INT_SIZE * 8) . "b\n";

printf("Выражение: %d = %d %s %d\n", $res, $val, $op, $places);

echo
" Десятичный вид:\n";
printf(" val=%d\n", $val);
printf(" res=%d\n", $res);

echo
" Двоичный вид:\n";
printf(' val=' . $format, $val);
printf(' res=' . $format, $res);

if (
$note) {
echo
" ЗАМЕЧАНИЕ: $note\n";
}

echo
"\n";
}
?>

Результат выполнения данного примера на 32-битных машинах:


--- СДВИГ ВПРАВО НАД ПОЛОЖИТЕЛЬНЫМИ ЦЕЛЫМИ ЧИСЛАМИ ---
Выражение: 2 = 4 >> 1
 Десятичный вид:
  val=4
  res=2
 Двоичный вид:
  val=00000000000000000000000000000100
  res=00000000000000000000000000000010
 ЗАМЕЧАНИЕ: слева была вставлена копия знакового бита

Выражение: 1 = 4 >> 2
 Десятичный вид:
  val=4
  res=1
 Двоичный вид:
  val=00000000000000000000000000000100
  res=00000000000000000000000000000001

Выражение: 0 = 4 >> 3
 Десятичный вид:
  val=4
  res=0
 Двоичный вид:
  val=00000000000000000000000000000100
  res=00000000000000000000000000000000
 ЗАМЕЧАНИЕ: биты были выдвинуты за правый край

Выражение: 0 = 4 >> 4
 Десятичный вид:
  val=4
  res=0
 Двоичный вид:
  val=00000000000000000000000000000100
  res=00000000000000000000000000000000
 ЗАМЕЧАНИЕ: то же, что и выше; нельзя сдвинуть дальше 0


--- СДВИГ ВПРАВО НА ОТРИЦАТЕЛЬНЫХ ЦЕЛЫХ ЧИСЛАХ ---
Выражение: -2 = -4 >> 1
 Десятичный вид:
  val=-4
  res=-2
 Двоичный вид:
  val=11111111111111111111111111111100
  res=11111111111111111111111111111110
 ЗАМЕЧАНИЕ: слева была вставлена копия знакового бита

Выражение: -1 = -4 >> 2
 Десятичный вид:
  val=-4
  res=-1
 Двоичный вид:
  val=11111111111111111111111111111100
  res=11111111111111111111111111111111
 ЗАМЕЧАНИЕ: биты были выдвинуты за правый край

Выражение: -1 = -4 >> 3
 Десятичный вид:
  val=-4
  res=-1
 Двоичный вид:
  val=11111111111111111111111111111100
  res=11111111111111111111111111111111
 ЗАМЕЧАНИЕ: то же, что и выше; нельзя сдвинуть дальше -1


--- СДВИГ ВЛЕВО НАД ПОЛОЖИТЕЛЬНЫМИ ЦЕЛЫМИ ЧИСЛАМИ ---
Выражение: 8 = 4 << 1
 Десятичный вид:
  val=4
  res=8
 Двоичный вид:
  val=00000000000000000000000000000100
  res=00000000000000000000000000001000
 ЗАМЕЧАНИЕ: правый край был дополнен нулями

Выражение: 1073741824 = 4 << 28
 Десятичный вид:
  val=4
  res=1073741824
 Двоичный вид:
  val=00000000000000000000000000000100
  res=01000000000000000000000000000000

Выражение: -2147483648 = 4 << 29
 Десятичный вид:
  val=4
  res=-2147483648
 Двоичный вид:
  val=00000000000000000000000000000100
  res=10000000000000000000000000000000
 ЗАМЕЧАНИЕ: знаковые биты были выдвинуты

Выражение: 0 = 4 << 30
 Десятичный вид:
  val=4
  res=0
 Двоичный вид:
  val=00000000000000000000000000000100
  res=00000000000000000000000000000000
 ЗАМЕЧАНИЕ: биты были выдвинуты за левый край


--- СДВИГ ВЛЕВО НАД ОТРИЦАТЕЛЬНЫМИ ЦЕЛЫМИ ЧИСЛАМИ ---
Выражение: -8 = -4 << 1
 Десятичный вид:
  val=-4
  res=-8
 Двоичный вид:
  val=11111111111111111111111111111100
  res=11111111111111111111111111111000
 ЗАМЕЧАНИЕ: правый край был дополнен нулями

Выражение: -2147483648 = -4 << 29
 Десятичный вид:
  val=-4
  res=-2147483648
 Двоичный вид:
  val=11111111111111111111111111111100
  res=10000000000000000000000000000000

Выражение: 0 = -4 << 30
 Десятичный вид:
  val=-4
  res=0
 Двоичный вид:
  val=11111111111111111111111111111100
  res=00000000000000000000000000000000
 ЗАМЕЧАНИЕ: биты были выдвинуты за левый край, включая знаковый бит

Результат выполнения данного примера на 64-битных машинах:


--- СДВИГ ВПРАВО НАД ПОЛОЖИТЕЛЬНЫМИ ЦЕЛЫМИ ЧИСЛАМИ ---
Выражение: 2 = 4 >> 1
 Десятичный вид:
  val=4
  res=2
 Двоичный вид:
  val=0000000000000000000000000000000000000000000000000000000000000100
  res=0000000000000000000000000000000000000000000000000000000000000010
 ЗАМЕЧАНИЕ: слева была вставлена копия знакового бита

Выражение: 1 = 4 >> 2
 Десятичный вид:
  val=4
  res=1
 Двоичный вид:
  val=0000000000000000000000000000000000000000000000000000000000000100
  res=0000000000000000000000000000000000000000000000000000000000000001

Выражение: 0 = 4 >> 3
 Десятичный вид:
  val=4
  res=0
 Двоичный вид:
  val=0000000000000000000000000000000000000000000000000000000000000100
  res=0000000000000000000000000000000000000000000000000000000000000000
 ЗАМЕЧАНИЕ: биты были выдвинуты за правый край

Выражение: 0 = 4 >> 4
 Десятичный вид:
  val=4
  res=0
 Двоичный вид:
  val=0000000000000000000000000000000000000000000000000000000000000100
  res=0000000000000000000000000000000000000000000000000000000000000000
 ЗАМЕЧАНИЕ: то же, что и выше; нельзя сдвинуть дальше 0


--- СДВИГ ВПРАВО НАД ОТРИЦАТЕЛЬНЫМИ ЦЕЛЫМИ ЧИСЛАМИ ---
Выражение: -2 = -4 >> 1
 Десятичный вид:
  val=-4
  res=-2
 Двоичный вид:
  val=1111111111111111111111111111111111111111111111111111111111111100
  res=1111111111111111111111111111111111111111111111111111111111111110
 ЗАМЕЧАНИЕ: слева была вставлена копия знакового бита

Выражение: -1 = -4 >> 2
 Десятичный вид:
  val=-4
  res=-1
 Двоичный вид:
  val=1111111111111111111111111111111111111111111111111111111111111100
  res=1111111111111111111111111111111111111111111111111111111111111111
 ЗАМЕЧАНИЕ: биты были выдвинуты за правый край

Выражение: -1 = -4 >> 3
 Десятичный вид:
  val=-4
  res=-1
 Двоичный вид:
  val=1111111111111111111111111111111111111111111111111111111111111100
  res=1111111111111111111111111111111111111111111111111111111111111111
 ЗАМЕЧАНИЕ: то же, что и выше; нельзя сдвинуть дальше -1


--- СДВИГ ВЛЕВО НАД ПОЛОЖИТЕЛЬНЫМИ ЦЕЛЫМИ ЧИСЛАМИ ---
Выражение: 8 = 4 << 1
 Десятичный вид:
  val=4
  res=8
 Двоичный вид:
  val=0000000000000000000000000000000000000000000000000000000000000100
  res=0000000000000000000000000000000000000000000000000000000000001000
 ЗАМЕЧАНИЕ: правый край был дополнен нулями

Выражение: 4611686018427387904 = 4 << 60
 Десятичный вид:
  val=4
  res=4611686018427387904
 Двоичный вид:
  val=0000000000000000000000000000000000000000000000000000000000000100
  res=0100000000000000000000000000000000000000000000000000000000000000

Выражение: -9223372036854775808 = 4 << 61
 Десятичный вид:
  val=4
  res=-9223372036854775808
 Двоичный вид:
  val=0000000000000000000000000000000000000000000000000000000000000100
  res=1000000000000000000000000000000000000000000000000000000000000000
 ЗАМЕЧАНИЕ: знаковые биты были выдвинуты

Выражение: 0 = 4 << 62
 Десятичный вид:
  val=4
  res=0
 Двоичный вид:
  val=0000000000000000000000000000000000000000000000000000000000000100
  res=0000000000000000000000000000000000000000000000000000000000000000
 ЗАМЕЧАНИЕ: биты были выдвинуты за левый край


--- СДВИГ ВЛЕВО НАД ОТРИЦАТЕЛЬНЫМИ ЦЕЛЫМИ ЧИСЛАМИ ---
Выражение: -8 = -4 << 1
 Десятичный вид:
  val=-4
  res=-8
 Двоичный вид:
  val=1111111111111111111111111111111111111111111111111111111111111100
  res=1111111111111111111111111111111111111111111111111111111111111000
 ЗАМЕЧАНИЕ: правый край был дополнен нулями

Выражение: -9223372036854775808 = -4 << 61
 Десятичный вид:
  val=-4
  res=-9223372036854775808
 Двоичный вид:
  val=1111111111111111111111111111111111111111111111111111111111111100
  res=1000000000000000000000000000000000000000000000000000000000000000

Выражение: 0 = -4 << 62
 Десятичный вид:
  val=-4
  res=0
 Двоичный вид:
  val=1111111111111111111111111111111111111111111111111111111111111100
  res=0000000000000000000000000000000000000000000000000000000000000000
 ЗАМЕЧАНИЕ: биты были выдвинуты за левый край, включая знаковый бит

Внимание

Используйте функции из модуля gmp для побитовых операций над числами, большими чем PHP_INT_MAX.



Операторы сравнения

Операторы сравнения, как это видно из их названия, позволяют сравнивать между собой два значения. Возможно вам будет интересно также ознакомиться с разделом Сравнение типов, в котором приведено большое количество соответствующих примеров.

Операторы сравнения
Пример Название Результат
$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, или они разных типов.
$a < $b Меньше true если $a строго меньше $b.
$a > $b Больше true если $a строго больше $b.
$a <= $b Меньше или равно true если $a меньше или равно $b.
$a >= $b Больше или равно true если $a больше или равно $b.
$a <=> $b Космический корабль (spaceship) Число типа int меньше, больше или равное нулю, когда $a соответственно меньше, больше или равно $b.

В случае, если оба операнда являются строками, содержащими числа или один операнд является числом, а другой - строкой, содержащей числа, то сравнение выполняется численно. Эти правила также применяются к оператору switch. Преобразование типа не происходит при сравнении === или !==, поскольку это включает сравнение типа, а также значения.

Внимание

До PHP 8.0.0, если строка (string) сравнивалась с числом или строкой, содержащей число, то строка (string) преобразовывалось в число перед выполнением сравнения. Это могло привести к неожиданным результатам, что можно увидеть на следующем примере:

<?php
var_dump
(0 == "a");
var_dump("1" == "01");
var_dump("10" == "1e1");
var_dump(100 == "1e2");

switch (
"a") {
case
0:
echo
"0";
break;
case
"a":
echo
"a";
break;
}
?>

Результат выполнения данного примера в PHP 7:

bool(true)
bool(true)
bool(true)
bool(true)
0

Результат выполнения данного примера в PHP 8:

bool(false)
bool(true)
bool(true)
bool(true)
a

<?php
// Целые числа
echo 1 <=> 1; // 0
echo 1 <=> 2; // -1
echo 2 <=> 1; // 1

// Числа с плавающей точкой
echo 1.5 <=> 1.5; // 0
echo 1.5 <=> 2.5; // -1
echo 2.5 <=> 1.5; // 1

// Строки
echo "a" <=> "a"; // 0
echo "a" <=> "b"; // -1
echo "b" <=> "a"; // 1

echo "a" <=> "aa"; // -1
echo "zz" <=> "aa"; // 1

// Массивы
echo [] <=> []; // 0
echo [1, 2, 3] <=> [1, 2, 3]; // 0
echo [1, 2, 3] <=> []; // 1
echo [1, 2, 3] <=> [1, 2, 1]; // 1
echo [1, 2, 3] <=> [1, 2, 4]; // -1

// Объекты
$a = (object) ["a" => "b"];
$b = (object) ["a" => "b"];
echo
$a <=> $b; // 0

$a = (object) ["a" => "b"];
$b = (object) ["a" => "c"];
echo
$a <=> $b; // -1

$a = (object) ["a" => "c"];
$b = (object) ["a" => "b"];
echo
$a <=> $b; // 1

// сравниваются не только значения; ключи также должны совпадать
$a = (object) ["a" => "b"];
$b = (object) ["b" => "b"];
echo
$a <=> $b; // 1

?>

Для различных типов сравнение происходит в соответствии со следующей таблицей (по порядку).

Сравнение различных типов
Тип операнда 1 Тип операнда 2 Результат
null или string string null преобразуется в "", числовое или лексическое сравнение
bool или null что угодно Преобразуется в тип bool, false < true
object object Встроенные классы могут определять свои собственные правила сравнения, объекты разных классов не сравниваются, про сравнение объектов одного класса смотрите Сравнение объекта
string, resource, int или float string, resource, int или float Строки и ресурсы переводятся в числа, обычная математика
array array Массивы с меньшим числом элементов считаются меньше, если ключ из первого операнда не найден во втором операнде - массивы не могут сравниваться, иначе идёт сравнение соответствующих значений (смотрите пример ниже)
array что угодно тип array всегда больше
object что угодно тип object всегда больше

Пример #1 Сравнение boolean/null

<?php
// Логические значения и null всегда сравниваются как логические
var_dump(1 == TRUE); // TRUE - то же, что и (bool)1 == TRUE
var_dump(0 == FALSE); // TRUE - то же, что и (bool)0 == FALSE
var_dump(100 < TRUE); // FALSE - то же, что и (bool)100 < TRUE
var_dump(-10 < FALSE);// FALSE - то же, что и (bool)-10 < FALSE
var_dump(min(-100, -10, NULL, 10, 100)); // NULL - (bool)NULL < (bool)-100 это FALSE < TRUE
?>

Пример #2 Алгоритм сравнения обычных массивов

<?php
// Массивы сравниваются таким образом с помощью стандартных операторов сравнения, а также оператора spaceship.
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
1;
} elseif (
$val < $op2[$key]) {
return -
1;
} elseif (
$val > $op2[$key]) {
return
1;
}
}
return
0; // $op1 == $op2
}
?>

Внимание

Сравнение чисел с плавающей точкой

Из-за особого внутреннего представления типа float, не нужно проверять на равенство два числа с плавающей точкой (float).

Для более подробной информации смотрите документацию по типу float.

Замечание: Помните, что жонглирование типами в PHP не всегда очевидно при сравнении значений разных типов, особенно при сравнении целых чисел (int) с логическими значениями (bool) или целых чисел (int) со строками (string). Поэтому в большинстве случаев рекомендуется использовать сравнения === и !==, а не == и !=.

Несравнимые значение

В то время как сравнение тождества (=== и !==) можно применять к произвольным значениям, другие операторы сравнения следует применять только к сравнимым значениям. Результат сравнения несравнимых значений не определён и на него не следует полагаться.

Тернарный оператор

Ещё одним условным оператором является тернарный оператор "?:".

Пример #3 Присваивание значения по умолчанию

<?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.

Также стало возможным не писать среднюю часть тернарного оператора. Выражение expr1 ?: expr3 оценивается как результат expr1, если результат выражения expr1 оценивается как true и expr3 в противном случае. Выражение expr1 в этом случае оценивается только один раз.

Замечание: Обратите внимание, что тернарный оператор является выражением и трактуется не как переменная, а как результат выражения. Это важно знать, если вы хотите вернуть переменную по ссылке. Выражение return $var == 42 ? $a : $b; не будет работать в функции, возвращающей значение по ссылке, а в более поздних версиях PHP также будет выдано предупреждение.

Замечание:

Рекомендуется избегать "нагромождения" тернарных выражений. Поведение PHP неочевидно при использовании более чем одного тернарного оператора без скобок в одном выражении по сравнению с другими языками. Действительно, до PHP 8.0.0 троичные выражения оценивались лево-ассоциативными, а не право-ассоциативными, как в большинстве других языков программирования. Использование лево-ассоциативности устарело в PHP 7.4.0. Начиная с PHP 8.0.0, тернарный оператор неассоциативен.

Пример #4 Неочевидное поведение тернарного оператора

<?php
// на первый взгляд, следующий код должен вывести 'true'
echo (true ? 'true' : false ? 't' : 'f');

// однако, он выводит 't' до PHP 8.0.0
// это потому, что тернарные выражения левоассоциативны

// это намного более очевидная версия вышеприведённого кода
echo ((true ? 'true' : false) ? 't' : 'f');

// здесь видно, что первое выражение вычисляется в 'true', которое
// в свою очередь вычисляется в (bool)true, таким образом возвращая истинную ветвь
// второго тернарного выражения.
?>

Замечание:

Цепочка коротких тернарных операторов (?:) стабильна и ведёт себя разумно. Она будет оценивать первый аргумент, который оценивается как не ложное значение. Обратите внимание, что неопределённые значения все равно вызовут предупреждение.

Пример #5 Цепочка коротких тернарных операторов

<?php
echo 0 ?: 1 ?: 2 ?: 3, PHP_EOL; //1
echo 0 ?: 0 ?: 2 ?: 3, PHP_EOL; //2
echo 0 ?: 0 ?: 0 ?: 3, PHP_EOL; //3
?>

Оператор объединения с null

Другим полезным сокращённым оператором является оператор "??" (null coalescing).

Пример #6 Присваивание значения по умолчанию

<?php
// Пример использования оператора
$action = $_POST['action'] ?? 'default';

// Пример выше аналогичен следующему коду
if (isset($_POST['action'])) {
$action = $_POST['action'];
} else {
$action = 'default';
}
?>
Выражение (expr1) ?? (expr2) вычисляется так: expr2, если expr1 равен null и expr1 в противном случае.

На практике, этот оператор не вызывает предупреждения или ошибки, если левый операнд не существует, как и isset(). Это очень полезно для ключей массива.

Замечание: Пожалуйста помните, что этот оператор является выражением, и он приравнивается к выражению, а не значению переменной. Это может быть важным, если вы хотите вернуть значение по ссылке. Выражение return $foo ?? $bar; в функции возвращающей ссылку будет не работать, а выводить предупреждение.

Замечание:

У оператора null coalescing низкий приоритет. Это означает, что при смешивании его с другими операторами (такими как конкатенация строк или арифметические операторы), скорее всего, потребуются круглые скобки.

<?php
// Вызывает предупреждение о том, что $name не определено.
print 'Mr. ' . $name ?? 'Anonymous';
// Выведет "Mr. Anonymous"
print 'Mr. ' . ($name ?? 'Anonymous');
?>

Замечание:

Обратите внимание, что этот оператор позволяет использовать простую вложенность:

Пример #7 Вложенный оператор null coalescing

<?php

$foo
= null;
$bar = null;
$baz = 1;
$qux = 2;

echo
$foo ?? $bar ?? $baz ?? $qux; // выведет 1

?>



Оператор управления ошибками

PHP поддерживает один оператор управления ошибками: знак @. В случае, если он предшествует какому-либо выражению в PHP-коде, любые сообщения об ошибках, генерируемые этим выражением, будут подавлены.

Если пользовательская функция обработчика ошибок установлена с помощью set_error_handler(), она всё равно будет вызываться, даже если диагностика была подавлена.

Внимание

До версии PHP 8.0.0 функция error_reporting(), вызываемая внутри пользовательского обработчика ошибок, всегда возвращала 0, если ошибка была подавлена оператором @. Начиная с PHP 8.0.0, она возвращает значение E_ERROR | E_CORE_ERROR | E_COMPILE_ERROR | E_USER_ERROR | E_RECOVERABLE_ERROR | E_PARSE.

Любое сообщение об ошибке, сгенерированное выражением, доступно в элементе массива "message", возвращаемого error_get_last(). Результат этой функции будет меняться при каждой ошибке, поэтому его необходимо проверить заранее.

<?php
// Преднамеренная ошибка при работе с файлами
$my_file = @file ('non_existent_file') or
die (
"Ошибка при открытии файла: сообщение об ошибке было таким: '" . error_get_last()['message'] . "'");

// работает для любых выражений, а не только для функций
$value = @$cache[$key];
// В случае если ключа $key нет, сообщение об ошибке (notice) не будет отображено

?>

Замечание: Оператор @ работает только с выражениями. Есть простое правило: если что-то возвращает значение, значит вы можете использовать перед ним оператор @. Например, вы можете использовать @ перед именем переменной, произвольной функцией или вызовом include и так далее. В то же время вы не можете использовать этот оператор перед определением функции или класса, условными конструкциями, такими как if, foreach и т.д.

Внимание

До PHP 8.0.0 оператор @ мог подавлять критические ошибки, которые прерывали выполнение скрипта. Например, добавление @ к вызову несуществующей функции, в случае, если она недоступна или написана неправильно, дальнейшая работа скрипта приведёт к прерыванию выполнения скрипта без каких-либо уведомлений.



Операторы исполнения

PHP поддерживает один оператор исполнения: обратные кавычки (``). Обратите внимание, что это не одинарные кавычки! PHP попытается выполнить строку, заключённую в обратные кавычки, как консольную команду, и вернёт полученный вывод (то есть он не просто выводится на экран, а, например, может быть присвоен переменной). Использование обратных кавычек аналогично использованию функции shell_exec().

<?php
$output
= `ls -al`;
echo
"<pre>$output</pre>";
?>

Замечание:

Обратные кавычки недоступны, в случае, если отключена функция shell_exec().

Замечание:

В отличие от некоторых других языков, обратные кавычки не будут работать внутри строк в двойных кавычках.



Операторы инкремента и декремента

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 (в отличие от С) касательно выполнения арифметических операций с символьными переменными. Например, в PHP и Perl $a = 'Z'; $a++; присвоит $a значение 'AA', в то время как в C a = 'Z'; a++; присвоит a значение '[' (ASCII-значение 'Z' равно 90, а ASCII-значение '[' равно 91). Следует учесть, что к символьным переменным можно применять операцию инкремента, в то время как операцию декремента применять нельзя, кроме того, поддерживаются только ASCII-символы (a-z, A-Z и 0-9). Попытка инкремента/декремента других символьных переменных не будет иметь никакого эффекта, исходная строка останется неизменной.

Пример #1 Арифметические операции с символьными переменными

<?php
echo '== Буквенные строки ==' . PHP_EOL;
$s = 'W';
for (
$n=0; $n<6; $n++) {
echo ++
$s . PHP_EOL;
}
// Буквенно-цифровые строки ведут себя по-разному
echo '== Буквенно-цифровые строки ==' . PHP_EOL;
$d = 'A8';
for (
$n=0; $n<6; $n++) {
echo ++
$d . PHP_EOL;
}
$d = 'A08';
for (
$n=0; $n<6; $n++) {
echo ++
$d . PHP_EOL;
}
?>

Результат выполнения данного примера:

== Буквенные строки ==
X
Y
Z
AA
AB
AC
== Буквенно-цифровые строки ==
A9
B0
B1
B2
B3
B4
A09
A10
A11
A12
A13
A14

Инкрементирование или декрементирование булевых переменных не приводит ни к какому результату.



Логические операторы

Логические операторы
Пример Название Результат
$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.

Смысл двух разных вариантов для операторов "and" и "or" в том, что они работают с различными приоритетами (смотрите таблицу Приоритет выполнения операторов).

Пример #1 Объяснение логических операторов

<?php

// --------------------
// foo() никогда не будет вызвана, т.к. эти операторы являются шунтирующими (short-circuit)

$a = (false && foo());
$b = (true || foo());
$c = (false and foo());
$d = (true or foo());

// --------------------
// "||" имеет больший приоритет, чем "or"

// Результат выражения (false || true) присваивается переменной $e
// Действует как: ($e = (false || true))
$e = false || true;

// Константа false присваивается $f, а затем значение true игнорируется
// Действует как: (($f = false) or true)
$f = false or true;

var_dump($e, $f);

// --------------------
// "&&" имеет больший приоритет, чем "and"

// Результат выражения (true && false) присваивается переменной $g
// Действует как: ($g = (true && false))
$g = true && false;

// Константа true присваивается $h, а затем значение false игнорируется
// Действует как: (($h = true) and false)
$h = true and false;

var_dump($g, $h);
?>

Результатом выполнения данного примера будет что-то подобное:

bool(true)
bool(false)
bool(false)
bool(true)


Строковые операторы

В PHP есть два оператора для работы со строками (string). Первый - оператор конкатенации ('.'), который возвращает строку, представляющую собой соединение левого и правого аргумента. Второй - оператор присваивания с конкатенацией ('.='), который присоединяет правый аргумент к левому. Для получения более полной информации ознакомьтесь с разделом Операторы присваивания.

<?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" => "apple", "b" => "banana");
$b = array("a" => "pear", "b" => "strawberry", "c" => "cherry");

$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; // Объединение $a += $b, это $a и $b
echo "Объединение \$a += \$b: \n";
var_dump($a);
?>
После своего выполнения скрипт напечатает следующее:
Объединение $a и $b:
array(3) {
  ["a"]=>
  string(5) "apple"
  ["b"]=>
  string(6) "banana"
  ["c"]=>
  string(6) "cherry"
}
Объединение $b и $a:
array(3) {
  ["a"]=>
  string(4) "pear"
  ["b"]=>
  string(10) "strawberry"
  ["c"]=>
  string(6) "cherry"
}

Объединение $a += $b:
array(3) {
  ["a"]=>
  string(5) "apple"
  ["b"]=>
  string(6) "banana"
  ["c"]=>
  string(6) "cherry"
}

При сравнении элементы массива считаются идентичными, если совпадает и ключ, и соответствующее ему значение.

Пример #1 Сравнение массивов

<?php
$a
= array("apple", "banana");
$b = array(1 => "banana", "0" => "apple");

var_dump($a == $b); // bool(true)
var_dump($a === $b); // bool(false)
?>



Оператор проверки типа

Оператор instanceof используется для определения того, является ли текущий объект экземпляром указанного класса.

Пример #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 также может быть использован для определения, наследует ли определённый объект какой-либо класс:

Пример #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.

Пример #3 Использование instanceof для проверки того, что объект не является экземпляром класса

<?php
class MyClass
{
}

$a = new MyClass;
var_dump(!($a instanceof stdClass));
?>

Результат выполнения данного примера:

bool(true)

Наконец, instanceof может быть также использован для проверки реализации объектом некоторого интерфейса:

Пример #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 обычно используется с прямо указанным именем класса, он также может быть использован с другим объектом или строковой переменной:

Пример #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)

Оператор instanceof не генерирует никаких ошибок, если проверяемая переменная не является объектом. В этом случае он просто возвращает false. Константы, тем не менее, не допускались до PHP 7.3.0.

Пример #6 Пример использования оператора instanceof для проверки других переменных

<?php
$a
= 1;
$b = NULL;
$c = imagecreate(5, 5);
var_dump($a instanceof stdClass); // $a - целое типа integer
var_dump($b instanceof stdClass); // $b - NULL
var_dump($c instanceof stdClass); // $c - значение типа resource
var_dump(FALSE instanceof stdClass);
?>

Результат выполнения данного примера:

bool(false)
bool(false)
bool(false)
PHP Fatal error:  instanceof expects an object instance, constant given

Начиная с PHP 7.3.0, константы разрешены в левой части оператора instanceof.

Пример #7 Использование instanceof для проверки констант

<?php
var_dump
(FALSE instanceof stdClass);
?>

Результат выполнения данного примера в PHP 7.3:

bool(false)

Начиная с PHP 8.0.0, instanceof теперь можно использовать с произвольными выражениями. Выражение должно быть заключено в круглые скобки и представлять собой строку (string).

Пример #8 Пример использования instanceof с произвольным выражением

<?php

class ClassA extends \stdClass {}
class
ClassB extends \stdClass {}
class
ClassC extends ClassB {}
class
ClassD extends ClassA {}

function
getSomeClass(): string
{
return
ClassA::class;
}

var_dump(new ClassA instanceof ('std' . 'Class'));
var_dump(new ClassB instanceof ('Class' . 'B'));
var_dump(new ClassC instanceof ('Class' . 'A'));
var_dump(new ClassD instanceof (getSomeClass()));
?>

Результат выполнения данного примера в PHP 8:

bool(true)
bool(true)
bool(false)
bool(true)

Оператор instanceof аналогичен функции is_a().

Смотрите также




Управляющие конструкции

Содержание


Введение

Любой сценарий PHP состоит из последовательности инструкций. Инструкцией может быть присваивание, вызов функции, повтор кода (цикл), сравнение, или даже инструкция, которая ничего не делает (пустой оператор). После инструкции обычно ставится точка с запятой. Кроме того, инструкции могут быть объединены в блоки заключением их в фигурные скобки. Блок инструкций также сам по себе является инструкцией. В этом разделе описываются различные типы инструкций.

Смотрите также

Ниже также рассматриваются языковые конструкции, даже если они упоминаются в функциях руководства.



if

(PHP 4, PHP 5, PHP 7, PHP 8)

Конструкция if является одной из наиболее важных во многих языках программирования, в том числе и PHP. Она предоставляет возможность условного выполнения фрагментов кода. Структура if реализована в PHP по аналогии с языком C:

if (выражение)
  инструкция

Как описано в разделе про выражения, выражение вычисляется в булево значение. Если выражение принимает значение true, PHP выполнит инструкцию, а если оно принимает значение 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;
}
?>

Инструкции if могут быть бесконечно вложены в другие инструкции if, что даёт большую гибкость в организации условного выполнения различных частей программы.



else

(PHP 4, PHP 5, PHP 7, PHP 8)

Часто необходимо выполнить одно выражение, если определённое условие верно, и другое выражение, если условие не верно. Именно для этого 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).

Замечание: Болтающийся else

В случае вложенных операторов if-else, else всегда ассоциируется с ближайшим if.

<?php
$a
= false;
$b = true;
if (
$a)
if (
$b)
echo
"b";
else
echo
"c";
?>
Несмотря на отступ (который не имеет значения в PHP), else связан с if ($b), поэтому этот пример ничего не выведет. Хотя такое поведение допустимо, рекомендуется его избегать, используя фигурные скобки для устранения потенциальных неоднозначностей.



elseif/else if

(PHP 4, PHP 5, PHP 7, PHP 8)

Конструкция 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";
}
?>

Может быть несколько elseif в одном выражении if. Первое выражение elseif (если оно есть) равное true будет выполнено. В PHP вы также можете написать else if (в два слова), и тогда поведение будет идентичным elseif' (в одно слово). Синтаксически значение немного отличается (то же поведение, что и у C), но в конечном итоге оба выражения приведут к одному и тому же результату.

Выражение elseif выполнится, если предшествующее выражение if и предшествующие выражения elseif эквивалентны false, а текущий elseif равен true.

Замечание: Заметьте, что elseif и else if будут равнозначны только при использовании фигурных скобок, как в примерах выше. Если используются синтаксис с двоеточием для определения условий if/elseif, возникает необходимость использования 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 4, PHP 5, PHP 7, PHP 8)

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;
?>

Замечание:

Смешивание синтаксиса в одном и том же блоке управления не поддерживается.

Внимание

Любой вывод (включая пробельные символы) между выражением switch и первым case приведут к синтаксической ошибке. Например, данный код не будет работать:

<?php switch ($foo): ?>
<?php case 1: ?>
...
<?php endswitch; ?>

В то же время следующий пример будет работать, так как завершающий перевод строки после выражения switch считается частью закрывающего ?> и следовательно ничего не выводится между switch и case:

<?php switch ($foo): ?>
<?php
case 1: ?>
...
<?php endswitch; ?>

Смотрите также while, for и if для дальнейших примеров.



while

(PHP 4, PHP 5, PHP 7, PHP 8)

Циклы while являются простейшим видом циклов в PHP. Они ведут себя так же, как и в языке C. Простейшей формой цикла while является следующее выражение:

while (expr)
    statement

Смысл выражения while очень прост. Оно указывает PHP выполнять вложенные выражения повторно до тех пор, пока выражение в самом while является true. Значение выражения expr проверяется каждый раз перед началом цикла, поэтому даже если значение выражения изменится в процессе выполнения вложенных выражений в цикле, выполнение не прекратится до конца итерации (каждый раз, когда PHP выполняет выражения в цикле - это одна итерация). Если выражение while равно false с самого начала, вложенные выражения ни разу не будут выполнены.

Также, как и с оператором if, вы можете группировать несколько выражений внутри одного цикла while, заключая эти выражения между фигурными скобками или используя альтернативный синтаксис:

while (expr):
    statement
    ...
endwhile;

Следующие примеры идентичны, и оба выведут числа от 1 до 10:

<?php
/* пример 1 */

$i = 1;
while (
$i <= 10) {
echo
$i++; /* выводиться будет значение переменной
$i перед её увеличением
(post-increment) */
}

/* пример 2 */

$i = 1;
while (
$i <= 10):
echo
$i;
$i++;
endwhile;
?>



do-while

(PHP 4, PHP 5, PHP 7, PHP 8)

Цикл do-while очень похож на цикл while, с тем отличием, что истинность выражения проверяется в конце итерации, а не в начале. Главное отличие от обычного цикла while в том, что первая итерация цикла do-while гарантированно выполнится (истинность выражения проверяется в конце итерации), тогда как она может не выполниться в обычном цикле while (истинность выражения которого проверяется в начале выполнения каждой итерации, и если изначально имеет значение false, то выполнение цикла будет прервано сразу).

Есть только один вариант синтаксиса цикла do-while:

<?php
$i
= 0;
do {
echo
$i;
} while (
$i > 0);
?>

В примере цикл будет выполнен ровно один раз, так как после первой итерации, когда проверяется истинность выражения, она будет вычислена как false ($i не больше 0) и выполнение цикла прекратится.

Опытные пользователи С могут быть знакомы с другим использованием цикла 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);
?>

Можно использовать оператор goto вместо подобного "хака".



for

(PHP 4, PHP 5, PHP 7, PHP 8)

Цикл 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
/*
* Это массив с некоторыми данными, которые мы хотим изменить
* при работе цикла.
*/
$people = array(
array(
'name' => 'Kalle', 'salt' => 856412),
array(
'name' => 'Pierre', 'salt' => 215863)
);

for(
$i = 0; $i < count($people); ++$i) {
$people[$i]['salt'] = mt_rand(000000, 999999);
}
?>

Вышеприведённый код может работать медленно, так как размер массива вычисляется в каждой итерации. Поскольку размер не меняется, цикл может быть легко оптимизирован с помощью промежуточной переменной, в которую будет записан размер массива, вместо повторяющихся вызовов функции count():

<?php
$people
= array(
array(
'name' => 'Kalle', 'salt' => 856412),
array(
'name' => 'Pierre', 'salt' => 215863)
);

for(
$i = 0, $size = count($people); $i < $size; ++$i) {
$people[$i]['salt'] = mt_rand(000000, 999999);
}
?>



foreach

(PHP 4, PHP 5, PHP 7, PHP 8)

Конструкция foreach предоставляет простой способ перебора массивов. foreach работает только с массивами и объектами, и будет генерировать ошибку при попытке использования с переменными других типов или неинициализированными переменными. Существует два вида синтаксиса:

foreach (iterable_expression as $value)
    statement
foreach (iterable_expression as $key => $value)
    statement

Первый цикл перебирает массив, задаваемый с помощью iterable_expression. На каждой итерации значение текущего элемента присваивается переменной $value.

Второй цикл дополнительно присвоит ключ текущего элемента переменной $key на каждой итерации.

Обратите внимание, что foreach не изменяет указатель внутреннего массива, который используется такими функциями, как current() и key().

Возможно настроить итераторы объектов.

Для того, чтобы напрямую изменять элементы массива внутри цикла, переменной $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(). В противном случае вы можете столкнуться с таким поведением:

<?php
$arr
= array(1, 2, 3, 4);
foreach (
$arr as &$value) {
$value = $value * 2;
}
// $arr = array(2, 4, 6, 8)

// Без unset($value), $value всё ещё ссылается на последний элемент: $arr[3]

foreach ($arr as $key => $value) {
// $arr[3] будет перезаписываться значениями $arr при каждой итерации цикла
echo "{$key} => {$value} ";
print_r($arr);
}
// ...И в конце концов предпоследнее значение определит окончательное содержимое $arr[3]

// вывод:
// 0 => 2 Array ( [0] => 2, [1] => 4, [2] => 6, [3] => 2 )
// 1 => 4 Array ( [0] => 2, [1] => 4, [2] => 6, [3] => 4 )
// 2 => 6 Array ( [0] => 2, [1] => 4, [2] => 6, [3] => 6 )
// 3 => 6 Array ( [0] => 2, [1] => 4, [2] => 6, [3] => 6 )
?>

Можно перебирать значение постоянного массива по ссылке:

<?php
foreach (array(1, 2, 3, 4) as &$value) {
$value = $value * 2;
}
?>

Замечание:

Оператор foreach не поддерживает возможность подавления сообщений об ошибках с помощью префикса @.

Ещё несколько примеров, демонстрирующие использование оператора:

<?php
/* Пример 1: только значение */

$a = array(1, 2, 3, 17);

foreach (
$a as $v) {
echo
"Текущее значение переменной \$a: $v.\n";
}

/* Пример 2: значение (для иллюстрации массив выводится в виде значения с ключом) */

$a = array(1, 2, 3, 17);

$i = 0; /* только для пояснения */

foreach ($a as $v) {
echo
"\$a[$i] => $v.\n";
$i++;
}

/* Пример 3: ключ и значение */

$a = array(
"one" => 1,
"two" => 2,
"three" => 3,
"seventeen" => 17
);

foreach (
$a as $k => $v) {
echo
"\$a[$k] => $v.\n";
}

/* Пример 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";
}
}

/* Пример 5: динамические массивы */

foreach (array(1, 2, 3, 4, 5) as $v) {
echo
"$v\n";
}
?>

Распаковка вложенных массивов с помощью list()

(PHP 5 >= 5.5.0, PHP 7, PHP 8)

Можно перебрать массив массивов и распаковать вложенный массив в переменные цикла, передав list() в качестве значения.

Например:

<?php
$array
= [
[
1, 2],
[
3, 4],
];

foreach (
$array as list($a, $b)) {
// $a содержит первый элемент вложенного массива,
// а $b содержит второй элемент.
echo "A: $a; B: $b\n";
}
?>

Результат выполнения данного примера:

A: 1; B: 2
A: 3; B: 4

Можно передавать меньшее количество элементов в list(), чем находится во вложенном массиве, в этом случае оставшиеся значения массива будут проигнорированы:

<?php
$array
= [
[
1, 2],
[
3, 4],
];

foreach (
$array as list($a)) {
// Обратите внимание на отсутствие $b.
echo "$a\n";
}
?>

Результат выполнения данного примера:

1
3

Если массив содержит недостаточно элементов для заполнения всех переменных из list(), то будет сгенерировано замечание об ошибке:

<?php
$array
= [
[
1, 2],
[
3, 4],
];

foreach (
$array as list($a, $b, $c)) {
echo
"A: $a; B: $b; C: $c\n";
}
?>

Результат выполнения данного примера:


Notice: Undefined offset: 2 in example.php on line 7
A: 1; B: 2; C:

Notice: Undefined offset: 2 in example.php on line 7
A: 3; B: 4; C:



break

(PHP 4, PHP 5, PHP 7, PHP 8)

break прерывает выполнение текущей структуры for, foreach, while, do-while или switch.

break принимает необязательный числовой аргумент, который сообщает ему выполнение какого количества вложенных структур необходимо прервать. Значение по умолчанию 1, только ближайшая структура будет прервана.

<?php
$arr
= array('один', 'два', 'три', 'четыре', 'стоп', 'пять');
foreach (
$arr as $val) {
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 4, PHP 5, PHP 7, PHP 8)

continue используется внутри циклических структур для пропуска оставшейся части текущей итерации цикла и, при соблюдении условий, начала следующей итерации.

Замечание: В PHP оператор switch считается циклическим и внутри него может использоваться continue. Если continue не передано аргументов, то он ведёт себя аналогично break, но выдаёт предупреждение о возможной ошибке. Если switch расположен внутри цикла, continue 2 продолжит выполнение внешнего цикла со следующей итерации.

continue принимает необязательный числовой аргумент, который указывает на скольких уровнях вложенных циклов будет пропущена оставшаяся часть итерации. Значением по умолчанию является 1, при которой пропускается оставшаяся часть текущего цикла.

<?php
$arr
= ['ноль', 'один', 'два', 'три', 'четыре', 'пять', 'шесть'];
foreach (
$arr as $key => $value) {
if (
0 === ($key % 2)) { // пропуск чётных чисел
continue;
}
echo
$value . "\n";
}
?>

Результат выполнения данных примеров:

один
три
пять
<?php
$i
= 0;
while (
$i++ < 5) {
echo
"Внешний\n";
while (
1) {
echo
"Средний\n";
while (
1) {
echo
"Внутренний\n";
continue
3;
}
echo
"Это никогда не выведется.\n";
}
echo
"Это также не выведется.\n";
}
?>

Результат выполнения данных примеров:

Внешний
Средний
Внутренний
Внешний
Средний
Внутренний
Внешний
Средний
Внутренний
Внешний
Средний
Внутренний
Внешний
Средний
Внутренний

Пропуск точки запятой после continue может привести к путанице. Пример как не надо делать.

<?php
for ($i = 0; $i < 5; ++$i) {
if (
$i == 2)
continue
print
"$i\n";
}
?>

Ожидается, что результат будет такой:

0
1
3
4

Изменения, касающиеся оператора continue
Версия Описание
7.3.0 continue внутри switch, использующееся как замена break для switch будет вызывать ошибку уровня E_WARNING.



switch

(PHP 4, PHP 5, PHP 7, PHP 8)

Оператор switch похож на ряд операторов IF с одинаковым условием. Во многих случаях вам может понадобиться сравнивать одну и ту же переменную (или выражение) с множеством различных значений и выполнять различные участки кода в зависимости от того, какое значение принимает эта переменная (или выражение). Это именно тот случай, для которого удобен оператор switch.

Замечание: Обратите внимание, что в отличие от некоторых других языков, оператор continue применяется в конструкциях switch и действует подобно оператору break. Если у вас конструкция switch находится внутри цикла, и вам необходимо перейти к следующей итерации цикла, используйте continue 2.

Замечание:

Заметьте, что конструкция switch/case использует нестрогое сравнение (==).

В следующем примере каждый блок кода эквивалентен. В одном используется серия операторов if и elseif, а в другом - оператор switch. В каждом случае результат один и тот же.

Пример #1 Оператор switch

<?php
// Оператор switch:

switch ($i) {
case
0:
echo
"i равно 0";
break;
case
1:
echo
"i равно 1";
break;
case
2:
echo
"i равно 2";
break;
}

// Эквивалентно:

if ($i == 0) {
echo
"i равно 0";
} elseif (
$i == 1) {
echo
"i равно 1";
} elseif (
$i == 2) {
echo
"i равно 2";
}
?>

Пример #2 Оператор switch допускает сравнение с типом string

<?php
switch ($i) {
case
"яблоко":
echo
"i это яблоко";
break;
case
"шоколадка":
echo
"i это шоколадка";
break;
case
"пирог":
echo
"i это пирог";
break;
}
?>

Важно понять, как оператор switch выполняется, чтобы избежать ошибок. Оператор switch исполняет строчка за строчкой (на самом деле выражение за выражением). В начале никакой код не исполняется. Только в случае нахождения оператора case, значение которого совпадает со значением выражения в операторе switch, PHP начинает исполнять операторы. PHP продолжает исполнять операторы до конца блока switch либо до тех пор, пока не встретит оператор break. Если вы не напишете оператор break в конце секции case, PHP будет продолжать исполнять команды следующей секции case. Например :

<?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 также может быть пустым, что просто передаёт управление списку операторов в следующей секции case.

<?php
switch ($i) {
case
0:
case
1:
case
2:
echo
"i меньше чем 3, но неотрицательный";
break;
case
3:
echo
"i равно 3";
}
?>

Специальный вид конструкции case - default. Сюда управление попадает тогда, когда не сработал ни один из других операторов case. Например:

<?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";
}
?>

Замечание: Несколько указаний default вызовут ошибку E_COMPILE_ERROR.

Замечание: Формально конструкция default может быть перечислена в любом месте. Она будет использоваться только в том случае, если ни один другой вариант не подходит. Однако, по соглашению, лучше всего поместить её в конец, как последнюю конструкцию.

Если ни одна конструкция case не совпадает и нет конструкции default, то код не будет выполнен, как если бы ни одно утверждение if не было истинным.

Значение case может быть задано в виде выражения. Однако это выражение будет оценено само по себе, а затем слабо сопоставлено со значением switch. Это означает, что его нельзя использовать для сложных оценок значения switch. Например:

<?php
$target
= 1;
$start = 3;

switch (
$target) {
case
$start - 1:
print
"A";
break;
case
$start - 2:
print
"B";
break;
case
$start - 3:
print
"C";
break;
case
$start - 4:
print
"D";
break;
}

// Выведет "B"
?>

Для более сложных сравнений в качестве значения switch может использоваться значение true. Или, как вариант, вместо switch использовать блоки if-else.

<?php
$offset
= 1;
$start = 3;

switch (
true) {
case
$start - $offset === 1:
print
"A";
break;
case
$start - $offset === 2:
print
"B";
break;
case
$start - $offset === 3:
print
"C";
break;
case
$start - $offset === 4:
print
"D";
break;
}

// Выведет "B"
?>

Возможен альтернативный синтаксис для управляющей структуры 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
'tuborg';
case
'carlsberg';
case
'stella';
case
'heineken';
echo
'Хороший выбор';
break;
default;
echo
'Пожалуйста, сделайте новый выбор...';
break;
}
?>

Смотрите также



match

(PHP 8)

Выражение match предназначено для ветвления потока исполнения на основании проверки совпадения значения с заданным условием. Аналогично оператору switch, выражение match принимает на вход выражение, которое сравнивается с множеством альтернатив. Но, в отличие от switch, оно обрабатывает значение в стиле, больше похожем на тернарный оператор. Также, в отличие от switch, используется строгое сравнение (===), а не слабое (==). Выражение match доступно начиная с PHP 8.0.0.

Пример #1 Структура выражения match

<?php
$return_value
= match (subject_expression) {
single_conditional_expression => return_expression,
conditional_expression1, conditional_expression2 => return_expression,
};
?>

Пример #2 Простой пример использования match

<?php
$food
= 'cake';
$return_value = match ($food) {
'apple' => 'На столе лежит яблоко',
'banana' => 'На столе лежит банан',
'cake' => 'На столе стоит торт',
};
var_dump($return_value);
?>

Результат выполнения данного примера:

string(35) "На столе стоит торт"

Замечание: Результат match использовать не обязательно.

Замечание: Выражение match должно завершаться точкой с запятой ;.

Выражение match похоже на оператор switch за исключением некоторых ключевых отличий:

  • В отличие от switch, в match используется строгое сравнение (===).
  • Выражение match возвращает результат.
  • В match исполняется только одна, первая подошедшая, ветвь кода, тогда как в switch происходит сквозное исполнение начиная с подошедшего условия и до первого встретившегося оператора break.
  • Выражение match должно быть исчерпывающим.

Также как и оператор switch, match последовательно проводит проверки на совпадение с заданными условиями. Выполнение кода условий происходит лениво, т.е. код следующего условия выполняется только если все предыдущие проверки провалились. Будет выполнена только одна ветвь кода, соответствующая подошедшему условию. Пример:

<?php
$result
= match ($x) {
foo() => ...,
$this->bar() => ..., // $this->bar() не будет выполнен, если foo() === $x
$this->baz => beep(), // beep() будет выполнен только если $x === $this->baz
// etc.
};
?>

Условия в match могут быть множественными. В этом случае их следует разделять запятыми. Множественные условия работают по принципу логического ИЛИ и, по сути, являются сокращённой формой для случаев, когда несколько условий должны обрабатываться идентично.

<?php
$result
= match ($x) {
// Множественное условие:
$a, $b, $c => 5,
// Аналогично трём одиночным:
$a => 5,
$b => 5,
$c => 5,
};
?>

Также можно использовать шаблон default. Этот шаблон совпадает с чем угодно, для чего не нашлось совпадений раньше. К примеру:

<?php
$expressionResult
= match ($condition) {
1, 2 => foo(),
3, 4 => bar(),
default =>
baz(),
};
?>

Замечание: Использование нескольких шаблонов default приведёт к фатальной ошибке E_FATAL_ERROR.

Выражение match должно быть исчерпывающим. Если проверяемое выражение не совпало ни с одним из условий, то будет выброшено исключение UnhandledMatchError.

Пример #3 Пример необработанного выражения

<?php
$condition
= 5;

try {
match ($condition) {
1, 2 => foo(),
3, 4 => bar(),
};
} catch (\
UnhandledMatchError $e) {
var_dump($e);
}
?>

Результат выполнения данного примера:

object(UnhandledMatchError)#1 (7) {
  ["message":protected]=>
  string(33) "Unhandled match value of type int"
  ["string":"Error":private]=>
  string(0) ""
  ["code":protected]=>
  int(0)
  ["file":protected]=>
  string(9) "/in/ICgGK"
  ["line":protected]=>
  int(6)
  ["trace":"Error":private]=>
  array(0) {
  }
  ["previous":"Error":private]=>
  NULL
}

Использование match для проверки сложных условий

Выражение match можно использовать не только для проверки идентичности, но и для любых выражений, возвращающих логическое значение. В этом случае в качестве входного параметра передаётся выражение true.

Пример #4 Использование match для ветвления в зависимости от вхождения в диапазоны целых чисел

<?php

$age
= 23;

$result = match (true) {
$age >= 65 => 'пожилой',
$age >= 25 => 'взрослый',
$age >= 18 => 'совершеннолетний',
default =>
'ребёнок',
};

var_dump($result);
?>

Результат выполнения данного примера:

string(11) "совершеннолетний"

Пример #5 Использование match для ветвления в зависимости от содержимого строки

<?php

$text
= 'Bienvenue chez nous';

$result = match (true) {
str_contains($text, 'Welcome') || str_contains($text, 'Hello') => 'en',
str_contains($text, 'Bienvenue') || str_contains($text, 'Bonjour') => 'fr',
// ...
};

var_dump($result);
?>

Результат выполнения данного примера:

string(2) "fr"


declare

(PHP 4, PHP 5, PHP 7, PHP 8)

Конструкция declare используется для установки директив исполнения для блока кода. Синтаксис declare аналогичен с синтаксисом других конструкций управления выполнением:

declare (directive)
    statement

Секция directive позволяет установить поведение блока declare. В настоящее время распознаются только три директивы: директива ticks (Дополнительная информация о директиве ticks доступна ниже), директива encoding (Дополнительная информация о директиве encoding доступна ниже) и директива strict_types (подробности в разделе про строгую типизацию на странице аргументов функции)

Поскольку директивы обрабатываются при компиляции файла, то только символьные данные могут использоваться как значения директивы. Нельзя использовать переменные и константы. Пример:

<?php
// Правильно:
declare(ticks=1);

// Недопустимо:
const TICK_VALUE = 1;
declare(
ticks=TICK_VALUE);
?>

Часть statement блока declare будет выполнена - как выполняется и какие побочные эффекты возникают во время выполнения, может зависеть от директивы, которая установлена в блоке directive.

Конструкция declare также может быть использована в глобальной области видимости, влияя на весь следующий за ней код (однако если файл с declare был включён, то она не будет действовать на родительский файл).

<?php
// это то же самое:

// можно так:
declare(ticks=1) {
// прочие действия
}

// или так:
declare(ticks=1);
// прочие действия
?>

Тики

Тик - это событие, которое случается каждые N низкоуровневых операций, выполненных парсером внутри блока declare. Значение N задаётся, используя ticks=N внутри секции directive блока declare.

Не все выражения подсчитываются. Обычно, условные выражения и выражения аргументов не подсчитываются.

Событие (или несколько событий), которое возникает на каждом тике определяется, используя register_tick_function(). Смотрите пример ниже для дополнительной информации. Имейте в виду, что для одного тика может возникать несколько событий.

Пример #1 Пример использования тика

<?php

declare(ticks=1);

// Функция, исполняемая при каждом тике
function tick_handler()
{
echo
"Вызывается tick_handler()\n";
}

register_tick_function('tick_handler'); // вызывает событие тика

$a = 1; // вызывает событие тика

if ($a > 0) {
$a += 2; // вызывает событие тика
print($a); // вызывает событие тика
}

?>

Смотрите также register_tick_function() и unregister_tick_function().

Кодировка

Кодировка скрипта может быть указана для каждого скрипта, используя директиву encoding.

Пример #2 Определение кодировки для скрипта.

<?php
declare(encoding='ISO-8859-1');
// прочий код
?>

Предостережение

В сочетании с пространством имён единственно допустимый синтаксис для declare является declare(encoding='...'); где ... это значение кодировки. declare(encoding='...') {} приведёт к ошибке парсера, если используется вместе с пространством имён.

Смотрите также zend.script_encoding.



return

(PHP 4, PHP 5, PHP 7, PHP 8)

return возвращает управление программой модулю, из которого была вызвана функция. Выполнение программы продолжается с инструкции, следующей за местом вызова.

Если вызывается из функции, выражение return немедленно прекращает выполнение текущей функции и возвращает свой аргумент как значение данной функции. return также завершит выполнение выражения eval() или всего файла скрипта.

Если вызывается из глобальной области видимости, выполнение текущего файла скрипта прекращается. Если текущий файл скрипта был подключён с помощью функций include или require, тогда управление возвращается к файлу, который вызывал текущий. Более того, если текущий файл скрипта был подключён с помощью include, тогда значение переданное return будет возвращено в качестве значения вызова include. Если return вызывается из главного файла скрипта, тогда выполнение скрипта прекращается. Если текущий файл скрипта был вызван конфигурационными опциями auto_prepend_file или auto_append_file из файла настроек php.ini, тогда выполнение этого скрипта прекращается.

Для более детальной информации смотрите раздел Возвращаемые значения.

Замечание: Заметьте, что return является языковой конструкцией, а не функцией и круглые скобки, окружающие аргументы, не являются необходимостью. Мало того, они тут не приветствуются.

Замечание: Если параметры не указаны, тогда круглые скобки должны быть опущены и будет возвращён null. Вызов return со скобками, но без аргументов вызовет синтаксическую ошибку.

Начиная с PHP 7.1.0, операторы возврата без аргумента в функциях, объявляющих тип возврата, вызывают E_COMPILE_ERROR, если только тип возврата не void, в этом случае такую же ошибку вызывают операторы возврата с аргументом.



require

(PHP 4, PHP 5, PHP 7, PHP 8)

require аналогично include, за исключением того, что в случае возникновения ошибки он также выдаст фатальную ошибку уровня E_COMPILE_ERROR. Другими словами, он остановит выполнение скрипта, тогда как include только выдал бы предупреждение E_WARNING, которое позволило бы скрипту продолжить выполнение.

Смотрите документацию по include, чтобы узнать как он работает.



include

(PHP 4, PHP 5, PHP 7, PHP 8)

Выражение include включает и выполняет указанный файл.

Документация ниже также относится к выражению require.

Файлы включаются исходя из пути указанного файла, или, если путь не указан, используется путь, указанный в директиве include_path. Если файл не найден в include_path, include попытается проверить директорию, в которой находится текущий включающий скрипт и текущую рабочую директорию перед тем, как выдать ошибку. Конструкция include выдаст E_WARNING, если не сможет найти файл; поведение отлично от require, который выдаст E_ERROR.

Обратите внимание, что и include и require выдают дополнительную ошибку уровня E_WARNING, если к файлу невозможно получить доступ, перед тем, как выдать последнюю ошибку уровня E_WARNING или E_ERROR соответственно.

Если путь указан — абсолютный (начинающийся с буквы диска или с \ в Windows или с / в Unix/Linux системах) или относительно текущей директории (начинающийся с . или ..) — include_path будет проигнорирован вообще. Например, если имя файла начинается с ../, парсер будет искать в родительской директории запрошенный файл.

Для дополнительной информации о том, как PHP обрабатывает включаемые файлы и включаемые пути, смотрите документацию для директивы include_path.

Когда файл включается, его код наследует ту же область видимости переменных, что и строка, на которой произошло включение. Все переменные, доступные на этой строке во включающем файле, будут также доступны во включаемом файле. Однако все функции и классы, объявленные во включаемом файле, имеют глобальную область видимости.

Пример #1 Простой пример include

vars.php
<?php

$color
= 'зелёное';
$fruit = 'яблоко';

?>

test.php
<?php

echo "Одно $color $fruit"; // Одно

include 'vars.php';

echo
"Одно $color $fruit"; // Одно зелёное яблоко

?>

Если включение происходит внутри функции включающего файла, тогда весь код, содержащийся во включаемом файле, будет вести себя так, как будто он был определён внутри этой функции. То есть, он будет в той же области видимости переменных этой функции. Исключением к этому правилу являются магические константы, которые выполняются парсером перед тем, как происходит включение.

Пример #2 Включение внутри функции

<?php

function foo()
{
global
$color;

include
'vars.php';

echo
"Одно $color $fruit";
}

/* vars.php в той же области видимости, что и foo(), *
* поэтому $fruit НЕ будет доступен за пределами этой области *
* $color доступен, поскольку мы объявили переменную глобальной */

foo(); // Одно зелёное яблоко
echo "Одно $color $fruit"; // Одно зелёное

?>

Когда файл включается, парсинг в режиме PHP-кода прекращается и переключается в режим HTML в начале указанного файла и продолжается снова в конце. По этой причине любой код внутри включаемого файла, который должен быть выполнен как код PHP, должен быть заключён в корректные теги начала и конца PHP-кода.

Если "обёртки URL include" включены в PHP, вы можете также указать файл для включения через URL (с помощью HTTP или других поддерживающихся обработчиков - смотрите Поддерживаемые протоколы и обёртки для списка протоколов) вместо локального пути. Если целевой сервер интерпретирует указанный файл как код PHP, переменные могут быть переданы во включаемый файл с помощью строки URL-запроса при использовании HTTP GET. Это совсем не то же самое, что включение файла и наследование родительской области видимости; скрипт выполняется на удалённом сервере, и результат затем включается в локальный скрипт.

Пример #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';
?>

Внимание

Предупреждение безопасности

Удалённые файлы могут быть обработаны на удалённой стороне (в зависимости от расширения файла и того, что удалённый сервер выполняет скрипты PHP или нет), но это всё равно должно производить корректный скрипт PHP, потому что он будет затем обработан уже на локальном сервере. Если файл с удалённого сервера должен быть обработан и только отображён его результат, гораздо эффективно воспользоваться функцией readfile() В противном случае следует соблюдать особую осторожность, чтобы обезопасить удалённый скрипт для получения корректного и желаемого кода.

Смотрите также раздел Удалённые файлы, функции fopen() и file() для дополнительной информации.

Обработка возвращаемых значений: оператор include возвращает значение FALSE в случае возникновения ошибки и выдаёт предупреждение. Успешные включения, пока это не переопределено во включаемом файле, возвращают значение 1. Возможно выполнить выражение return внутри включаемого файла, чтобы завершить процесс выполнения в этом файле и вернуться к выполнению включающего файла. Кроме того, возможно вернуть значение из включаемых файлов. Вы можете получить значение включения, как если бы вы вызвали обычную функцию. Хотя это невозможно при включении удалённого файла, только если вывод удалённого файла не содержит корректные теги начала и конца PHP кода (так же, как и локальный файл). Вы можете определить необходимые переменные внутри этих тегов и они будут представлены в зависимости от того, какой файл был выключен.

Так как include - это специальная языковая конструкция, круглые скобки не обязательны вокруг аргумента. Будьте внимательны при сравнении возвращаемого значения.

Пример #4 Сравнение возвращаемого значения при include

<?php
// не сработает, интерпретируется как include(('vars.php') == TRUE), то есть include('1')
if (include('vars.php') == TRUE) {
echo
'OK';
}

// сработает
if ((include 'vars.php') == TRUE) {
echo
'OK';
}
?>

Пример #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 выдаст фатальную ошибку, потому что функции уже были определены. Рекомендуется использовать include_once вместо того, чтобы проверять был ли файл уже включён.

Другой путь "включить" PHP-файл в переменную - это захватить вывод с помощью функций контроля вывода вместе с include. Например:

Пример #6 Использование буферизации вывода для включения файла PHP в строку

<?php
$string
= get_include_contents('somefile.php');

function
get_include_contents($filename) {
if (
is_file($filename)) {
ob_start();
include
$filename;
return
ob_get_clean();
}
return
false;
}

?>

Для того, чтобы включать файлы автоматически в скрипты, обратите внимание на конфигурационные директивы auto_prepend_file и auto_append_file в php.ini.

Замечание: Поскольку это языковая конструкция, а не функция, она не может вызываться при помощи переменных функций или именованных аргументов.

Смотрите также require, require_once, include_once, get_included_files(), readfile(), virtual() и include_path.



require_once

(PHP 4, PHP 5, PHP 7, PHP 8)

Выражение require_once аналогично require за исключением того, что PHP проверит, включался ли уже данный файл, и если да, не будет включать его ещё раз.

Смотрите документацию include_once для информации по поведению _once и чем он отличается от таких же функций, без _once.



include_once

(PHP 4, PHP 5, PHP 7, PHP 8)

Выражение include_once включает и выполняет указанный файл во время выполнения скрипта. Его поведение идентично выражению include, с той лишь разницей, что если код из файла уже один раз был включён, он не будет включён и выполнен повторно и вернёт true. Как видно из имени, он включит файл только один раз.

include_once может использоваться в тех случаях, когда один и тот же файл может быть включён и выполнен более одного раза во время выполнения скрипта, в данном случае это поможет избежать проблем с переопределением функций, переменных и т.д.

Смотрите документацию по include для получения информации о том, как эта функция работает.



goto

(PHP 5 >= 5.3.0, PHP 7, PHP 8)

Что наихудшее может случиться, если используется goto?
Изображение предоставлено » xkcd

Оператор goto используется для перехода в другую часть программы. Место, куда необходимо перейти указывается с помощью чувствительный к регистру метки, за которой ставится двоеточие, после оператора goto указывается желаемая метка для перехода. Оператор не является неограниченным "goto". Целевая метка должна находиться в том же файле, в том же контексте. Имеется в виду, что вы не можете ни перейти за границы функции или метода, ни перейти внутрь одной из них. Вы также не можете перейти внутрь любой циклической структуры или оператора switch. Но вы можете выйти из них, и обычным применением оператора goto является использование его вместо многоуровневых break.

Пример #1 Пример использования goto

<?php
goto a;
echo
'Foo';

a:
echo
'Bar';
?>

Результат выполнения данного примера:

Bar

Пример #2 Пример использования goto в цикле

<?php
for($i=0,$j=50; $i<100; $i++) {
while(
$j--) {
if(
$j==17) goto end;
}
}
echo
"i = $i";
end:
echo
'j hit 17';
?>

Результат выполнения данного примера:

j hit 17

Пример #3 Это не сработает

<?php
goto loop;
for(
$i=0,$j=50; $i<100; $i++) {
while(
$j--) {
loop:
}
}
echo
"$i = $i";
?>

Результат выполнения данного примера:

Fatal error: 'goto' into loop or switch statement is disallowed in
script on line 2




Функции

Содержание


Функции, определяемые пользователем

Приведём пример синтаксиса, используемого для описания функций:

Пример #1 Псевдокод для демонстрации использования функций

<?php
function foo($arg_1, $arg_2, /* ..., */ $arg_n)
{
echo
"Пример функции.\n";
return
$retval;
}
?>

Внутри функции можно использовать любой корректный PHP-код, в том числе другие функции и даже объявления классов.

Имена функций следуют тем же правилам, что и другие метки в PHP. Корректное имя функции начинается с буквы или знака подчёркивания, за которым следует любое количество букв, цифр или знаков подчёркивания. В качестве регулярного выражения оно может быть выражено так: ^[a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*$.

Подсказка

Смотрите также Руководство по именованию.

Функции не обязаны быть определены до их использования, исключая тот случай, когда функции определяются условно, как это показано в двух последующих примерах.

В случае, когда функция определяется в зависимости от какого-либо условия, например, как это показано в двух приведённых ниже примерах, обработка описания функции должна предшествовать её вызову.

Пример #2 Функции, зависящие от условий

<?php

$makefoo
= true;

/* Мы не можем вызвать функцию foo() в этом месте,
поскольку она ещё не определена, но мы можем
обратиться к bar() */

bar();

if (
$makefoo) {
function
foo()
{
echo
"Я не существую до тех пор, пока выполнение программы меня не достигнет.\n";
}
}

/* Теперь мы благополучно можем вызывать foo(),
поскольку $makefoo была интерпретирована как true */

if ($makefoo) foo();

function
bar()
{
echo
"Я существую сразу с начала старта программы.\n";
}

?>

Пример #3 Вложенные функции

<?php
function foo()
{
function
bar()
{
echo
"Я не существую пока не будет вызвана foo().\n";
}
}

/* Мы пока не можем обратиться к bar(),
поскольку она ещё не определена. */

foo();

/* Теперь мы можем вызвать функцию bar(),
обработка foo() сделала её доступной. */

bar();

?>

Все функции и классы PHP имеют глобальную область видимости - они могут быть вызваны вне функции, даже если были определены внутри и наоборот.

PHP не поддерживает перегрузку функции, также отсутствует возможность переопределить или удалить объявленную ранее функцию.

Замечание: Имена функций регистронезависимы для символов ASCII от A до Z, тем не менее, предпочтительнее вызывать функции так, как они были объявлены.

Функции PHP поддерживают как списки аргументов переменной длины, так и значения аргументов по умолчанию. Смотрите также описания функций func_num_args(), func_get_arg() и func_get_args() для более детальной информации.

Можно вызывать функции PHP рекурсивно.

Пример #4 Рекурсивные функции

<?php
function recursion($a)
{
if (
$a < 20) {
echo
"$a\n";
recursion($a + 1);
}
}
?>

Замечание: Рекурсивный вызов методов/процедур с глубиной более 100-200 уровней рекурсии может вызвать переполнение стека и привести к аварийному завершению скрипта. В частности, бесконечная рекурсия будет считаться программной ошибкой.



Аргументы функции

Функция может принимать информацию в виде списка аргументов, который является списком разделённых запятыми выражений. Аргументы вычисляются слева направо перед фактическим вызовом функции (энергичное вычисление).

PHP поддерживает передачу аргументов по значению (по умолчанию), передачу аргументов по ссылке, и значения по умолчанию. Списки аргументов переменной длины и именованные аргументы также поддерживаются.

Пример #1 Передача массива в функцию

<?php
function takes_array($input)
{
echo
"$input[0] + $input[1] = ", $input[0]+$input[1];
}
?>

Начиная с PHP 8.0.0, список аргументов функции может содержать завершающую запятую, которая будет проигнорирована. Это полезно в случае, когда список аргументов очень длинный, либо если имена переменных длинны, что подталкивает к их вертикальному расположению.

Пример #2 Список аргументов функции с завершающей запятой

<?php
function takes_many_args(
$first_arg,
$second_arg,
$a_very_long_argument_name,
$arg_with_default = 5,
$again = 'a default string', // Эта завершающая запятая допустима только начиная с 8.0.0.
)
{
// ...
}
?>

Передача аргументов по ссылке

По умолчанию аргументы в функцию передаются по значению (это означает, что если вы измените значение аргумента внутри функции, то вне её значение всё равно останется прежним). Если вы хотите разрешить функции модифицировать свои аргументы, вы должны передавать их по ссылке.

Если вы хотите, чтобы аргумент всегда передавался по ссылке, вы можете указать амперсанд (&) перед именем аргумента в описании функции:

Пример #3 Передача аргументов по ссылке

<?php
function add_some_extra(&$string)
{
$string .= 'и кое-что ещё.';
}
$str = 'Это строка, ';
add_some_extra($str);
echo
$str; // выведет 'Это строка, и кое-что ещё.'
?>

Передача значения в качестве аргумента, которое должно передаваться по ссылке, является ошибкой.

Значения аргументов по умолчанию

Функция может определять значения по умолчанию для аргументов, используя синтаксис, подобный присвоению переменной. Значение по умолчанию используется только в том случае, если параметр не указан; в частности, обратите внимание, что передача null не присваивает значение по умолчанию.

Пример #4 Использование значений по умолчанию в определении функции

<?php
function makecoffee($type = "капучино")
{
return
"Готовим чашку $type.\n";
}
echo
makecoffee();
echo
makecoffee(null);
echo
makecoffee("эспрессо");
?>

Результат выполнения данного примера:

Готовим чашку капучино.
Готовим чашку .
Готовим чашку эспрессо.

Значениями параметров по умолчанию могут быть скалярные значения, массивы (array), специальный тип null, и, начиная с версии PHP 8.1.0, объекты, использующие синтаксис new ClassName().

Пример #5 Использование нескалярных типов в качестве значений по умолчанию

<?php
function makecoffee($types = array("капучино"), $coffeeMaker = NULL)
{
$device = is_null($coffeeMaker) ? "вручную" : $coffeeMaker;
return
"Готовлю чашку ".join(", ", $types)." $device.\n";
}
echo
makecoffee();
echo
makecoffee(array("капучино", "лавацца"), "в чайнике");
?>

Пример #6 Использование объектов в качестве значений по умолчанию (начиная с PHP 8.1.0)

<?php
class DefaultCoffeeMaker {
public function
brew() {
return
'Приготовление кофе.';
}
}
class
FancyCoffeeMaker {
public function
brew() {
return
'Приготовление прекрасного кофе специально для вас.';
}
}
function
makecoffee($coffeeMaker = new DefaultCoffeeMaker)
{
return
$coffeeMaker->brew();
}
echo
makecoffee();
echo
makecoffee(new FancyCoffeeMaker);
?>

Значение по умолчанию должно быть константным выражением, а не (к примеру) переменной или вызовом функции/метода класса.

Обратите внимание, что любые необязательные аргументы должны быть указаны после любых обязательных аргументов, иначе они не могут быть опущены при вызове. Рассмотрим следующий пример:

Пример #7 Некорректное использование значений по умолчанию

<?php
function makeyogurt($container = "миску", $flavour)
{
return
"Делаем $container с $flavour йогуртом.\n";
}

echo
makeyogurt("малиновым"); // "малиновым" - это $container, не $flavour
?>

Результат выполнения данного примера:

Fatal error: Uncaught ArgumentCountError: Too few arguments
to function makeyogurt(), 1 passed in example.php on line 42

Теперь сравним его со следующим примером:

Пример #8 Корректное использование значений по умолчанию

<?php
function makeyogurt($flavour, $container = "миску")
{
return
"Делаем $container с $flavour йогуртом.\n";
}

echo
makeyogurt("малиновым"); // "малиновым" - это $flavour
?>

Результат выполнения данного примера:

Делаем миску с малиновым йогуртом.

Начиная с PHP 8.0.0, именованные аргументы можно использовать для пропуска нескольких необязательных параметров.

Пример #9 Правильное использование аргументов функций по умолчанию

<?php
function makeyogurt($container = "миску", $flavour = "малиновым", $style = "греческим")
{
return
"Делаем $container с $flavour $style йогуртом.\n";
}
echo
makeyogurt(style: "натуральным");
?>

Результат выполнения данного примера:

Делаем миску с малиновым натуральным йогуртом.

Начиная с PHP 8.0.0, объявление обязательных аргументов после необязательных аргументов является устаревшим. Обычно это можно решить отказавшись от значения по умолчанию, поскольку оно никогда не будет использоваться. Исключением из этого правила являются аргументы вида Type $param = null, где null по умолчанию делает тип неявно обнуляемым. Такое использование остаётся допустимым, хотя рекомендуется использовать явный тип nullable.

Пример #10 Объявление необязательных аргументов после обязательных аргументов

<?php
function foo($a = [], $b) {} // По умолчанию не используется; устарел, начиная с версии PHP 8.0.0
function foo($a, $b) {} // Функционально эквивалентны, без уведомления об устаревании
function bar(A $a = null, $b) {} // Все еще разрешено; $a является обязательным, но допускающим значение null
function bar(?A $a, $b) {} // Рекомендуется
?>

Замечание: Начиная с PHP 7.1.0, опущение параметра, не заданного по умолчанию, выбрасывает исключение ArgumentCountError; в предыдущих версиях это вызывало предупреждение.

Замечание: Значения по умолчанию могут быть переданы по ссылке.

Списки аргументов переменной длины

PHP поддерживает списки аргументов переменной длины для функций, определяемых пользователем с помощью добавления многоточия (...).

Замечание: Также можно добиться аргументов переменной длины, используя функции func_num_args(), func_get_arg() и func_get_args(). Этот метод не рекомендуется, поскольку он использовался до введения многоточия (...).

Список аргументов может содержать многоточие (...), чтобы показать, что функция принимает переменное количество аргументов. Аргументы в этом случае будут переданы в виде массива:

Пример #11 Использование ... для доступа к аргументам

<?php
function sum(...$numbers) {
$acc = 0;
foreach (
$numbers as $n) {
$acc += $n;
}
return
$acc;
}

echo
sum(1, 2, 3, 4);
?>

Результат выполнения данного примера:

10

Многоточие (...) можно использовать при вызове функции, чтобы распаковать массив (array) или Traversable переменную в список аргументов:

Пример #12 Использование ... для передачи аргументов

<?php
function add($a, $b) {
return
$a + $b;
}

echo
add(...[1, 2])."\n";

$a = [1, 2];
echo
add(...$a);
?>

Результат выполнения данного примера:

3
3

Можно задать несколько аргументов в привычном виде, а затем добавить .... В этом случае ... поместит в массив только те аргументы, которые не нашли соответствия указанным в объявлении функции.

Также можно добавить объявление типа перед .... В этом случае все аргументы, обработанные многоточием (...), должны соответствовать этому типу параметра.

Пример #13 Аргументы с подсказкой типа

<?php
function total_intervals($unit, DateInterval ...$intervals) {
$time = 0;
foreach (
$intervals as $interval) {
$time += $interval->$unit;
}
return
$time;
}

$a = new DateInterval('P1D');
$b = new DateInterval('P2D');
echo
total_intervals('d', $a, $b).' days';

// Это не сработает, т.к. null не является объектом DateInterval.
echo total_intervals('d', null);
?>

Результат выполнения данного примера:

3 days
Catchable fatal error: Argument 2 passed to total_intervals() must be an instance of DateInterval, null given, called in - on line 14 and defined in - on line 2

В конце концов, можно передавать аргументы по ссылке. Для этого перед ... нужно поставить амперсанд (&).

Предыдущие версии PHP

Для указания того, что функция принимает переменное число аргументов, никакой специальный синтаксис не используется. Для доступа к аргументам необходимо использовать функции func_num_args(), func_get_arg() и func_get_args().

В первом примере выше было показано, как задать список аргументов переменной длины для предыдущих версий PHP:

Пример #14 Доступ к аргументам в предыдущих версиях PHP

<?php
function sum() {
$acc = 0;
foreach (
func_get_args() as $n) {
$acc += $n;
}
return
$acc;
}

echo
sum(1, 2, 3, 4);
?>

Результат выполнения данного примера:

10

Именованные аргументы

В PHP 8.0.0 в виде продолжения позиционных параметров появились именованные аргументы. С их помощью аргументы функции можно передавать по имени параметра, а не по его позиции. Таким образом аргумент становится самодокументированным, независимым от порядка и указанного значения по умолчанию.

Именованные аргументы передаются путём добавления через двоеточия имени параметра перед его значением. В качестве имён параметров можно использовать зарезервированные ключевые слова. Имя параметра должно быть идентификатором, т.е. он не может быть создан динамически.

Пример #15 Синтаксис именованного аргумента

<?php
myFunction
(paramName: $value);
array_foobar(array: $value);

// НЕ поддерживается.
function_name($variableStoringParamName: $value);
?>

Пример #16 Позиционные аргументы в сравнении с именованными аргументами

<?php
// Использование позиционных аргументов:
array_fill(0, 100, 50);

// Использование именованных аргументов:
array_fill(start_index: 0, count: 100, value: 50);
?>

Порядок, в котором передаются именованные аргументы, не имеет значения.

Пример #17 Тот же пример, что и выше, но с другим порядком параметров

<?php
array_fill
(value: 50, count: 100, start_index: 0);
?>

Именованные аргументы можно комбинировать с позиционными. В этом случае именованные аргументы должны следовать после позиционных аргументов. Также возможно передать только часть необязательных аргументов функции, независимо от их порядка.

Пример #18 Объединение именованных аргументов с позиционными аргументами

<?php
htmlspecialchars
($string, double_encode: false);
// То же самое
htmlspecialchars($string, ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401, 'UTF-8', false);
?>

Передача одного и того же параметра несколько раз приводит к выбрасыванию исключения Error.

Пример #19 Ошибка, возникающая при передаче одного и того же параметра несколько раз

<?php
function foo($param) { ... }

foo(param: 1, param: 2);
// Error: Named parameter $param overwrites previous argument
foo(1, param: 2);
// Error: Named parameter $param overwrites previous argument
?>

Начиная с PHP 8.1.0, можно использовать именованные аргументы после распаковки аргументов. Именованный аргумент не должен переопределять уже распакованный аргумент.

Пример #20 Пример использования именованных аргументов после распаковки

<?php
function foo($a, $b, $c = 3, $d = 4) {
return
$a + $b + $c + $d;
}
var_dump(foo(...[1, 2], d: 40)); // 46
var_dump(foo(...['b' => 2, 'a' => 1], d: 40)); // 46
var_dump(foo(...[1, 2], b: 20)); // Фатальная ошибка. Именованный аргумент $b переопределяет предыдущий аргумент
?>


Возврат значений

Значения возвращаются при помощи необязательного оператора возврата. Возвращаемые значения могут быть любого типа, в том числе это могут быть массивы и объекты. Возврат приводит к завершению выполнения функции и передаче управления обратно к той строке кода, в которой данная функция была вызвана. Для получения более детальной информации ознакомьтесь с описанием return.

Замечание:

Если конструкция return не указана, то функция вернёт значение null.

Использование выражения return

Пример #1 Использование конструкции return

<?php
function square($num)
{
return
$num * $num;
}
echo
square(4); // выводит '16'.
?>

Функция не может возвращать несколько значений, но аналогичного результата можно добиться, возвращая массив.

Пример #2 Возврат нескольких значений в виде массива

<?php
function small_numbers()
{
return [
0, 1, 2];
}
// Деструктуризация массива будет собирать каждый элемент массива индивидуально
[$zero, $one, $two] = small_numbers();

// До версии 7.1.0 единственной эквивалентной альтернативой было использование конструкции list().
list($zero, $one, $two) = small_numbers();

?>

Для того, чтобы функция возвращала результат по ссылке, вам необходимо использовать оператор & и при описании функции, и при присвоении переменной возвращаемого значения:

Пример #3 Возврат результата по ссылке

<?php
function &returns_reference()
{
return
$someref;
}

$newref =& returns_reference();
?>

Для получения более детальной информации о ссылках обратитесь к разделу документации Подробно о ссылках.



Обращение к функциям через переменные

PHP поддерживает концепцию переменных функций. Это означает, что если к имени переменной присоединены круглые скобки, PHP ищет функцию с тем же именем, что и результат вычисления переменной, и пытается её выполнить. Эту возможность можно использовать для реализации обратных вызовов, таблиц функций и множества других вещей.

Переменные функции не будут работать с такими языковыми конструкциями как echo, print, unset(), isset(), empty(), include, require и т.п. Вам необходимо реализовать свою функцию-обёртку для того, чтобы приведённые выше конструкции могли работать с переменными функциями.

Пример #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()
?>

Вы также можете вызвать методы объекта используя возможности PHP для работы с переменными функциями.

Пример #2 Обращение к методам класса посредством переменных

<?php
class Foo
{
function
Variable()
{
$name = 'Bar';
$this->$name(); // Вызываем метод Bar()
}

function
Bar()
{
echo
"Это Bar";
}
}

$foo = new Foo();
$funcname = "Variable";
$foo->$funcname(); // Обращаемся к $foo->Variable()

?>

При вызове статических методов вызов функции "сильнее", чем оператор доступа к статическому свойству:

Пример #3 Пример вызова переменного метода со статическим свойством

<?php
class Foo
{
static
$variable = 'статическое свойство';
static function
Variable()
{
echo
'Вызов метода Variable';
}
}

echo
Foo::$variable; // Это выведет 'статическое свойство'. Переменная $variable будет разрешена в этой области видимости.
$variable = "Variable";
Foo::$variable(); // Это вызовет $foo->Variable(), прочитав $variable из этой области видимости.

?>

Пример #4 Сложные callable-функции

<?php
class Foo
{
static function
bar()
{
echo
"bar\n";
}
function
baz()
{
echo
"baz\n";
}
}

$func = array("Foo", "bar");
$func(); // выведет "bar"
$func = array(new Foo, "baz");
$func(); // выведет "baz"
$func = "Foo::bar";
$func(); // выведет "bar"
?>



Встроенные функции

В самом PHP содержится достаточно большое количество встроенных функций и языковых конструкций. Также есть функции, которые требуют, чтобы PHP был собран с определёнными модулями, в противном случае будут генерироваться фатальные ошибки, вызванные использованием неизвестной функции. Например, для того чтобы использовать функции для работы с изображениями, например, imagecreatetruecolor(), необходимо собрать PHP с поддержкой GD. Или же для того, чтобы воспользоваться функцией mysqli_connect(), необходима поддержка модуля MySQLi. Тем не менее, есть много встроенных функций, которые доступны всегда: например, функции обработки строк и функции для работы с переменными. Вызвав phpinfo() или get_loaded_extensions(), можно узнать, поддержка каких модулей есть в используемом PHP. Также следует учесть, что поддержка некоторых дополнительных модулей включена по умолчанию, и что сама документация к PHP разбита по модулям. Ознакомьтесь с разделами Конфигурация, Установка, а также с документацией непосредственно к дополнительным модулям для получения более детальной информации о том, как настроить PHP.

Более подробную информацию о том, как следует читать и интерпретировать прототипы функций, вы можете найти в разделе Как читать определения функции. Очень важно понимать, что возвращает функция, или как именно она модифицирует передаваемые аргументы. Например, функция str_replace() возвращает модифицированную строку, в то время как функция usort() работает с фактически переданной переменной. Каждая страница документации также содержит информацию, которая специфична для данной функции, например, информацию о передаваемых параметрах, изменениях в поведении, возвращаемых значениях в случае как удачного, так и неудачного выполнения, доступности функции в различных версиях. Знание и применение этих (порой даже незаметных) нюансов очень важно для написания корректного PHP-кода.

Замечание: Если в функцию передаются не те аргументы, которые она ожидает, например, массив (array) вместо строки (string), возвращаемое значение функции не определено. Скорее всего в этом случае будет возвращён null, но это просто соглашение, на него нельзя полагаться. Начиная с PHP 8.0.0, в этом случае должно быть выброшено исключение TypeError.

Замечание:

Скалярные типы для встроенных функций по умолчанию являются допускающими значение null в принудительном режиме. Начиная с PHP 8.1.0, передача null в параметр встроенной функции, который не объявлен как допускающий значение null, не рекомендуется и в принудительном режиме выдаётся уведомление об устаревании, чтобы соответствовать поведению пользовательских функций, где скалярные типы должны быть явно помечены как допускающие значение null.

Например, функция strlen() ожидает, что параметр $string будет строкой (string), не допускающей значение null. По историческим причинам PHP позволяет передавать null для этого параметра в принудительном режиме и параметр неявно приводится к строке (string), в результате чего получается значение "". В строгом режиме выбрасывается исключение TypeError.

<?php
var_dump
(strlen(null));
// "Deprecated: Passing null to parameter #1 ($string) of type string is deprecated" начиная с PHP 8.1.0
// int(0)

var_dump(str_contains("foobar", null));
// "Deprecated: Passing null to parameter #2 ($needle) of type string is deprecated" начиная с PHP 8.1.0
// bool(true)
?>



Анонимные функции

Анонимные функции, также известные как замыкания (closures), позволяют создавать функции, не имеющие определённых имён. Они наиболее полезны в качестве значений callable-параметров, но также могут иметь и множество других применений.

Анонимные функции реализуются с использованием класса Closure.

Пример #1 Пример анонимной функции

<?php
echo preg_replace_callback('~-([a-z])~', function ($match) {
return
strtoupper($match[1]);
},
'hello-world');
// выведет helloWorld
?>

Замыкания также могут быть использованы в качестве значений переменных; PHP автоматически преобразует такие выражения в экземпляры внутреннего класса Closure. Присвоение замыкания переменной использует тот же синтаксис, что и для любого другого присвоения, включая завершающую точку с запятой:

Пример #2 Пример присвоения анонимной функции переменной

<?php
$greet
= function($name) {
printf("Привет, %s\r\n", $name);
};

$greet('Мир');
$greet('PHP');
?>

Замыкания могут также наследовать переменные из родительской области видимости. Любая подобная переменная должна быть объявлена в конструкции use. Начиная с PHP 7.1, эти переменные не должны включать superglobals, $this и переменные с теми же именами, что и параметры функции. Объявление типа возвращаемого значения функции должно быть помещено после конструкции use.

Пример #3 Наследование переменных из родительской области видимости

<?php
$message
= 'привет';

// Без "use"
$example = function () {
var_dump($message);
};
$example();

// Наследуем $message
$example = function () use ($message) {
var_dump($message);
};
$example();

// Значение унаследованной переменной задано там, где функция определена,
// но не там, где вызвана
$message = 'мир';
$example();

// Сбросим message
$message = 'привет';

// Наследование по ссылке
$example = function () use (&$message) {
var_dump($message);
};
$example();

// Изменённое в родительской области видимости значение
// остаётся тем же внутри вызова функции
$message = 'мир';
echo
$example();

// Замыкания могут принимать обычные аргументы
$example = function ($arg) use ($message) {
var_dump($arg . ', ' . $message);
};
$example("привет");

// Объявление типа возвращаемого значения идет после конструкции use
$example = function () use ($message): string {
return
"привет $message";
};
var_dump($example());
?>

Результатом выполнения данного примера будет что-то подобное:

Notice: Undefined variable: message in /example.php on line 6
NULL
string(6) "привет"
string(6) "привет"
string(6) "привет"
string(3) "мир"
string(11) "привет, мир"
string(10) "привет мир"

Начиная с PHP 8.0.0, список наследуемых переменных может завершаться запятой, которая будет проигнорирована.

Наследование переменных из родительской области видимости не то же самое, что использование глобальных переменных. Глобальные переменные существуют в глобальной области видимости, которая не меняется, вне зависимости от того, какая функция выполняется в данный момент. Родительская область видимости - это функция, в которой было объявлено замыкание (не обязательно та же самая, из которой оно было вызвано). Смотрите следующий пример:

Пример #4 Замыкания и область видимости

<?php
// Базовая корзина покупок, содержащая список добавленных
// продуктов и количество каждого продукта. Включает метод,
// вычисляющий общую цену элементов корзины с помощью
// callback-замыкания.
class Cart
{
const
PRICE_BUTTER = 1.00;
const
PRICE_MILK = 3.00;
const
PRICE_EGGS = 6.95;

protected
$products = array();

public function
add($product, $quantity)
{
$this->products[$product] = $quantity;
}

public function
getQuantity($product)
{
return isset(
$this->products[$product]) ? $this->products[$product] :
FALSE;
}

public function
getTotal($tax)
{
$total = 0.00;

$callback =
function (
$quantity, $product) use ($tax, &$total)
{
$pricePerItem = constant(__CLASS__ . "::PRICE_" .
strtoupper($product));
$total += ($pricePerItem * $quantity) * ($tax + 1.0);
};

array_walk($this->products, $callback);
return
round($total, 2);
}
}

$my_cart = new Cart;

// Добавляем несколько элементов в корзину
$my_cart->add('butter', 1);
$my_cart->add('milk', 3);
$my_cart->add('eggs', 6);

// Выводим общую сумму с 5% налогом на продажу.
print $my_cart->getTotal(0.05) . "\n";
// Результатом будет 54.29
?>

Пример #5 Автоматическое связывание $this

<?php

class Test
{
public function
testing()
{
return function() {
var_dump($this);
};
}
}

$object = new Test;
$function = $object->testing();
$function();

?>

Результат выполнения данного примера:

object(Test)#1 (0) {
}

При объявлении в контексте класса, текущий класс будет автоматически связан с ним, делая $this доступным внутри функций класса. Если вы не хотите автоматического связывания с текущим классом, используйте статические анонимные функции.

Статические анонимные функции

Анонимные функции могут быть объявлены статически. Это предотвратит их автоматическое связывание с текущим классом. Объекты также не будут с ними связаны во время выполнения.

Пример #6 Попытка использовать $this в статической анонимной функции

<?php

class Foo
{
function
__construct()
{
$func = static function() {
var_dump($this);
};
$func();
}
};
new
Foo();

?>

Результат выполнения данного примера:

Notice: Undefined variable: this in %s on line %d
NULL

Пример #7 Попытка связать объект со статической анонимной функцией

<?php

$func
= static function() {
// тело функции
};
$func = $func->bindTo(new stdClass);
$func();

?>

Результат выполнения данного примера:

Warning: Cannot bind an instance to a static closure in %s on line %d

Список изменений

Версия Описание
7.1.0 Анонимные функции не могут замыкаться вокруг superglobals, $this или любой переменной с тем же именем, что и параметр.

Примечания

Замечание: Совместно с замыканиями можно использовать функции func_num_args(), func_get_arg() и func_get_args().



Стрелочные функции

Стрелочные функции появились в PHP 7.4, как более лаконичный синтаксис для анонимных функций.

И анонимные, и стрелочные функции реализованы с использованием класса Closure.

Основной вид записи стрелочных функций: fn (argument_list) => expr.

Стрелочные функции поддерживают те же возможности, что и анонимные функции, за исключением того, что использование переменных из родительской области всегда выполняется автоматически.

Когда переменная, используемая в выражении, определена в родительской области, она будет неявно захвачена по значению. В следующем примере функции $fn1 и $fn2 ведут себя одинаково.

Пример #1 Стрелочные функции захватывают переменные по значению автоматически

<?php

$y
= 1;

$fn1 = fn($x) => $x + $y;
// эквивалентно использованию $y по значению:
$fn2 = function ($x) use ($y) {
return
$x + $y;
};

var_export($fn1(3));
?>

Результат выполнения данного примера:

4

Это также работает во вложенных стрелочных функциях:

Пример #2 Стрелочные функции захватывают переменные по значению автоматически, даже когда они вложены

<?php

$z
= 1;
$fn = fn($x) => fn($y) => $x * $y + $z;
// Выведет 51
var_export($fn(5)(10));
?>

Подобно анонимным функциям, синтаксис стрелочных функций допускает произвольные сигнатуры функций, включая типы параметров и возвращаемых значений, значения по умолчанию, переменные, а также передачу и возврат по ссылке. Ниже приведены корректные примеры стрелочных функций:

Пример #3 Примеры использования стрелочных функций

<?php

fn
(array $x) => $x;
static
fn(): int => $x;
fn($x = 42) => $x;
fn(&$x) => $x;
fn&($x) => $x;
fn($x, ...$rest) => $rest;

?>

Стрелочные функции используют привязку переменных по значению. Это примерно эквивалентно выполнению use($x) для каждой переменной $x, используемой внутри стрелочной функции. Привязка по значению означает, что невозможно изменить какие-либо значения из внешней области. Вместо этого можно использовать анонимные функции для привязок по ссылкам.

Пример #4 Значения из внешней области видимости не могут быть изменены стрелочными функциями

<?php

$x
= 1;
$fn = fn() => $x++; // Ничего не изменит
$fn();
var_export($x); // Выведет 1

?>

Список изменений

Версия Описание
7.4.0 Стали доступны стрелочные функции.

Примечания

Замечание: Можно использовать func_num_args(), func_get_arg() и func_get_args() в стрелочной функции.



Callback-функции как объекты первого класса

Callback-функции как объекты первого класса представлены в PHP 8.1.0 как способ создания анонимных функций из callback-функций. Синтаксис заменяет существующий синтаксис вызова с использованием строк и массивов. Преимущество синтаксиса заключается в том, что он доступен для статического анализа и использует область видимости в точке, где получена callback-функция.

Синтаксис CallableExpr(...) используется для создания объекта Closure из callback-функции. CallableExpr принимает любое выражение, которое может быть вызвано напрямую в грамматике PHP:

Пример #1 Простой пример callback-функции как объекты первого класса

<?php
class Foo {
public function
method() {}
public static function
staticmethod() {}
public function
__invoke() {}
}
$obj = new Foo();
$classStr = 'Foo';
$methodStr = 'method';
$staticmethodStr = 'staticmethod';
$f1 = strlen(...);
$f2 = $obj(...); // вызываемый объект
$f3 = $obj->method(...);
$f4 = $obj->$methodStr(...);
$f5 = Foo::staticmethod(...);
$f6 = $classStr::$staticmethodStr(...);
// традиционная callback-функция с использованием строки, массива
$f7 = 'strlen'(...);
$f8 = [$obj, 'method'](...);
$f9 = [Foo::class, 'staticmethod'](...);
?>

Замечание:

... является частью синтаксиса, а не пропуском.

У CallableExpr(...) та же семантика, что и у Closure::fromCallable(). То есть, в отличие от callback-функции с использованием строк и массивов, CallableExpr(...) учитывает область видимости в точке, где она создаётся:

Пример #2 Сравнение области действия CallableExpr(...) и традиционной callback-функции

<?php
class Foo {
public function
getPrivateMethod() {
return [
$this, 'privateMethod'];
}
private function
privateMethod() {
echo
__METHOD__, "\n";
}
}
$foo = new Foo;
$privateMethod = $foo->getPrivateMethod();
$privateMethod();
// Fatal error: Call to private method Foo::privateMethod() from global scope
// Это потому, что вызов выполняется вне Foo, и с этого момента будет проверяться видимость.
class Foo1 {
public function
getPrivateMethod() {
// Использует область, в которой получена callback-функция.
return $this->privateMethod(...); // идентично Closure::fromCallable([$this, 'privateMethod']);
}
private function
privateMethod() {
echo
__METHOD__, "\n";
}
}
$foo1 = new Foo1;
$privateMethod = $foo1->getPrivateMethod();
$privateMethod(); // Foo1::privateMethod
?>

Замечание:

Создание объекта с помощью этого синтаксиса (например, new Foo(...)) не поддерживается, поскольку синтаксис new Foo() не считается callback-функцией.

Замечание:

Callback-функции как объекты первого класса нельзя комбинировать с оператором Nullsafe. Оба следующих результата приводят к ошибке времени компиляции:

<?php
$obj
?->method(...);
$obj?->prop->method(...);
?>




Классы и объекты

Содержание


Введение

PHP включает полноценную объектную модель. Некоторые из её особенностей: видимость, абстрактные и ненаследуемые (final) классы и методы, а также магические методы, интерфейсы и клонирование.

PHP работает с объектами так же, как с ссылками или дескрипторами, это означает что каждая переменная содержит ссылку на объект, а не его копию. Более подробную информацию смотрите в разделе Объекты и ссылки.

Подсказка

Смотрите также Руководство по именованию.



Основы

class

Каждое определение класса начинается с ключевого слова class, затем следует имя класса, и далее пара фигурных скобок, которые заключают в себе определение свойств и методов этого класса.

Именем класса может быть любое слово, при условии, что оно не входит в список зарезервированных слов PHP, начинается с буквы или символа подчёркивания и за которым следует любое количество букв, цифр или символов подчёркивания. Если задать эти правила в виде регулярного выражения, то получится следующее выражение: ^[a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*$.

Класс может содержать собственные константы, переменные (называемые свойствами) и функции (называемые методами).

Пример #1 Простое определение класса

<?php
class SimpleClass
{
// объявление свойства
public $var = 'значение по умолчанию';

// объявление метода
public function displayVar() {
echo
$this->var;
}
}
?>

Псевдопеременная $this доступна в том случае, если метод был вызван в контексте объекта. $this - значение вызывающего объекта.

Внимание

Вызов нестатического метода статически вызывает ошибку Error. До PHP 8.0.0 это привело бы к уведомлению об устаревании, и $this не была бы определена.

Пример #2 Некоторые примеры псевдо-переменной $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();
?>

Результат выполнения данного примера в PHP 7:

$this определена (A)

Deprecated: Non-static method A::foo() should not be called statically in %s  on line 27
$this не определена.

Deprecated: Non-static method A::foo() should not be called statically in %s  on line 20
$this не определена.

Deprecated: Non-static method B::bar() should not be called statically in %s  on line 32

Deprecated: Non-static method A::foo() should not be called statically in %s  on line 20
$this не определена.

Результат выполнения данного примера в PHP 8:

$this определена (A)

Fatal error: Uncaught Error: Non-static method A::foo() cannot be called statically in %s :27
Stack trace:
#0 {main}
  thrown in %s  on line 27

Классы, доступные только для чтения

Начиная с PHP 8.2.0, класс может быть помечен модификатором readonly. Пометка класса как readonly добавит модификатор readonly к каждому объявленному свойству и предотвратит создание динамических свойств. Более того, невозможно добавить их поддержку с помощью атрибута AllowDynamicProperties. Попытка это сделать приведёт к ошибке компиляции.

<?php
#[\AllowDynamicProperties]
readonly class Foo {
}

// Fatal error: Cannot apply #[AllowDynamicProperties] to readonly class Foo
?>

Поскольку ни нетипизированные, ни статические свойства не могут быть помечены модификатором readonly, классы, доступные только для чтения также не могут их объявлять:

<?php
readonly
class Foo
{
public
$bar;
}

// Fatal error: Readonly property Foo::$bar must have type
?>
<?php
readonly
class Foo
{
public static
int $bar;
}

// Fatal error: Readonly class Foo cannot declare static properties
?>

Класс readonly может быть расширен тогда и только тогда, когда дочерний класс также является классом readonly.

new

Для создания экземпляра класса используется директива new. Новый объект всегда будет создан, за исключением случаев, когда он содержит конструктор, в котором определён вызов исключения в случае возникновения ошибки. Рекомендуется определять классы до создания их экземпляров (в некоторых случаях это обязательно).

Если с директивой new используется строка (string), содержащая имя класса, то будет создан новый экземпляр этого класса. Если имя находится в пространстве имён, то оно должно быть задано полностью.

Замечание:

В случае отсутствия аргументов в конструктор класса, круглые скобки после названия класса можно опустить.

Пример #3 Создание экземпляра класса

<?php
$instance
= new SimpleClass();

// Это же можно сделать с помощью переменной:
$className = 'SimpleClass';
$instance = new $className(); // new SimpleClass()
?>

Начиная с PHP 8.0.0, поддерживается использование оператора new с произвольными выражениями. Это позволяет создавать более сложные экземпляры, если выражение представлено в виде строки (string). Выражения должны быть заключены в круглые скобки.

Пример #4 Создание экземпляра с использованием произвольного выражения

В данном примере мы показываем несколько вариантов допустимых произвольных выражений, которые представляют имя класса. Пример вызова функции, конкатенации строк и константы ::class.

<?php

class ClassA extends \stdClass {}
class
ClassB extends \stdClass {}
class
ClassC extends ClassB {}
class
ClassD extends ClassA {}

function
getSomeClass(): string
{
return
'ClassA';
}

var_dump(new (getSomeClass()));
var_dump(new ('Class' . 'B'));
var_dump(new ('Class' . 'C'));
var_dump(new (ClassD::class));
?>

Результат выполнения данного примера в PHP 8:

object(ClassA)#1 (0) {
}
object(ClassB)#1 (0) {
}
object(ClassC)#1 (0) {
}
object(ClassD)#1 (0) {
}

В контексте класса можно создать новый объект через new self и new parent.

Когда происходит присвоение уже существующего экземпляра класса новой переменной, то эта переменная будет указывать на этот же экземпляр класса. То же самое происходит и при передаче экземпляра класса в функцию. Копию уже созданного объекта можно создать через её клонирование.

Пример #5 Присваивание объекта

<?php

$instance
= new SimpleClass();

$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 будет иметь это значение"
}

Создавать экземпляры объекта можно двумя способами:

Пример #6 Создание новых объектов

<?php
class Test
{
static public function
getNew()
{
return new static;
}
}

class
Child extends Test
{}

$obj1 = new Test();
$obj2 = new $obj1;
var_dump($obj1 !== $obj2);

$obj3 = Test::getNew();
var_dump($obj3 instanceof Test);

$obj4 = Child::getNew();
var_dump($obj4 instanceof Child);
?>

Результат выполнения данного примера:

bool(true)
bool(true)
bool(true)

Обратиться к свойству или методу только что созданного объекта можно с помощью одного выражения:

Пример #7 Доступ к свойствам/методам только что созданного объекта

<?php
echo (new DateTime())->format('Y');
?>

Результатом выполнения данного примера будет что-то подобное:

2016

Замечание: До PHP 7.1 аргументы не имели значения, если не определена функция конструктора.

Свойства и методы

Свойства и методы класса живут в разделённых "пространствах имён", так что возможно иметь свойство и метод с одним и тем же именем. Ссылки как на свойства, так и на методы имеют одинаковую нотацию, и получается, что получите вы доступ к свойству или же вызовете метод - определяется контекстом использования.

Пример #8 Доступ к свойству vs. вызов метода

<?php
class Foo
{
public
$bar = 'свойство';

public function
bar() {
return
'метод';
}
}

$obj = new Foo();
echo
$obj->bar, PHP_EOL, $obj->bar(), PHP_EOL;

Результат выполнения данного примера:

свойство
метод

Это означает, что вызвать анонимную функцию, присвоенную переменной, напрямую не получится. Вместо этого свойство должно быть назначено, например, переменной. Можно вызвать такое свойство напрямую, заключив его в скобки.

Пример #9 Вызов анонимной функции, содержащейся в свойстве

<?php
class Foo
{
public
$bar;

public function
__construct() {
$this->bar = function() {
return
42;
};
}
}

$obj = new Foo();

echo (
$obj->bar)(), PHP_EOL;

Результат выполнения данного примера:

42

extends

Класс может наследовать константы, методы и свойства другого класса используя ключевое слово extends в его объявлении. Невозможно наследовать несколько классов, один класс может наследовать только один базовый класс.

Наследуемые константы, методы и свойства могут быть переопределены (за исключением случаев, когда метод или константа класса объявлены как final) путём объявления их с теми же именами, как и в родительском классе. Существует возможность доступа к переопределённым методам или статическим свойствам путём обращения к ним через parent::

Замечание: Начиная с PHP 8.1.0, константы можно объявлять окончательными (final).

Пример #10 Простое наследование классов

<?php
class ExtendClass extends SimpleClass
{
// Переопределение метода родителя
function displayVar()
{
echo
"Расширенный класс\n";
parent::displayVar();
}
}

$extended = new ExtendClass();
$extended->displayVar();
?>

Результат выполнения данного примера:

Расширенный класс
значение по умолчанию

Правила совместимости сигнатуры

При переопределении метода его сигнатура должна быть совместима с родительским методом. В противном случае выдаётся фатальная ошибка или, до PHP 8.0.0, генерируется ошибка уровня E_WARNING. Сигнатура является совместимой, если она соответствует правилам контравариантности, делает обязательный параметр необязательным, добавляет только необязательные новые параметры и не ограничивает, а только ослабляет видимость. Это известно как принцип подстановки Барбары Лисков или сокращённо LSP. Правила совместимости не распространяются на конструктор и сигнатуру private методов, они не будут выдавать фатальную ошибку в случае несоответствия сигнатуры.

Пример #11 Совместимость дочерних методов

<?php

class Base
{
public function
foo(int $a) {
echo
"Допустимо\n";
}
}

class
Extend1 extends Base
{
function
foo(int $a = 5)
{
parent::foo($a);
}
}

class
Extend2 extends Base
{
function
foo(int $a, $b = 5)
{
parent::foo($a);
}
}

$extended1 = new Extend1();
$extended1->foo();
$extended2 = new Extend2();
$extended2->foo(1);

Результат выполнения данного примера:

Допустимо
Допустимо

Следующие примеры демонстрируют, что дочерний метод, который удаляет параметр или делает необязательный параметр обязательным, несовместим с родительским методом.

Пример #12 Фатальная ошибка, когда дочерний метод удаляет параметр

<?php

class Base
{
public function
foo(int $a = 5) {
echo
"Допустимо\n";
}
}

class
Extend extends Base
{
function
foo()
{
parent::foo(1);
}
}

Результат выполнения данного примера в PHP 8 аналогичен:

Fatal error: Declaration of Extend::foo() must be compatible with Base::foo(int $a = 5) in /in/evtlq on line 13

Пример #13 Фатальная ошибка, когда дочерний метод делает необязательный параметр обязательным.

<?php

class Base
{
public function
foo(int $a = 5) {
echo
"Допустимо\n";
}
}

class
Extend extends Base
{
function
foo(int $a)
{
parent::foo($a);
}
}

Результат выполнения данного примера в PHP 8 аналогичен:

Fatal error: Declaration of Extend::foo(int $a) must be compatible with Base::foo(int $a = 5) in /in/qJXVC on line 13
Внимание

Переименование параметра метода в дочернем классе не является несовместимостью сигнатуры. Однако это не рекомендуется, так как приведёт к Error во время выполнения, если используются именованные аргументы.

Пример #14 Ошибка при использовании именованных аргументов и параметров, переименованных в дочернем классе

<?php

class A {
public function
test($foo, $bar) {}
}

class
B extends A {
public function
test($a, $b) {}
}

$obj = new B;

// Передача параметров согласно контракту A::test()
$obj->test(foo: "foo", bar: "bar"); // ОШИБКА!

Результатом выполнения данного примера будет что-то подобное:

Fatal error: Uncaught Error: Unknown named parameter $foo in /in/XaaeN:14
Stack trace:
#0 {main}
  thrown in /in/XaaeN on line 14

::class

Ключевое слово class используется для разрешения имени класса. Чтобы получить полное имя класса ClassName, используйте ClassName::class. Обычно это довольно полезно при работе с классами, использующими пространства имён.

Пример #15 Разрешение имени класса

<?php
namespace NS {
class
ClassName {
}

echo
ClassName::class;
}
?>

Результат выполнения данного примера:

NS\ClassName

Замечание:

Разрешение имён класса с использованием ::class происходит на этапе компиляции. Это означает, что на момент создания строки с именем класса автозагрузки класса не происходит. Как следствие, имена классов раскрываются, даже если класс не существует. Ошибка в этом случае не выдаётся.

Пример #16 Отсутствует разрешение имени класса

<?php
print Does\Not\Exist::class;
?>

Результат выполнения данного примера:

Does\Not\Exist

Начиная с PHP 8.0.0, константа ::class также может использоваться для объектов. Это разрешение происходит во время выполнения, а не во время компиляции. То же самое, что и при вызове get_class() для объекта.

Пример #17 Разрешение имени объекта

<?php
namespace NS {
class
ClassName {
}
}
$c = new ClassName();
print
$c::class;
?>

Результат выполнения данного примера:

NS\ClassName

Методы и свойства Nullsafe

Начиная с PHP 8.0.0, к свойствам и методам можно также обращаться с помощью оператора "nullsafe": ?->. Оператор nullsafe работает так же, как доступ к свойству или методу, как указано выше, за исключением того, что если разыменование объекта выдаёт null, то будет возвращён null, а не выброшено исключение. Если разыменование является частью цепочки, остальная часть цепочки пропускается.

Аналогично заключению каждого обращения в is_null(), но более компактный.

Пример #18 Оператор Nullsafe

<?php

// Начиная с PHP 8.0.0, эта строка:
$result = $repository?->getUser(5)?->name;

// Эквивалентна следующему блоку кода:
if (is_null($repository)) {
$result = null;
} else {
$user = $repository->getUser(5);
if (
is_null($user)) {
$result = null;
} else {
$result = $user->name;
}
}
?>

Замечание:

Оператор nullsafe лучше всего использовать, когда null считается допустимым и ожидаемым значением для возвращаемого свойства или метода. Для индикации ошибки предпочтительнее выбрасывать исключение.



Свойства

Переменные, которые являются членами класса, называются свойства. Также их называют, используя другие термины, таких как поля, но в рамках этой документации, мы будем называть их свойствами. Они определяются с использованием хотя бы одного необязательного (за исключением readonly-свойств) модификатора (например, Область видимости, Ключевое слово static или, начиная с PHP 8.1.0, readonly), начиная с PHP 7.4, за которым следует необязательное объявление типа, за которым следует обычное объявление переменной. Это объявление может содержать инициализацию, но эта инициализация должна быть постоянным значением.

Замечание:

Устаревший способ объявления свойств класса — использование ключевого слова var вместо модификатора.

Замечание: Свойство, объявленное без модификатора Область видимости, будет объявлено как public.

В пределах методов класса доступ к нестатическим свойствам может быть получен с помощью -> (объектного оператора): $this->property (где property - имя свойства). Доступ к статическим свойствам осуществляется с помощью :: (двойного двоеточия): self::$property. Дополнительную информацию о различии статических и нестатических свойств смотрите в разделе Ключевое слово static.

Псевдопеременная $this доступна внутри любого метода класса, когда этот метод вызывается из контекста объекта. $this - значение вызывающего объекта.

Пример #1 Определение свойств

<?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 = [true, false];

public
$var8 = <<<'EOD'
hello world
EOD;

// Без модификатора области видимости:
static $var9;
readonly int $var10;

}
?>

Замечание:

Существуют различные функции для обработки классов и объектов. Смотрите справочник по функций для классов/объектов.

Объявления типов

Начиная с PHP 7.4.0, определения свойств могут включать Объявление типов, за исключением типа callable.

Пример #2 Пример использования типизированных свойств

<?php

class User
{
public
int $id;
public ?
string $name;

public function
__construct(int $id, ?string $name)
{
$this->id = $id;
$this->name = $name;
}
}

$user = new User(1234, null);

var_dump($user->id);
var_dump($user->name);

?>

Результат выполнения данного примера:

int(1234)
NULL

Перед обращением к типизированному свойству у него должно быть задано значение, иначе будет выброшено исключение Error.

Пример #3 Обращение к свойствам

<?php

class Shape
{
public
int $numberOfSides;
public
string $name;

public function
setNumberOfSides(int $numberOfSides): void
{
$this->numberOfSides = $numberOfSides;
}

public function
setName(string $name): void
{
$this->name = $name;
}

public function
getNumberOfSides(): int
{
return
$this->numberOfSides;
}

public function
getName(): string
{
return
$this->name;
}
}

$triangle = new Shape();
$triangle->setName("triangle");
$triangle->setNumberofSides(3);
var_dump($triangle->getName());
var_dump($triangle->getNumberOfSides());

$circle = new Shape();
$circle->setName("circle");
var_dump($circle->getName());
var_dump($circle->getNumberOfSides());
?>

Результат выполнения данного примера:

string(8) "triangle"
int(3)
string(6) "circle"

Fatal error: Uncaught Error: Typed property Shape::$numberOfSides must not be accessed before initialization

Readonly-свойства

Начиная с PHP 8.1.0, свойство можно объявить с помощью модификатора readonly, который предотвращает изменение свойства после инициализации.

Пример #4 Примеры readonly-свойств

<?php
class Test {
public
readonly string $prop;
public function
__construct(string $prop) {
// Правильная инициализация.
$this->prop = $prop;
}
}
$test = new Test("foobar");
// Правильное чтение.
var_dump($test->prop); // string(6) "foobar"
// Неправильное переопределение. Не имеет значения, что присвоенное значение такое же.
$test->prop = "foobar";
// Ошибка: невозможно изменить readonly-свойство Test::$prop
?>

Замечание:

Модификатор readonly может применяться только к типизированным свойствам. Readonly-свойство без ограничений типа можно создать с помощью типа Mixed.

Замечание:

Статические readonly-свойства не поддерживаются.

Readonly-свойство можно инициализировать только один раз и только из области, в которой оно было объявлено. Любое другое присвоение или изменение свойства приведёт к исключению Error.

Пример #5 Неправильная инициализация readonly-свойств

<?php
class Test1 {
public
readonly string $prop;
}
$test1 = new Test1;
// Неправильная инициализация за пределами закрытой области.
$test1->prop = "foobar";
// Ошибка: не удаётся инициализировать readonly-свойство Test1::$prop из глобальной области
?>

Замечание:

Указание явного значения по умолчанию для readonly-свойств не допускается, потому что readonly-свойство со значением по умолчанию, по сути, то же самое, что и константа и поэтому не особенно полезно.

<?php
class Test {
// Ошибка: у readonly-свойства Test::$prop не может быть значения по умолчанию
public readonly int $prop = 42;
}
?>

Замечание:

Readonly-свойства не могут быть уничтожены с помощью unset() после их инициализации. Однако можно уничтожить readonly-свойство до инициализации из области, в которой было объявлено свойство.

Модификации не обязательно являются простыми присвоениями, всё перечисленное ниже также приведёт к исключению Error:

<?php
class Test {
public function
__construct(
public
readonly int $i = 0,
public
readonly array $ary = [],
) {}
}
$test = new Test;
$test->i += 1;
$test->i++;
++
$test->i;
$test->ary[] = 1;
$test->ary[0][] = 1;
$ref =& $test->i;
$test->i =& $ref;
byRef($test->i);
foreach (
$test as &$prop);
?>

Однако readonly-свойства не исключают внутренней изменчивости. Объекты (или ресурсы), хранящиеся в readonly-свойствах по-прежнему могут быть изменены внутри:

<?php
class Test {
public function
__construct(public readonly object $obj) {}
}
$test = new Test(new stdClass);
// Правильное внутреннее изменение.
$test->obj->foo = 1;
// Неправильное переопределение.
$test->obj = new stdClass;
?>

Динамические свойства

При попытке присвоить несуществующее свойство объекту (object), PHP автоматически создаст соответствующее свойство. Это динамически созданное свойство будет доступно только для данного экземпляра класса.

Внимание

Динамические свойства устарели, начиная с PHP 8.2.0. Вместо этого рекомендуется объявлять свойство. Для работы с произвольными именами свойств, класс должен реализовать магические методы __get() и __set(). В крайнем случае, класс можно пометить атрибутом #[\AllowDynamicProperties].



Константы классов

Константы также могут быть объявлены в пределах одного класса. Область видимости констант по умолчанию public.

Замечание:

Константы класса могут быть переопределены дочерним классом. Начиная с PHP 8.1.0, константы класса не могут быть переопределены дочерним классом, если он определён как окончательный (final).

Интерфейсы также могут содержать константы. За примерами обращайтесь к разделу об интерфейсах.

К классу можно обратиться с помощью переменной. Значение переменной не может быть ключевым словом (например, self, parent и static).

Обратите внимание, что константы класса задаются один раз для всего класса, а не отдельно для каждого созданного объекта этого класса.

Пример #1 Объявление и использование константы

<?php
class MyClass
{
const
CONSTANT = 'значение константы';

function
showConstant() {
echo
self::CONSTANT . "\n";
}
}

echo
MyClass::CONSTANT . "\n";

$classname = "MyClass";
echo
$classname::CONSTANT . "\n";

$class = new MyClass();
$class->showConstant();

echo
$class::CONSTANT."\n";
?>

Специальная константа ::class, которой на этапе компиляции присваивается полное имя класса, полезна при использовании с классами, использующими пространства имён.

Пример #2 Пример использования ::class с пространством имён

<?php
namespace foo {
class
bar {
}

echo
bar::class; // foo\bar
}
?>

Пример #3 Пример констант, заданных выражением

<?php
const ONE = 1;

class
foo {
const
TWO = ONE * 2;
const
THREE = ONE + self::TWO;
const
SENTENCE = 'Значение константы THREE - ' . self::THREE;
}
?>

Пример #4 Модификаторы видимости констант класса, начиная с PHP 7.1.0

<?php
class Foo {
public const
BAR = 'bar';
private const
BAZ = 'baz';
}
echo
Foo::BAR, PHP_EOL;
echo
Foo::BAZ, PHP_EOL;
?>

Результат выполнения данного примера в PHP 7.1:

bar

Fatal error: Uncaught Error: Cannot access private const Foo::BAZ in …

Замечание:

Начиная с PHP 7.1.0 для констант класса можно использовать модификаторы области видимости.



Автоматическая загрузка классов

Большинство разработчиков объектно-ориентированных приложений используют такое соглашение именования файлов, в котором каждый класс хранится в отдельно созданном для него файле. Одна из самых больших неприятностей - необходимость писать в начале каждого скрипта длинный список подгружаемых файлов (по одному для каждого класса).

Функция spl_autoload_register() позволяет зарегистрировать необходимое количество автозагрузчиков для автоматической загрузки классов и интерфейсов, если они в настоящее время не определены. Регистрируя автозагрузчики, PHP получает последний шанс для интерпретатора загрузить класс прежде, чем он закончит выполнение скрипта с ошибкой.

Любая конструкция, подобная классу может быть автоматически загружена таким же образом, включая классы, интерфейсы, трейты и перечисления.

Предостережение

До PHP 8.0.0 можно было использовать __autoload() для автозагрузки классов и интерфейсов. Однако это менее гибкая альтернатива spl_autoload_register(), функция __autoload() объявлена устаревшей в PHP 7.2.0 и удалена в PHP 8.0.0.

Замечание:

Функция spl_autoload_register() может быть вызвана несколько раз, чтобы зарегистрировать несколько автозагрузчиков. Выброс исключения из функции автозагрузки, однако, прервёт этот процесс и не позволит запускать дальнейшие функции автозагрузки. По этой причине выбрасывать исключения из функции автозагрузки настоятельно не рекомендуется.

Пример #1 Пример автоматической загрузки

В этом примере функция пытается загрузить классы MyClass1 и MyClass2 из файлов MyClass1.php и MyClass2.php соответственно.

<?php
spl_autoload_register
(function ($class_name) {
include
$class_name . '.php';
});

$obj = new MyClass1();
$obj2 = new MyClass2();
?>

Пример #2 Ещё один пример автоматической загрузки

В этом примере представлена попытка загрузки интерфейса ITest.

<?php

spl_autoload_register
(function ($name) {
var_dump($name);
});

class
Foo implements ITest {
}

/*
string(5) "ITest"

Fatal error: Interface 'ITest' not found in ...
*/
?>



Конструкторы и деструкторы

Конструктор

__construct(mixed ...$values = ""): void

PHP позволяет объявлять методы-конструкторы. Классы, в которых объявлен метод-конструктор, будут вызывать этот метод при каждом создании нового объекта, так что это может оказаться полезным, например, для инициализации какого-либо состояния объекта перед его использованием.

Замечание: Конструкторы, определённые в классах-родителях, не вызываются автоматически, если дочерний класс определяет собственный конструктор. Чтобы вызвать конструктор, объявленный в родительском классе, требуется вызвать parent::__construct() внутри конструктора дочернего класса. Если в дочернем классе не определён конструктор, то он может быть унаследован от родительского класса как обычный метод (если он не был определён как приватный).

Пример #1 Конструкторы при наследовании

<?php
class BaseClass {
function
__construct() {
print
"Конструктор класса BaseClass\n";
}
}

class
SubClass extends BaseClass {
function
__construct() {
parent::__construct();
print
"Конструктор класса SubClass\n";
}
}

class
OtherSubClass extends BaseClass {
// наследует конструктор BaseClass
}

// Конструктор класса BaseClass
$obj = new BaseClass();

// Конструктор класса BaseClass
// Конструктор класса SubClass
$obj = new SubClass();

// Конструктор класса BaseClass
$obj = new OtherSubClass();
?>

В отличие от других методов, __construct() освобождается от обычных правил совместимости сигнатуры при наследовании.

Конструкторы - это обычные методы, которые вызываются при инстанциировании соответствующих объектов. Следовательно, они могут иметь произвольное количество аргументов, которые могут быть обязательными, могут быть типизированными и могут иметь значения по умолчанию. Аргументы конструктора указываются в круглых скобках после имени класса.

Пример #2 Использование аргументов в конструкторах

<?php
class Point {
protected
int $x;
protected
int $y;

public function
__construct(int $x, int $y = 0) {
$this->x = $x;
$this->y = $y;
}
}

// Передаём оба параметра.
$p1 = new Point(4, 5);
// Передаём только обязательные параметры. Для $y используется значение по умолчанию 0.
$p2 = new Point(4);
// Вызываем с именованными параметрами (начиная с PHP 8.0):
$p3 = new Point(y: 5, x: 4);
?>

Если у класса нет конструктора, или его конструктор не имеет обязательных параметров, скобки после имени класса можно не писать.

Конструкторы в старом стиле

До PHP 8.0.0, классы в глобальном пространстве имён будут интерпретировать метод, названный так же, как класс, как конструктор старого стиля. Этот синтаксис считается устаревшим и будет вызывать ошибку уровня E_DEPRECATED, но всё равно эти методы будут вызываться в качестве конструктора. Если в классе присутствуют и __construct(), и метод с именем класса, то в качестве конструктора будет вызван __construct().

Для классов, находящихся в собственном пространстве имён и для всех классов, начиная с PHP 8.0.0, метод, названный по имени класса, будет игнорироваться.

В новом коде всегда используйте __construct().

Определение свойств объекта в конструкторе

Начиная с PHP 8.0.0, параметры конструктора можно использовать для задания соответствующих свойств объекта. Это довольно распространённая практика — присваивать свойствам объекта параметры, переданные в конструктор, не производя никаких дополнительных преобразований. Определение свойств класса в конструкторе позволяет значительно сократить количество шаблонного кода для такого случая. Пример выше можно будет переписать следующим образом:

Пример #3 Использование определения свойств в конструкторе

<?php
class Point {
public function
__construct(protected int $x, protected int $y = 0) {
}
}

Если декларация аргумента конструктора включает модификатор видимости, PHP интерпретирует его одновременно и как аргумент конструктора, и как свойство объекта и автоматически присвоит свойству значение, переданное в конструктор. При этом, если не предполагается какой-либо дополнительной логики, тело конструктора можно оставить пустым. Код конструктора выполнится после того, как все аргументы присвоятся всем соответствующим свойствам.

Не все передаваемые в конструктор аргументы должны быть свойствами объекта. В конструкторе можно задавать как обычные, так и являющиеся свойствами объекта аргументы в любом порядке. Аргументы-свойства никак не влияют на код, исполняемый в конструкторе.

Замечание:

Свойства объектов не могут быть типа callable в связи с неоднозначностью которую они представляют для движка PHP. Соответственно и свойства определяемые в конструкторе также не могут быть типа callable. Любые другие декларации типов допустимы.

Замечание:

Атрибуты, заданные для таких аргументов, будут применены как для них самих, так и для соответствующих свойств. Значения по умолчанию для продвигаемого аргумента конструктора будут реплицироваться только на аргумент, а не на свойство.

New в инициализации класса

Начиная с PHP 8.1.0, объекты можно использовать в качестве значений параметров по умолчанию, статических переменных и глобальных констант, а также в аргументах атрибутов. Объекты также теперь можно передавать в define().

Замечание:

Использование динамического или не строкового имени класса или анонимного класса не допускается. Использование распаковки аргументов не допускается. Использование неподдерживаемых выражений в качестве аргументов не допускается.

Пример #4 Пример использования new в инициализации класса

<?php
// Всё допустимо:
static $x = new Foo;
const
C = new Foo;

function
test($param = new Foo) {}

#[AnAttribute(new Foo)]
class Test {
public function
__construct(
public
$prop = new Foo,
) {}
}
// Всё не допустимо (ошибка во времени компиляции):
function test(
$a = new (CLASS_NAME_CONSTANT)(), // динамическое имя класса
$b = new class {}, // анонимный класс
$c = new A(...[]), // распаковка аргументов
$d = new B($abc), // неподдерживаемое постоянное выражение
) {}
?>

Статические методы создания объекта

PHP поддерживает только один конструктор для класса. Однако в некоторых случаях есть необходимость создавать объект разными путями в зависимости от разных входных данных. Рекомендуемый способ - использовать статические методы как обёртки над конструктором.

Пример #5 Использование статических методов для создания объектов

<?php
class Product {

private ?
int $id;
private ?
string $name;

private function
__construct(?int $id = null, ?string $name = null) {
$this->id = $id;
$this->name = $name;
}

public static function
fromBasicData(int $id, string $name): static {
$new = new static($id, $name);
return
$new;
}

public static function
fromJson(string $json): static {
$data = json_decode($json);
return new static(
$data['id'], $data['name']);
}

public static function
fromXml(string $xml): static {
// Пользовательская логика.
$data = convert_xml_to_array($xml);
$new = new static();
$new->id = $data['id'];
$new->name = $data['name'];
return
$new;
}
}

$p1 = Product::fromBasicData(5, 'Widget');
$p2 = Product::fromJson($some_json_string);
$p3 = Product::fromXml($some_xml_string);

Конструктор можно сделать скрытым или защищённым для предотвращения его прямого вызова. В таком случае объект класса можно будет создать только с помощью статических методов. Так как это методы того же класса, они имеют доступ ко всем его скрытым методам, даже если они относятся к разным экземплярам класса. Скрытый конструктор опционален и может присутствовать или отсутствовать по необходимости.

В примере выше три публичных статических метода демонстрируют различные способы создания экземпляра объекта.

  • fromBasicData() принимает явные параметры, создаёт экземпляр класса через конструктор и возвращает объект.
  • fromJson() принимает JSON строку, производит над ней некоторые преобразования, извлекает данные необходимые для создания объекта и, так же как и предыдущий метод, вызывает конструктор и возвращает созданный объект.
  • fromXml() принимает XML строку, извлекает нужные данные и, так как в конструкторе нет обязательных параметров, вызывает его без них. После этого, так как ему доступны скрытые свойства, он присваивает им значения напрямую. После чего возвращает готовый объект.

Во всех трёх случаях, ключевое слово static транслируется в имя класса, в котором этот код вызывается. В нашем случае Product.

Деструкторы

__destruct(): void

PHP предоставляет концепцию деструктора, аналогичную с той, которая применяется в других ОО-языках, таких как C++. Деструктор будет вызван при освобождении всех ссылок на определённый объект или при завершении скрипта (порядок выполнения деструкторов не гарантируется).

Пример #6 Пример использования деструктора

<?php
class MyDestructableClass
{
function
__construct() {
print
"Конструктор\n";
}

function
__destruct() {
print
"Уничтожается " . __CLASS__ . "\n";
}
}

$obj = new MyDestructableClass();

Как и в случае с конструкторами, деструкторы, объявленные в родительском классе, не будут вызываться автоматически. Для вызова деструктора родительского класса, требуется вызвать parent::__destruct() в теле деструктора дочернего класса. Подобно конструкторам, дочерний класс может унаследовать деструктор из родительского класса, если он не определён в нем.

Деструктор будет вызываться даже в том случае, если скрипт был остановлен с помощью функции exit(). Вызов exit() в деструкторе предотвратит запуск всех последующих функций завершения.

Замечание:

Деструкторы, вызываемые при завершении скрипта, вызываются после отправки HTTP-заголовков. Рабочая директория во время фазы завершения скрипта может отличаться в некоторых SAPI (например, в Apache).

Замечание:

Попытка выбросить исключение из деструктора (вызываемого во время завершения скрипта) вызывает фатальную ошибку.



Область видимости

Область видимости свойства, метода или константы (начиная c PHP 7.1.0) может быть определена путём использования следующих ключевых слов в объявлении: public, protected или private. Доступ к свойствам и методам класса, объявленным как public (общедоступный), разрешён отовсюду. Модификатор protected (защищённый) разрешает доступ самому классу, наследующим его классам и родительским классам. Модификатор private (закрытый) ограничивает область видимости так, что только класс, где объявлен сам элемент, имеет к нему доступ.

Область видимости свойства

Свойства класса могут быть определены как public, private или protected. Свойства, объявленные без явного ключевого слова области видимости, определяются как общедоступные (public).

Пример #1 Объявление свойства класса

<?php
/**
* Определение MyClass
*/
class MyClass
{
public
$public = 'Public';
protected
$protected = 'Protected';
private
$private = 'Private';

function
printHello()
{
echo
$this->public;
echo
$this->protected;
echo
$this->private;
}
}

$obj = new MyClass();
echo
$obj->public; // Работает
echo $obj->protected; // Неисправимая ошибка
echo $obj->private; // Неисправимая ошибка
$obj->printHello(); // Выводит Public, Protected и Private


/**
* Определение MyClass2
*/
class MyClass2 extends MyClass
{
// Мы можем переопределить общедоступные и защищённые свойства, но не закрытые
public $public = 'Public2';
protected
$protected = 'Protected2';

function
printHello()
{
echo
$this->public;
echo
$this->protected;
echo
$this->private;
}
}

$obj2 = new MyClass2();
echo
$obj2->public; // Работает
echo $obj2->private; // Неопределён
echo $obj2->protected; // Неисправимая ошибка
$obj2->printHello(); // Выводит Public2, Protected2, Undefined

?>

Область видимости метода

Методы класса могут быть определены как public, private или protected. Методы, объявленные без указания области видимости, определяются как public.

Пример #2 Объявление метода

<?php
/**
* Определение MyClass
*/
class MyClass
{
// Объявление общедоступного конструктора
public function __construct() { }

// Объявление общедоступного метода
public function MyPublic() { }

// Объявление защищённого метода
protected function MyProtected() { }

// Объявление закрытого метода
private function MyPrivate() { }

// Это общедоступный метод
function Foo()
{
$this->MyPublic();
$this->MyProtected();
$this->MyPrivate();
}
}

$myclass = new MyClass;
$myclass->MyPublic(); // Работает
$myclass->MyProtected(); // Неисправимая ошибка
$myclass->MyPrivate(); // Неисправимая ошибка
$myclass->Foo(); // Работает общедоступный, защищённый и закрытый


/**
* Определение MyClass2
*/
class MyClass2 extends MyClass
{
// Это общедоступный метод
function Foo2()
{
$this->MyPublic();
$this->MyProtected();
$this->MyPrivate(); // Неисправимая ошибка
}
}

$myclass2 = new MyClass2;
$myclass2->MyPublic(); // Работает
$myclass2->Foo2(); // Работает общедоступный и защищённый, закрытый не работает

class Bar
{
public function
test() {
$this->testPrivate();
$this->testPublic();
}

public function
testPublic() {
echo
"Bar::testPublic\n";
}

private function
testPrivate() {
echo
"Bar::testPrivate\n";
}
}

class
Foo extends Bar
{
public function
testPublic() {
echo
"Foo::testPublic\n";
}

private function
testPrivate() {
echo
"Foo::testPrivate\n";
}
}

$myFoo = new Foo();
$myFoo->test(); // Bar::testPrivate
// Foo::testPublic
?>

Область видимости констант

Начиная с PHP 7.1.0, константы класса могут быть определены как public, private или protected. Константы, объявленные без указания области видимости, определяются как public.

Пример #3 Объявление констант, начиная с PHP 7.1.0

<?php
/**
* Объявление класса MyClass
*/
class MyClass
{
// Объявление общедоступной константы
public const MY_PUBLIC = 'public';

// Объявление защищённой константы
protected const MY_PROTECTED = 'protected';

// Объявление закрытой константы
private const MY_PRIVATE = 'private';

public function
foo()
{
echo
self::MY_PUBLIC;
echo
self::MY_PROTECTED;
echo
self::MY_PRIVATE;
}
}

$myclass = new MyClass();
MyClass::MY_PUBLIC; // Работает
MyClass::MY_PROTECTED; // Неисправимая ошибка
MyClass::MY_PRIVATE; // Неисправимая ошибка
$myclass->foo(); // Выводятся константы public, protected и private


/**
* Объявление класса MyClass2
*/
class MyClass2 extends MyClass
{
// Публичный метод
function foo2()
{
echo
self::MY_PUBLIC;
echo
self::MY_PROTECTED;
echo
self::MY_PRIVATE; // Неисправимая ошибка
}
}

$myclass2 = new MyClass2;
echo
MyClass2::MY_PUBLIC; // Работает
$myclass2->foo2(); // Выводятся константы public и protected, но не private
?>

Видимость из других объектов

Объекты, которые имеют общий тип (наследуются от одного класса), имеют доступ к элементам с модификаторами private и protected друг друга, даже если не являются одним и тем же экземпляром. Это объясняется тем, что реализация видимости элементов известна внутри этих объектов.

Пример #4 Доступ к элементам с модификатором private из объектов одного типа

<?php
class Test
{
private
$foo;

public function
__construct($foo)
{
$this->foo = $foo;
}

private function
bar()
{
echo
'Доступ к закрытому методу.';
}

public function
baz(Test $other)
{
// Мы можем изменить закрытое свойство:
$other->foo = 'привет';
var_dump($other->foo);

// Мы также можем вызвать закрытый метод:
$other->bar();
}
}

$test = new Test('test');

$test->baz(new Test('other'));
?>

Результат выполнения данного примера:

string(6) "привет"
Доступ к закрытому методу.


Наследование

Наследование — это хорошо зарекомендовавший себя принцип программирования, и PHP использует этот принцип в своей объектной модели. Этот принцип повлияет на то, как многие классы и объекты связаны друг с другом.

Например, при расширении класса дочерний класс наследует все общедоступные и защищённые методы, свойства и константы родительского класса. До тех пор пока эти методы не будут переопределены, они будут сохранять свою исходную функциональность.

Это полезно для определения и абстрагирования функциональности и позволяет реализовать дополнительную функциональность в похожих объектах без необходимости реализовывать всю общую функциональность.

Закрытые методы родительского класса недоступны для дочернего класса. В результате дочерние классы могут повторно реализовать закрытый метод без учёта обычных правил наследования. Однако до PHP 8.0.0 к закрытым методам применялись ограничения final и static. Начиная с PHP 8.0.0, единственное ограничение закрытого метода, которое применяется - это конструкторы private final, поскольку это обычный способ "отключить" конструктор при использовании вместо него статичных фабричных методов.

Видимость методов, свойств и констант можно ослабить, например, защищённый метод может быть помечен как общедоступный, но нельзя ограничить видимость, например, нельзя пометить общедоступное свойство как закрытое. Исключением являются конструкторы, видимость которых может быть ограничена, например, общедоступный конструктор может быть помечен как закрытый в дочернем классе.

Замечание:

Если не используется автозагрузка, классы должны быть объявлены до того, как они будут использоваться. Если класс расширяет другой, то родительский класс должен быть объявлен до наследующего класса. Это правило применяется к классам, которые наследуют другие классы или интерфейсы.

Замечание:

Не разрешается переопределять свойство чтения-записи с помощью readonly-свойства или наоборот.

<?php
class A {
public
int $prop;
}
class
B extends A {
// Нельзя: read-write -> readonly
public readonly int $prop;
}
?>

Пример #1 Пример наследования

<?php

class Foo
{
public function
printItem($string)
{
echo
'Foo: ' . $string . PHP_EOL;
}

public function
printPHP()
{
echo
'PHP просто супер.' . PHP_EOL;
}
}

class
Bar extends Foo
{
public function
printItem($string)
{
echo
'Bar: ' . $string . PHP_EOL;
}
}

$foo = new Foo();
$bar = new Bar();
$foo->printItem('baz'); // Выведет: 'Foo: baz'
$foo->printPHP(); // Выведет: 'PHP просто супер'
$bar->printItem('baz'); // Выведет: 'Bar: baz'
$bar->printPHP(); // Выведет: 'PHP просто супер'

?>

Совместимость типов возвращаемых значений с внутренними классами

До PHP 8.1.0 большинство внутренних классов или методов не объявляли свои типы возвращаемых значений и при их расширении допускался любой тип возвращаемого значения.

Начиная с PHP 8.1.0, большинство внутренних методов начали "предварительно" объявлять тип возвращаемого значения. В этом случае тип возвращаемого значения методов должен быть совместим с расширяемым родителем; в противном случае выдаётся уведомление об устаревании. Обратите внимание, что отсутствие явного объявления типа возвращаемого значения также считается несоответствием сигнатуры и, соответственно, приводит к уведомлению об устаревании.

Если тип возвращаемого значения не может быть объявлен для переопределяемого метода из-за проблем с совместимостью с различными версиями PHP, может быть добавлен атрибут ReturnTypeWillChange, чтобы заглушить уведомление об устаревании.

Пример #2 Переопределяющий метод не объявляет никакого типа возвращаемого значения

<?php
class MyDateTime extends DateTime
{
public function
modify(string $modifier) { return false; }
}

// "Deprecated: Return type of MyDateTime::modify(string $modifier) should either be compatible with DateTime::modify(string $modifier): DateTime|false, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice", начиная с PHP 8.1.0
?>

Пример #3 Переопределяющий метод объявляет неверный тип возвращаемого значения

<?php
class MyDateTime extends DateTime
{
public function
modify(string $modifier): ?DateTime { return null; }
}

// "Deprecated: Return type of MyDateTime::modify(string $modifier): ?DateTime should either be compatible with DateTime::modify(string $modifier): DateTime|false, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice", начиная с PHP 8.1.0
?>

Пример #4 Переопределяющий метод объявляет неверный тип возвращаемого значения без уведомления об устаревании

<?php
class MyDateTime extends DateTime
{
/**
* @return DateTime|false
*/
#[\ReturnTypeWillChange]
public function modify(string $modifier) { return false; }
}

// Уведомление об устаревании не выводится
?>


Оператор разрешения области видимости (::)

Оператор разрешения области видимости (также называемый "Paamayim Nekudotayim") или просто "двойное двоеточие" - это лексема, позволяющая обращаться к статическим свойствам, константам и переопределённым свойствам или методам класса.

При обращении к этим элементам извне класса, необходимо использовать имя этого класса.

Можно обратиться к классу с помощью переменной. Значение переменной не должно быть ключевым словом (например, self, parent или static).

"Paamayim Nekudotayim" на первый взгляд может показаться странным словосочетанием для обозначения двойного двоеточия. Однако, во время создания Zend Engine версии 0.5 (который входил в PHP3), команда Zend выбрала именно это обозначение. Оно на самом деле означает "двойное двоеточие" - на иврите!

Пример #1 Использование :: вне объявления класса

<?php
class MyClass {
const
CONST_VALUE = 'Значение константы';
}

$classname = 'MyClass';
echo
$classname::CONST_VALUE;

echo
MyClass::CONST_VALUE;
?>

Для обращения к свойствам и методам внутри самого класса используются ключевые слова self, parent и static.

Пример #2 Использование :: внутри объявления класса

<?php
class OtherClass extends MyClass
{
public static
$my_static = 'статическая переменная';

public static function
doubleColon() {
echo
parent::CONST_VALUE . "\n";
echo
self::$my_static . "\n";
}
}

$classname = 'OtherClass';
$classname::doubleColon();

OtherClass::doubleColon();
?>

Когда дочерний класс переопределяет методы, объявленные в родительском классе, PHP не будет осуществлять автоматический вызов методов, принадлежащих классу-родителю. Эта функциональность возлагается на метод, переопределяемый в дочернем классе. Данное правило распространяется на конструкторы и деструкторы, перегруженные и "магические" методы.

Пример #3 Обращение к методу в родительском классе

<?php
class MyClass
{
protected function
myFunc() {
echo
"MyClass::myFunc()\n";
}
}

class
OtherClass extends MyClass
{
// Переопределить родительское определение
public function myFunc()
{
// Но всё ещё вызываем родительскую функцию
parent::myFunc();
echo
"OtherClass::myFunc()\n";
}
}

$class = new OtherClass();
$class->myFunc();
?>

Смотрите также некоторые примеры статических вызовов.



Ключевое слово static

Подсказка

Эта страница описывает использование ключевого слова static для определения статических методов и свойств. static также может использоваться для определения статических переменных, определения статических анонимных функций и позднего статического связывания. Для получения информации о таком применении ключевого слова static обратитесь по вышеуказанным страницам.

Объявление свойств и методов класса статическими позволяет обращаться к ним без создания экземпляра класса. К ним также можно получить доступ статически в созданном экземпляре объекта класса.

Статические методы

Так как статические методы вызываются без создания экземпляра класса, то псевдопеременная $this недоступна внутри статических методов.

Внимание

Вызов нестатических методов статически вызывает ошибку Error.

До PHP 8.0.0 вызов нестатических методов статически был объявлен устаревшим и вызывал ошибку уровня E_DEPRECATED.

Пример #1 Пример статического метода

<?php
class Foo {
public static function
aStaticMethod() {
// ...
}
}

Foo::aStaticMethod();
$classname = 'Foo';
$classname::aStaticMethod();
?>

Статические свойства

Доступ к статическим свойствам осуществляется с помощью оператора разрешения области видимости (::), и к ним нельзя получить доступ через оператор объекта (->).

На класс можно ссылаться с помощью переменной. Значение переменной в таком случае не может быть ключевым словом (например, self, parent и static).

Пример #2 Пример статического свойства

<?php
class Foo
{
public static
$my_static = 'foo';

public function
staticValue() {
return
self::$my_static;
}
}

class
Bar extends Foo
{
public function
fooStatic() {
return
parent::$my_static;
}
}


print
Foo::$my_static . "\n";

$foo = new Foo();
print
$foo->staticValue() . "\n";
print
$foo->my_static . "\n"; // Не определено свойство my_static

print $foo::$my_static . "\n";
$classname = 'Foo';
print
$classname::$my_static . "\n";

print
Bar::$my_static . "\n";
$bar = new Bar();
print
$bar->fooStatic() . "\n";
?>

Результат выполнения данного примера в PHP 8 аналогичен:

foo
foo

Notice: Accessing static property Foo::$my_static as non static in /in/V0Rvv on line 23

Warning: Undefined property: Foo::$my_static in /in/V0Rvv on line 23

foo
foo
foo
foo


Абстрактные классы

PHP поддерживает определение абстрактных классов и методов. На основе абстрактного класса нельзя создавать объекты, и любой класс, содержащий хотя бы один абстрактный метод, должен быть определён как абстрактный. Методы, объявленные абстрактными, несут, по существу, лишь описательный смысл и не могут включать реализацию.

При наследовании от абстрактного класса, все методы, помеченные абстрактными в родительском классе, должны быть определены в дочернем классе и следовать обычным правилам наследования и совместимости сигнатуры.

Пример #1 Пример абстрактного класса

<?php
abstract class AbstractClass
{
// Данные методы должны быть определены в дочернем классе
abstract protected function getValue();
abstract protected function
prefixValue($prefix);

// Общий метод
public function printOut() {
print
$this->getValue() . "\n";
}
}

class
ConcreteClass1 extends AbstractClass
{
protected function
getValue() {
return
"ConcreteClass1";
}

public function
prefixValue($prefix) {
return
"{$prefix}ConcreteClass1";
}
}

class
ConcreteClass2 extends AbstractClass
{
public function
getValue() {
return
"ConcreteClass2";
}

public function
prefixValue($prefix) {
return
"{$prefix}ConcreteClass2";
}
}

$class1 = new ConcreteClass1;
$class1->printOut();
echo
$class1->prefixValue('FOO_') ."\n";

$class2 = new ConcreteClass2;
$class2->printOut();
echo
$class2->prefixValue('FOO_') ."\n";
?>

Результат выполнения данного примера:

ConcreteClass1
FOO_ConcreteClass1
ConcreteClass2
FOO_ConcreteClass2

Пример #2 Пример абстрактного класса

<?php
abstract class AbstractClass
{
// Наш абстрактный метод требует только определить необходимые аргументы
abstract protected function prefixName($name);

}

class
ConcreteClass extends AbstractClass
{

// Наш дочерний класс может определить необязательные аргументы, не указанные в объявлении родительского метода
public function prefixName($name, $separator = ".") {
if (
$name == "Pacman") {
$prefix = "Mr";
} elseif (
$name == "Pacwoman") {
$prefix = "Mrs";
} else {
$prefix = "";
}
return
"{$prefix}{$separator} {$name}";
}
}

$class = new ConcreteClass;
echo
$class->prefixName("Pacman"), "\n";
echo
$class->prefixName("Pacwoman"), "\n";
?>

Результат выполнения данного примера:

Mr. Pacman
Mrs. Pacwoman


Интерфейсы объектов

Интерфейсы объектов позволяют создавать код, который указывает, какие методы должен реализовать класс, без необходимости определять, как именно они должны быть реализованы. Интерфейсы разделяют пространство имён с классами и трейтами, поэтому они не могут называться одинаково.

Интерфейсы объявляются так же, как и обычные классы, но с использованием ключевого слова interface вместо class. Тела методов интерфейсов должны быть пустыми.

Все методы, определённые в интерфейсах, должны быть общедоступными, что следует из самой природы интерфейса.

На практике интерфейсы используются в двух взаимодополняющих случаях:

  • Чтобы позволить разработчикам создавать объекты разных классов, которые могут использоваться взаимозаменяемо, поскольку они реализуют один и тот же интерфейс или интерфейсы. Типичный пример - несколько служб доступа к базе данных, несколько платёжных шлюзов или разных стратегий кеширования. Различные реализации могут быть заменены без каких-либо изменений в коде, который их использует.
  • Чтобы разрешить функции или методу принимать и оперировать параметром, который соответствует интерфейсу, не заботясь о том, что ещё может делать объект или как он реализован. Эти интерфейсы часто называют Iterable, Cacheable, Renderable и так далее, чтобы описать их поведение.

Интерфейсы могут определять магические методы, требуя от реализующих классов реализации этих методов.

Замечание:

Хотя они поддерживаются, использование конструкторов в интерфейсах настоятельно не рекомендуется. Это значительно снижает гибкость объекта, реализующего интерфейс. Кроме того, к конструкторам не применяются правила наследования, что может привести к противоречивому и неожиданному поведению.

implements

Для реализации интерфейса используется оператор implements. Класс должен реализовать все методы, описанные в интерфейсе, иначе произойдёт фатальная ошибка. При желании классы могут реализовывать более одного интерфейса, разделяя каждый интерфейс запятой.

Внимание

Класс, реализующий интерфейс, может использовать для своих параметров имя, отличное от имени интерфейса. Однако, начиная с PHP 8.0, в языке поддерживаются именованные аргументы, и вызывающий код может полагаться на имя параметра в интерфейсе. По этой причине настоятельно рекомендуется, чтобы разработчики использовали те же имена параметров, что и реализуемый интерфейс.

Замечание:

Интерфейсы могут быть унаследованы друг от друга, так же, как и классы, с помощью оператора extends.

Замечание:

Класс, реализующий интерфейс, должен объявить все методы в интерфейсе с совместимой сигнатурой. Класс может реализовывать несколько интерфейсов, которые объявляют метод с одинаковым именем. В этом случае реализация должна следовать правилам совместимости сигнатуры для всех интерфейсов. Таким образом, можно применять ковариантность и контравариантность.

Константы

Интерфейсы могут содержать константы. Константы интерфейсов работают точно так же, как и константы классов. До PHP 8.1.0 они не могли быть переопределены классом или интерфейсом, который их наследует.

Примеры

Пример #1 Пример интерфейса

<?php

// Объявим интерфейс 'Template'
interface Template
{
public function
setVariable($name, $var);
public function
getHtml($template);
}

// Реализация интерфейса
// Это будет работать
class WorkingTemplate implements Template
{
private
$vars = [];

public function
setVariable($name, $var)
{
$this->vars[$name] = $var;
}

public function
getHtml($template)
{
foreach(
$this->vars as $name => $value) {
$template = str_replace('{' . $name . '}', $value, $template);
}

return
$template;
}
}

// Это не будет работать
// Fatal error: Class BadTemplate contains 1 abstract methods
// and must therefore be declared abstract (Template::getHtml)
// (Фатальная ошибка: Класс BadTemplate содержит 1 абстрактный метод
// и поэтому должен быть объявлен абстрактным (Template::getHtml))
class BadTemplate implements Template
{
private
$vars = [];

public function
setVariable($name, $var)
{
$this->vars[$name] = $var;
}
}
?>

Пример #2 Наследование интерфейсов

<?php
interface A
{
public function
foo();
}

interface
B extends A
{
public function
baz(Baz $baz);
}

// Это сработает
class C implements B
{
public function
foo()
{
}

public function
baz(Baz $baz)
{
}
}

// Это не сработает и выдаст фатальную ошибку
class D implements B
{
public function
foo()
{
}

public function
baz(Foo $foo)
{
}
}
?>

Пример #3 Совместимость с несколькими интерфейсами

<?php
class Foo {}
class
Bar extends Foo {}

interface
A {
public function
myfunc(Foo $arg): Foo;
}

interface
B {
public function
myfunc(Bar $arg): Bar;
}

class
MyClass implements A, B
{
public function
myfunc(Foo $arg): Bar
{
return new
Bar();
}
}
?>

Пример #4 Множественное наследование интерфейсов

<?php
interface A
{
public function
foo();
}

interface
B
{
public function
bar();
}

interface
C extends A, B
{
public function
baz();
}

class
D implements C
{
public function
foo()
{
}

public function
bar()
{
}

public function
baz()
{
}
}
?>

Пример #5 Интерфейсы с константами

<?php
interface A
{
const
B = 'Константа интерфейса';
}

// Выведет: Константа интерфейса
echo A::B;


class
B implements A
{
const
B = 'Константа класса';
}

// Выведет: Константа класса
// До PHP 8.1.0 этот код не будет работать,
// потому что было нельзя переопределять константы.
echo B::B;
?>

Пример #6 Интерфейсы с абстрактными классами

<?php
interface A
{
public function
foo(string $s): string;

public function
bar(int $i): int;
}

// Абстрактный класс может реализовывать только часть интерфейса.
// Классы, расширяющие абстрактный класс, должны реализовать все остальные.
abstract class B implements A
{
public function
foo(string $s): string
{
return
$s . PHP_EOL;
}
}

class
C extends B
{
public function
bar(int $i): int
{
return
$i * 2;
}
}
?>

Пример #7 Одновременное расширение и внедрение

<?php

class One
{
/* ... */
}

interface
Usable
{
/* ... */
}

interface
Updatable
{
/* ... */
}

// Порядок ключевых слов здесь важен. "extends" должно быть первым.
class Two extends One implements Usable, Updatable
{
/* ... */
}
?>

Интерфейс, совместно с объявлениями типов, предоставляет отличный способ проверки того, что определённый объект содержит определённый набор методов. Смотрите также оператор instanceof и объявление типов.



Трейты

PHP реализует метод для повторного использования кода под названием трейт (trait).

Трейт - это механизм обеспечения повторного использования кода в языках с поддержкой только одиночного наследования, таких как PHP. Трейт предназначен для уменьшения некоторых ограничений одиночного наследования, позволяя разработчику повторно использовать наборы методов свободно, в нескольких независимых классах и реализованных с использованием разных архитектур построения классов. Семантика комбинации трейтов и классов определена таким образом, чтобы снизить уровень сложности, а также избежать типичных проблем, связанных с множественным наследованием и смешиванием (mixins).

Трейт очень похож на класс, но предназначен для группирования функционала хорошо структурированным и последовательным образом. Невозможно создать самостоятельный экземпляр трейта. Это дополнение к обычному наследованию и позволяет сделать горизонтальную композицию поведения, то есть применение членов класса без необходимости наследования.

Пример #1 Пример использования трейта

<?php
trait ezcReflectionReturnInfo {
function
getReturnType() { /*1*/ }
function
getReturnDescription() { /*2*/ }
}

class
ezcReflectionMethod extends ReflectionMethod {
use
ezcReflectionReturnInfo;
/* ... */
}

class
ezcReflectionFunction extends ReflectionFunction {
use
ezcReflectionReturnInfo;
/* ... */
}
?>

Приоритет

Наследуемый член из базового класса переопределяется членом, находящимся в трейте. Порядок приоритета следующий: члены из текущего класса переопределяют методы в трейте, которые в свою очередь переопределяют унаследованные методы.

Пример #2 Пример приоритета старшинства

Наследуемый метод от базового класса переопределяется методом, добавленным в MyHelloWorld из трейта SayWorld. Поведение такое же как и для методов, определённых в классе MyHelloWorld. Порядок приоритета такой: методы из текущего класса переопределяют методы трейта, которые в свою очередь переопределяют методы из базового класса.

<?php
class Base {
public function
sayHello() {
echo
'Hello ';
}
}

trait
SayWorld {
public function
sayHello() {
parent::sayHello();
echo
'World!';
}
}

class
MyHelloWorld extends Base {
use
SayWorld;
}

$o = new MyHelloWorld();
$o->sayHello();
?>

Результат выполнения данного примера:

Hello World!

Пример #3 Пример альтернативного порядка приоритета

<?php
trait HelloWorld {
public function
sayHello() {
echo
'Hello World!';
}
}

class
TheWorldIsNotEnough {
use
HelloWorld;
public function
sayHello() {
echo
'Hello Universe!';
}
}

$o = new TheWorldIsNotEnough();
$o->sayHello();
?>

Результат выполнения данного примера:

Hello Universe!

Несколько трейтов

В класс можно добавить несколько трейтов, перечислив их в директиве use через запятую.

Пример #4 Пример использования нескольких трейтов

<?php
trait Hello {
public function
sayHello() {
echo
'Hello ';
}
}

trait
World {
public function
sayWorld() {
echo
'World';
}
}

class
MyHelloWorld {
use
Hello, World;
public function
sayExclamationMark() {
echo
'!';
}
}

$o = new MyHelloWorld();
$o->sayHello();
$o->sayWorld();
$o->sayExclamationMark();
?>

Результат выполнения данного примера:

Hello World!

Разрешение конфликтов

Если два трейта добавляют метод с одним и тем же именем, это приводит к фатальной ошибке в случае, если конфликт явно не разрешён.

Для разрешения конфликтов именования между трейтами, используемыми в одном и том же классе, необходимо использовать оператор insteadof для того, чтобы точно выбрать один из конфликтующих методов.

Так как предыдущий оператор позволяет только исключать методы, оператор as может быть использован для включения одного из конфликтующих методов под другим именем. Обратите внимание, что оператор as не переименовывает метод и не влияет на какой-либо другой метод.

Пример #5 Пример разрешения конфликтов

В этом примере Talker использует трейты A и B. Так как в A и B есть конфликтующие методы, он использует вариант smallTalk из трейта B, а вариант bigTalk - из трейта A.

Класс Aliased_Talker применяет оператор as, чтобы получить возможность использовать реализацию bigTalk из B под дополнительным псевдонимом talk.

<?php
trait A {
public function
smallTalk() {
echo
'a';
}
public function
bigTalk() {
echo
'A';
}
}

trait
B {
public function
smallTalk() {
echo
'b';
}
public function
bigTalk() {
echo
'B';
}
}

class
Talker {
use
A, B {
B::smallTalk insteadof A;
A::bigTalk insteadof B;
}
}

class
Aliased_Talker {
use
A, B {
B::smallTalk insteadof A;
A::bigTalk insteadof B;
B::bigTalk as talk;
}
}
?>

Изменение видимости метода

Используя синтаксис оператора as, можно также изменить видимость метода в использующем трейт классе.

Пример #6 Пример изменения видимости метода

<?php
trait HelloWorld {
public function
sayHello() {
echo
'Hello World!';
}
}

// Изменение видимости метода sayHello
class MyClass1 {
use
HelloWorld { sayHello as protected; }
}

// Создание псевдонима метода с изменённой видимостью
// видимость sayHello не изменилась
class MyClass2 {
use
HelloWorld { sayHello as private myPrivateHello; }
}
?>

Трейты, состоящие из трейтов

Трейты могут использоваться как в классах, так и в других трейтах. Используя один или более трейтов в определении другого трейта, он может частично или полностью состоять из членов, определённых в этих трейтах.

Пример #7 Пример трейтов, составленных из трейтов

<?php
trait Hello {
public function
sayHello() {
echo
'Hello ';
}
}

trait
World {
public function
sayWorld() {
echo
'World!';
}
}

trait
HelloWorld {
use
Hello, World;
}

class
MyHelloWorld {
use
HelloWorld;
}

$o = new MyHelloWorld();
$o->sayHello();
$o->sayWorld();
?>

Результат выполнения данного примера:

Hello World!

Абстрактные члены трейтов

Трейты поддерживают использование абстрактных методов для того, чтобы установить требования к использующему классу. Поддерживаются общедоступные, защищённые и закрытые методы. До PHP 8.0.0 поддерживались только общедоступные и защищённые абстрактные методы.

Предостережение

Конкретный класс исполняет эти требования путём определения конкретного метода с тем же именем; при этом сигнатура метода может отличаться.

Пример #8 Требования трейта при помощи абстрактных методов

<?php
trait Hello {
public function
sayHelloWorld() {
echo
'Hello'.$this->getWorld();
}
abstract public function
getWorld();
}

class
MyHelloWorld {
private
$world;
use
Hello;
public function
getWorld() {
return
$this->world;
}
public function
setWorld($val) {
$this->world = $val;
}
}
?>

Статические члены трейта

В трейтах можно определять статические переменные, статические методы и статические свойства.

Замечание:

Начиная с PHP 8.1.0, вызов статического метода или доступ к статическому свойству непосредственно в трейте устарел. К статическим методам и свойствам следует обращаться только в классе, использующем трейт.

Пример #9 Статические переменные

<?php
trait Counter {
public function
inc() {
static
$c = 0;
$c = $c + 1;
echo
"$c\n";
}
}

class
C1 {
use
Counter;
}

class
C2 {
use
Counter;
}

$o = new C1(); $o->inc(); // echo 1
$p = new C2(); $p->inc(); // echo 1
?>

Пример #10 Статические методы

<?php
trait StaticExample {
public static function
doSomething() {
return
'Что-либо делаем';
}
}

class
Example {
use
StaticExample;
}

Example::doSomething();
?>

Пример #11 Статические свойства

<?php
trait StaticExample {
public static
$static = 'foo';
}
class
Example {
use
StaticExample;
}
echo
Example::$static;
?>

Свойства

Трейты могут также определять свойства.

Пример #12 Определение свойств

<?php
trait PropertiesTrait {
public
$x = 1;
}

class
PropertiesExample {
use
PropertiesTrait;
}

$example = new PropertiesExample;
$example->x;
?>

Если трейт определяет свойство, то класс не может определить свойство с таким же именем, кроме случаев полного совпадения (та же область видимости и тип, модификатор readonly и начальное значение), иначе будет выброшена фатальная ошибка.

Пример #13 Разрешение конфликтов

<?php
trait PropertiesTrait {
public
$same = true;
public
$different1 = false;
public
bool $different2;
public
bool $different3;
}

class
PropertiesExample {
use
PropertiesTrait;
public
$same = true;
public
$different1 = true; // Фатальная ошибка
public string $different2; // Фатальная ошибка
readonly protected bool $different3; // Фатальная ошибка
}
?>

Константы

Начиная с версии PHP 8.2.0, трейты могут также определять константы.

Пример #14 Определение констант

<?php
trait ConstantsTrait {
public const
FLAG_MUTABLE = 1;
final public const
FLAG_IMMUTABLE = 5;
}

class
ConstantsExample {
use
ConstantsTrait;
}

$example = new ConstantsExample;
echo
$example::FLAG_MUTABLE; // 1
?>

Если трейт определяет константу, то класс не может определить константу с таким же именем, если только они не совместимы (одинаковая область видимости, начальное значение и модификатор final), иначе выбрасывается фатальная ошибка.

Пример #15 Разрешение конфликтов

<?php
trait ConstantsTrait {
public const
FLAG_MUTABLE = 1;
final public const
FLAG_IMMUTABLE = 5;
}

class
ConstantsExample {
use
ConstantsTrait;
public const
FLAG_IMMUTABLE = 5; // Фатальная ошибка
}
?>


Анонимные классы

Анонимные классы полезны, когда нужно создать простые, одноразовые объекты.

<?php

// Использование явного класса
class Logger
{
public function
log($msg)
{
echo
$msg;
}
}

$util->setLogger(new Logger());

// Использование анонимного класса
$util->setLogger(new class {
public function
log($msg)
{
echo
$msg;
}
});

Они могут передавать аргументы в конструкторы, расширять другие классы, реализовывать интерфейсы и использовать трейты как обычный класс:

<?php

class SomeClass {}
interface
SomeInterface {}
trait
SomeTrait {}

var_dump(new class(10) extends SomeClass implements SomeInterface {
private
$num;

public function
__construct($num)
{
$this->num = $num;
}

use
SomeTrait;
});

Результат выполнения данного примера:

object(class@anonymous)#1 (1) {
  ["Command line code0x104c5b612":"class@anonymous":private]=>
  int(10)
}

Вложение анонимного класса в другой класс не даёт ему доступ к закрытым или защищённым методам и свойствам этого внешнего класса. Для того, чтобы использовать защищённые свойства и методы внешнего класса, анонимный класс может расширить внешний класс. Чтобы использовать закрытые свойства внешнего класса в анонимном классе, их нужно передать в конструктор:

<?php

class Outer
{
private
$prop = 1;
protected
$prop2 = 2;

protected function
func1()
{
return
3;
}

public function
func2()
{
return new class(
$this->prop) extends Outer {
private
$prop3;

public function
__construct($prop)
{
$this->prop3 = $prop;
}

public function
func3()
{
return
$this->prop2 + $this->prop3 + $this->func1();
}
};
}
}

echo (new
Outer)->func2()->func3();

Результат выполнения данного примера:

6

Все объекты, созданные одним и тем же объявлением анонимного класса, являются экземплярами этого самого класса.

<?php
function anonymous_class()
{
return new class {};
}

if (
get_class(anonymous_class()) === get_class(anonymous_class())) {
echo
'Тот же класс';
} else {
echo
'Другой класс';
}

Результат выполнения данного примера:

Тот же класс

Замечание:

Обратите внимание, что анонимным классам присваиваются имена движком PHP, как показано в примере ниже. Это имя следует рассматривать как особенность реализации, на которую не следует полагаться.

<?php
echo get_class(new class {});

Результатом выполнения данного примера будет что-то подобное:

class@anonymous/in/oNi1A0x7f8636ad2021



Перегрузка

Перегрузка в PHP означает возможность динамически создавать свойства и методы. Эти динамические сущности обрабатываются с помощью магических методов, которые можно создать в классе для различных видов действий.

Методы перегрузки вызываются при взаимодействии со свойствами или методами, которые не были объявлены или не видны в текущей области видимости. Далее в этом разделе будут использоваться термины недоступные свойства или недоступные методы для обозначения этой комбинации объявления и области видимости.

Все методы перегрузки должны быть объявлены как public.

Замечание:

Ни один из аргументов этих магических методов не может быть передан по ссылке.

Замечание:

Интерпретация перегрузки в PHP отличается от большинства объектно-ориентированных языков. Традиционно перегрузка означает возможность иметь несколько одноимённых методов с разным количеством и типами аргументов.

Перегрузка свойств

public __set(string $name, mixed $value): void
public __get(string $name): mixed
public __isset(string $name): bool
public __unset(string $name): void

Метод __set() будет выполнен при записи данных в недоступные (защищённые или приватные) или несуществующие свойства.

Метод __get() будет выполнен при чтении данных из недоступных (защищённых или приватных) или несуществующих свойств.

Метод __isset() будет выполнен при использовании isset() или empty() на недоступных (защищённых или приватных) или несуществующих свойствах.

Метод __unset() будет выполнен при вызове unset() на недоступном (защищённом или приватном) или несуществующем свойстве.

Аргумент $name представляет собой имя вызываемого свойства. Метод __set() содержит аргумент $value, представляющий собой значение, которое будет записано в свойство с именем $name.

Перегрузка свойств работает только в контексте объекта. Данные магические методы не будут вызваны в статическом контексте. Поэтому эти методы не должны объявляться статическими. При объявлении любого магического метода как static будет выдано предупреждение.

Замечание:

Возвращаемое значение __set() будет проигнорировано из-за способа обработки в PHP оператора присваивания. Аналогично, __get() никогда не вызывается при объединении присваиваний, например, подобным образом:

 $a = $obj->b = 8;

Замечание:

PHP не будет вызывать перегруженный метод изнутри того же перегруженного метода. Это означает, что, например, написание return $this->foo внутри __get() вернёт null и вызовет ошибку уровня E_WARNING, если не определено свойство foo, вместо того, чтобы вызвать метод __get() во второй раз. Однако методы перегрузки могут неявно вызывать другие методы перегрузки (например, метод __set() вызывает метод __get()).

Пример #1 Перегрузка свойств с помощью методов __get(), __set(), __isset() и __unset()

<?php
class PropertyTest
{
/** Место хранения перегружаемых данных. */
private $data = array();

/** Перегрузка не применяется к объявленным свойствам. */
public $declared = 1;

/** Здесь перегрузка будет использована только при доступе вне класса. */
private $hidden = 2;

public function
__set($name, $value)
{
echo
"Установка '$name' в '$value'\n";
$this->data[$name] = $value;
}

public function
__get($name)
{
echo
"Получение '$name'\n";
if (
array_key_exists($name, $this->data)) {
return
$this->data[$name];
}

$trace = debug_backtrace();
trigger_error(
'Неопределённое свойство в __get(): ' . $name .
' в файле ' . $trace[0]['file'] .
' на строке ' . $trace[0]['line'],
E_USER_NOTICE);
return
null;
}

public function
__isset($name)
{
echo
"Установлено ли '$name'?\n";
return isset(
$this->data[$name]);
}

public function
__unset($name)
{
echo
"Уничтожение '$name'\n";
unset(
$this->data[$name]);
}

/** Не магический метод, просто для примера. */
public function getHidden()
{
return
$this->hidden;
}
}


echo
"<pre>\n";

$obj = new PropertyTest;

$obj->a = 1;
echo
$obj->a . "\n\n";

var_dump(isset($obj->a));
unset(
$obj->a);
var_dump(isset($obj->a));
echo
"\n";

echo
$obj->declared . "\n\n";

echo
"Давайте поэкспериментируем с закрытым свойством 'hidden':\n";
echo
"Закрытые свойства видны внутри класса, поэтому __get() не используется...\n";
echo
$obj->getHidden() . "\n";
echo
"Закрытые свойства не видны вне класса, поэтому __get() используется...\n";
echo
$obj->hidden . "\n";
?>

Результат выполнения данного примера:

Установка 'a' в '1'
Получение 'a'
1

Установлено ли 'a'?
bool(true)
Уничтожение 'a'
Установлено ли 'a'?
bool(false)

1

Давайте поэкспериментируем с закрытым свойством 'hidden':
Закрытые свойства видны внутри класса, поэтому __get() не используется...
2
Закрытые свойства не видны вне класса, поэтому __get() используется...
Получение 'hidden'


Notice: Неопределённое свойство в __get(): hidden в <file> on line 70 in <file> on line 29

Перегрузка методов

public __call(string $name, array $arguments): mixed
public static __callStatic(string $name, array $arguments): mixed

__call() запускается при вызове недоступных методов в контексте объект.

__callStatic() запускается при вызове недоступных методов в статическом контексте.

Аргумент $name представляет собой имя вызываемого метода. Аргумент $arguments представляет собой нумерованный массив, содержащий параметры, переданные в вызываемый метод $name.

Пример #2 Перегрузка методов с помощью методов __call() и __callStatic()

<?php
class MethodTest {
public function
__call($name, $arguments) {
// Замечание: значение $name регистрозависимо.
echo "Вызов метода '$name' "
. implode(', ', $arguments). "\n";
}

public static function
__callStatic($name, $arguments) {
// Замечание: значение $name регистрозависимо.
echo "Вызов статического метода '$name' "
. implode(', ', $arguments). "\n";
}
}

$obj = new MethodTest;
$obj->runTest('в контексте объекта');

MethodTest::runTest('в статическом контексте');
?>

Результат выполнения данного примера:

Вызов метода 'runTest' в контексте объекта
Вызов статического метода 'runTest' в статическом контексте


Итераторы объектов

PHP предоставляет такой способ объявления объектов, который даёт возможность пройти по списку элементов данного объекта, например, с помощью оператора foreach. По умолчанию, в этом обходе (итерации) будут участвовать все видимые свойства объекта.

Пример #1 Итерация простого объекта

<?php
class MyClass
{
public
$var1 = 'значение 1';
public
$var2 = 'значение 2';
public
$var3 = 'значение 3';

protected
$protected = 'защищённая переменная';
private
$private = 'закрытая переменная';

function
iterateVisible() {
echo
"MyClass::iterateVisible:\n";
foreach (
$this as $key => $value) {
print
"$key => $value\n";
}
}
}

$class = new MyClass();

foreach(
$class as $key => $value) {
print
"$key => $value\n";
}
echo
"\n";


$class->iterateVisible();

?>

Результат выполнения данного примера:

var1 => значение 1
var2 => значение 2
var3 => значение 3

MyClass::iterateVisible:
var1 => значение 1
var2 => значение 2
var3 => значение 3
protected => защищённая переменная
private => закрытая переменная

Как показывает результат, foreach проитерировал все доступные и принадлежащие объекту видимые свойства.



Магические методы

Магические методы - это специальные методы, которые переопределяют действие PHP по умолчанию, когда над объектом выполняются определённые действия.

Предостережение

Все имена методов, начинающиеся с __, зарезервированы PHP. Не рекомендуется использовать имена методов с __ в PHP, если вы не хотите использовать соответствующую магическую функциональность.

Следующие названия методов считаются магическими: __construct(), __destruct(), __call(), __callStatic(), __get(), __set(), __isset(), __unset(), __sleep(), __wakeup(), __serialize(), __unserialize(), __toString(), __invoke(), __set_state(), __clone() и __debugInfo()

Внимание

Все магические методы, за исключением __construct(), __destruct() и __clone(), ДОЛЖНЫ быть объявлены как public, в противном случае будет вызвана ошибка уровня E_WARNING. До PHP 8.0.0 для магических методов __sleep(), __wakeup(), __serialize(), __unserialize() и __set_state() не выполнялась проверка.

Внимание

Если объявления типа используются в определении магического метода, они должны быть идентичны сигнатуре, описанной в этом документе. В противном случае выдаётся фатальная ошибка. До PHP 8.0.0 диагностические сообщения не отправлялись. Однако __construct() и __destruct() не должны объявлять возвращаемый тип; в противном случае выдаётся фатальная ошибка.

__sleep() и __wakeup()

public __sleep(): array
public __wakeup(): void

Функция serialize() проверяет, присутствует ли в классе метод с магическим именем __sleep(). Если это так, то этот метод выполняется до любой операции сериализации. Он может очистить объект и должен возвращать массив с именами всех переменных этого объекта, которые должны быть сериализованы. Если метод ничего не возвращает, то сериализуется null и выдаётся предупреждение E_NOTICE.

Замечание:

Недопустимо возвращать в __sleep() имена закрытых свойств в родительском классе. Это приведёт к ошибке уровня E_NOTICE. Вместо этого вы можете использовать __serialize().

Предполагаемое использование __sleep() состоит в завершении работы над данными, ждущими обработки или других подобных задач очистки. Кроме того, этот метод может быть полезен, когда есть очень большие объекты, которые нет необходимости полностью сохранять.

С другой стороны, функция unserialize() проверяет наличие метода с магическим именем __wakeup(). Если она имеется, эта функция может восстанавливать любые ресурсы, которые может иметь объект.

Предполагаемое использование __wakeup() заключается в восстановлении любых соединений с базой данных, которые могли быть потеряны во время операции сериализации и выполнения других операций повторной инициализации.

Пример #1 Сериализация и десериализация

<?php
class Connection
{
protected
$link;
private
$dsn, $username, $password;

public function
__construct($dsn, $username, $password)
{
$this->dsn = $dsn;
$this->username = $username;
$this->password = $password;
$this->connect();
}

private function
connect()
{
$this->link = new PDO($this->dsn, $this->username, $this->password);
}

public function
__sleep()
{
return array(
'dsn', 'username', 'password');
}

public function
__wakeup()
{
$this->connect();
}
}
?>

__serialize() и __unserialize()

public __serialize(): array
public __unserialize(array $data): void

serialize() проверяет, есть ли в классе функция с магическим именем __serialize(). Если да, функция выполняется перед любой сериализацией. Она должна создать и вернуть ассоциативный массив пар ключ/значение, которые представляют сериализованную форму объекта. Если массив не возвращён, будет выдано TypeError.

Замечание:

Если и __serialize() и __sleep() определены в одном и том же объекте, будет вызван только метод __serialize(). __sleep() будет игнорироваться. Если объект реализует интерфейс Serializable, метод serialize() интерфейса будет игнорироваться, а вместо него будет использован __serialize().

Предполагаемое использование __serialize() заключается в определении удобного для сериализации произвольного представления объекта. Элементы массива могут соответствовать свойствам объекта, но это не обязательно.

И наоборот, unserialize() проверяет наличие магической функции __unserialize(). Если функция присутствует, ей будет передан восстановленный массив, который был возвращён из __serialize(). Затем он может восстановить свойства объекта из этого массива соответствующим образом.

Замечание:

Если и __unserialize() и __wakeup() определены в одном и том же объекте, будет вызван только метод __unserialize(). __wakeup() будет игнорироваться.

Замечание:

Функция доступна с PHP 7.4.0.

Пример #2 Сериализация и десериализация

<?php
class Connection
{
protected
$link;
private
$dsn, $username, $password;

public function
__construct($dsn, $username, $password)
{
$this->dsn = $dsn;
$this->username = $username;
$this->password = $password;
$this->connect();
}

private function
connect()
{
$this->link = new PDO($this->dsn, $this->username, $this->password);
}

public function
__serialize(): array
{
return [
'dsn' => $this->dsn,
'user' => $this->username,
'pass' => $this->password,
];
}

public function
__unserialize(array $data): void
{
$this->dsn = $data['dsn'];
$this->username = $data['user'];
$this->password = $data['pass'];

$this->connect();
}
}
?>

__toString()

public __toString(): string

Метод __toString() позволяет классу решать, как он должен реагировать при преобразовании в строку. Например, что вывести при выполнении echo $obj;.

Внимание

Начиная с PHP 8.0.0, возвращаемое значение следует стандартной семантике типа PHP, что означает, что оно будет преобразовано в строку (string), если возможно, и если strict typing отключён.

Начиная с PHP 8.0.0, любой класс, содержащий метод __toString(), также будет неявно реализовывать интерфейс Stringable и, таким образом, будет проходить проверку типа для этого интерфейса В любом случае рекомендуется явно реализовать интерфейс.

В PHP 7.4 возвращаемое значение ДОЛЖНО быть строкой (string), иначе выдаётся Error.

До PHP 7.4.0 возвращаемое значение должно быть строкой (string), в противном случае выдаётся фатальная ошибка E_RECOVERABLE_ERROR. is emitted.

Внимание

Нельзя выбросить исключение из метода __toString() до PHP 7.4.0. Это приведёт к фатальной ошибке.

Пример #3 Простой пример

<?php
// Объявление простого класса
class TestClass
{
public
$foo;

public function
__construct($foo)
{
$this->foo = $foo;
}

public function
__toString()
{
return
$this->foo;
}
}

$class = new TestClass('Привет');
echo
$class;
?>

Результат выполнения данного примера:

Привет

__invoke()

__invoke( ...$values): mixed

Метод __invoke() вызывается, когда скрипт пытается выполнить объект как функцию.

Пример #4 Использование __invoke()

<?php
class CallableClass
{
public function
__invoke($x)
{
var_dump($x);
}
}
$obj = new CallableClass;
$obj(5);
var_dump(is_callable($obj));
?>

Результат выполнения данного примера:

int(5)
bool(true)

Пример #5 Пример использования __invoke()

<?php
class Sort
{
private
$key;

public function
__construct(string $key)
{
$this->key = $key;
}

public function
__invoke(array $a, array $b): int
{
return
$a[$this->key] <=> $b[$this->key];
}
}

$customers = [
[
'id' => 1, 'first_name' => 'John', 'last_name' => 'Do'],
[
'id' => 3, 'first_name' => 'Alice', 'last_name' => 'Gustav'],
[
'id' => 2, 'first_name' => 'Bob', 'last_name' => 'Filipe']
];

// сортировка клиентов по имени
usort($customers, new Sort('first_name'));
print_r($customers);

// сортировка клиентов по фамилии
usort($customers, new Sort('last_name'));
print_r($customers);
?>

Результат выполнения данного примера:

Array
(
    [0] => Array
        (
            [id] => 3
            [first_name] => Alice
            [last_name] => Gustav
        )

    [1] => Array
        (
            [id] => 2
            [first_name] => Bob
            [last_name] => Filipe
        )

    [2] => Array
        (
            [id] => 1
            [first_name] => John
            [last_name] => Do
        )

)
Array
(
    [0] => Array
        (
            [id] => 1
            [first_name] => John
            [last_name] => Do
        )

    [1] => Array
        (
            [id] => 2
            [first_name] => Bob
            [last_name] => Filipe
        )

    [2] => Array
        (
            [id] => 3
            [first_name] => Alice
            [last_name] => Gustav
        )

)

__set_state()

static __set_state(array $properties): object

Этот статический метод вызывается для тех классов, которые экспортируются функцией var_export().

Единственным параметром этого метода является массив, содержащий экспортируемые свойства в виде ['property' => value, ...].

Пример #6 Использование __set_state()

<?php

class A
{
public
$var1;
public
$var2;

public static function
__set_state($an_array)
{
$obj = new A;
$obj->var1 = $an_array['var1'];
$obj->var2 = $an_array['var2'];
return
$obj;
}
}

$a = new A;
$a->var1 = 5;
$a->var2 = 'foo';

$b = var_export($a, true);
var_dump($b);
eval(
'$c = ' . $b . ';');
var_dump($c);
?>

Результат выполнения данного примера:

string(60) "A::__set_state(array(
   'var1' => 5,
   'var2' => 'foo',
))"
object(A)#2 (2) {
  ["var1"]=>
  int(5)
  ["var2"]=>
  string(3) "foo"
}

Замечание: При экспорте объекта var_export() не проверяет, реализует ли класс объекта метод __set_state(), поэтому повторный импорт объектов приведёт к исключению Error, если метод __set_state() не реализован. В частности, это относится к некоторым внутренним классам. Необходимость проверки, реализует ли импортируемый класс метод __set_state(), полностью лежит на разработчике.

__debugInfo()

__debugInfo(): array

Этот метод вызывается функцией var_dump(), когда необходимо вывести список свойств объекта. Если этот метод не определён, тогда будут выведены все свойства объекта c модификаторами public, protected и private.

Пример #7 Использование __debugInfo()

<?php
class C {
private
$prop;

public function
__construct($val) {
$this->prop = $val;
}

public function
__debugInfo() {
return [
'propSquared' => $this->prop ** 2,
];
}
}

var_dump(new C(42));
?>

Результат выполнения данного примера:

object(C)#1 (1) {
  ["propSquared"]=>
  int(1764)
}


Ключевое слово final

PHP предоставляет ключевое слово final, разместив которое перед объявлениями методов или констант класса, можно предотвратить их переопределение в дочерних классах. Если же сам класс определяется с этим ключевым словом, то он не сможет быть унаследован.

Пример #1 Пример окончательных (final) методов

<?php
class BaseClass {
public function
test() {
echo
"Вызван метод BaseClass::test()\n";
}

final public function
moreTesting() {
echo
"Вызван метод BaseClass::moreTesting()\n";
}
}

class
ChildClass extends BaseClass {
public function
moreTesting() {
echo
"Вызван метод ChildClass::moreTesting()\n";
}
}
// Выполнение заканчивается фатальной ошибкой: Cannot override final method BaseClass::moreTesting()
// (Окончательный (final) метод BaseClass::moreТesting() не может быть переопределён)
?>

Пример #2 Пример окончательного (final) класса

<?php
final class BaseClass {
public function
test() {
echo
"Вызван метод BaseClass::test()\n";
}

// Поскольку класс уже является final, ключевое слово final является избыточным
final public function moreTesting() {
echo
"BaseClass::moreTesting() called\n";
}
}

class
ChildClass extends BaseClass {
}
// Выполнение заканчивается фатальной ошибкой: Class ChildClass may not inherit from final class (BaseClass)
// (Класс ChildClass не может быть унаследован от окончательного класса (BaseClass))
?>

Пример #3 Пример окончательной (final) константы класса, начиная с PHP 8.1.0

<?php
class Foo
{
final public const
X = "foo";
}

class
Bar extends Foo
{
public const
X = "bar";
}

// Ошибка: Bar::X не может переопределить окончательную константу Foo::X
?>

Замечание: Свойства не могут быть объявлены окончательными: только классы, методы и константы (начиная с PHP 8.1.0) могут быть объявлены как окончательные (final). Начиная с PHP 8.0.0, закрытые методы не могут быть объявлены окончательными, за исключением конструктора.



Клонирование объектов

Создание копии объекта с абсолютно идентичными свойствами не всегда является приемлемым вариантом. Хорошим примером необходимости копирования конструкторов может послужить ситуация, когда у вас есть объект, представляющий собой окно GTK и содержащий ресурс-идентификатор этого окна; когда вы создаёте копию этого объекта, вам может понадобиться, чтобы копия объекта содержала ресурс-идентификатор нового окна. Другим примером может послужить ситуация, когда ваш объект содержит ссылку на какой-либо другой используемый объект и, когда вы создаёте копию родительского объекта, вам нужно также создать новый экземпляр этого другого объекта, так, чтобы копия объекта-контейнера содержала собственный отдельный экземпляр содержащегося объекта.

Копия объекта создаётся с использованием ключевого слова clone (который вызывает метод __clone() объекта, если это возможно).

$copy_of_object = clone $object;

При клонировании объекта, PHP выполняет поверхностную копию всех свойств объекта. Любые свойства, являющиеся ссылками на другие переменные, останутся ссылками.

__clone(): void

После завершения клонирования, если метод __clone() определён, то будет вызван метод __clone() вновь созданного объекта для возможного изменения всех необходимых свойств.

Пример #1 Клонирование объекта

<?php
class SubObject
{
static
$instances = 0;
public
$instance;

public function
__construct() {
$this->instance = ++self::$instances;
}

public function
__clone() {
$this->instance = ++self::$instances;
}
}

class
MyCloneable
{
public
$object1;
public
$object2;

function
__clone()
{
// Принудительно клонируем this->object1, иначе
// он будет указывать на один и тот же объект.
$this->object1 = clone $this->object1;
}
}

$obj = new MyCloneable();

$obj->object1 = new SubObject();
$obj->object2 = new SubObject();

$obj2 = clone $obj;


print(
"Оригинальный объект:\n");
print_r($obj);

print(
"Клонированный объект:\n");
print_r($obj2);

?>

Результат выполнения данного примера:

Оригинальный объект:
MyCloneable Object
(
    [object1] => SubObject Object
        (
            [instance] => 1
        )

    [object2] => SubObject Object
        (
            [instance] => 2
        )

)
Клонированный объект:
MyCloneable Object
(
    [object1] => SubObject Object
        (
            [instance] => 3
        )

    [object2] => SubObject Object
        (
            [instance] => 2
        )

)

Возможно обращаться к свойствам/методам только что склонированного объекта:

Пример #2 Доступ к только что склонированному объекту

<?php
$dateTime
= new DateTime();
echo (clone
$dateTime)->format('Y');
?>

Результатом выполнения данного примера будет что-то подобное:

2016


Сравнение объектов

При использовании оператора сравнения (==), свойства объектов просто сравниваются друг с другом, а именно: два объекта равны, если они имеют одинаковые атрибуты и значения (значения сравниваются через ==) и являются экземплярами одного и того же класса.

С другой стороны, при использовании оператора идентичности (===), переменные, содержащие объекты, считаются идентичными только тогда, когда они ссылаются на один и тот же экземпляр одного и того же класса.

Следующий пример пояснит эти правила.

Пример #1 Пример сравнения объектов

<?php
function bool2str($bool)
{
return (string)
$bool;
}

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
{
public
$flag;

function
__construct($flag = true) {
$this->flag = $flag;
}
}

class
OtherFlag
{
public
$flag;

function
__construct($flag = true) {
$this->flag = $flag;
}
}

$o = new Flag();
$p = new Flag();
$q = $o;
$r = new OtherFlag();

echo
"Два экземпляра одного и того же класса\n";
compareObjects($o, $p);

echo
"\nДве ссылки на один и тот же экземпляр\n";
compareObjects($o, $q);

echo
"\nЭкземпляры двух разных классов\n";
compareObjects($o, $r);
?>

Результат выполнения данного примера:

Два экземпляра одного и того же класса
o1 == o2 : TRUE
o1 != o2 : FALSE
o1 === o2 : FALSE
o1 !== o2 : TRUE

Две ссылки на один и тот же экземпляр
o1 == o2 : TRUE
o1 != o2 : FALSE
o1 === o2 : TRUE
o1 !== o2 : FALSE

Экземпляры двух разных классов
o1 == o2 : FALSE
o1 != o2 : TRUE
o1 === o2 : FALSE
o1 !== o2 : TRUE

Замечание:

Модули могут определять собственные правила для сравнения своих объектов (==).



Позднее статическое связывание

PHP реализует функцию, называемую позднее статическое связывание, которая может быть использована для того, чтобы получить ссылку на вызываемый класс в контексте статического наследования.

Если говорить более точно, позднее статическое связывание сохраняет имя класса указанного в последнем "неперенаправленном вызове". В случае статических вызовов это явно указанный класс (обычно слева от оператора ::); в случае не статических вызовов это класс объекта. "Перенаправленный вызов" - это статический вызов, начинающийся с self::, parent::, static::, или, если двигаться вверх по иерархии классов, forward_static_call(). Функция get_called_class() может быть использована для получения строки с именем вызванного класса, а static:: представляет её область действия.

Само название "позднее статическое связывание" отражает в себе внутреннюю реализацию этой особенности. "Позднее связывание" отражает тот факт, что обращения через static:: не будут вычисляться по отношению к классу, в котором вызываемый метод определён, а будут вычисляться на основе информации в ходе исполнения. Также эта особенность была названа "статическое связывание" потому, что она может быть использована (но не обязательно) в статических методах.

Ограничения self::

Статические ссылки на текущий класс, такие как self:: или __CLASS__, вычисляются используя класс, к которому эта функция принадлежит, как и в том месте, где она была определена:

Пример #1 Использование self::

<?php
class A {
public static function
who() {
echo
__CLASS__;
}
public static function
test() {
self::who();
}
}

class
B extends A {
public static function
who() {
echo
__CLASS__;
}
}

B::test();
?>

Результат выполнения данного примера:

A

Использование позднего статического связывания

Позднее статическое связывание пытается устранить это ограничение, предоставляя ключевое слово, которое ссылается на класс, вызванный непосредственно в ходе выполнения. Попросту говоря, ключевое слово, которое позволит вам ссылаться на B из test() в предыдущем примере. Было решено не вводить новое ключевое слово, а использовать static, которое уже зарезервировано.

Пример #2 Простое использование static::

<?php
class A {
public static function
who() {
echo
__CLASS__;
}
public static function
test() {
static::
who(); // Здесь действует позднее статическое связывание
}
}

class
B extends A {
public static function
who() {
echo
__CLASS__;
}
}

B::test();
?>

Результат выполнения данного примера:

B

Замечание:

В нестатическом контексте вызванным классом будет тот, к которому относится экземпляр объекта. Поскольку $this-> будет пытаться вызывать закрытые методы из той же области действия, использование static:: может дать разные результаты. Другое отличие в том, что static:: может ссылаться только на статические поля класса.

Пример #3 Использование static:: в нестатическом контексте

<?php
class A {
private function
foo() {
echo
"success!\n";
}
public function
test() {
$this->foo();
static::
foo();
}
}

class
B extends A {
/* foo() будет скопирован в В, следовательно его область действия по прежнему А,
и вызов будет успешным */
}

class
C extends A {
private function
foo() {
/* исходный метод заменён; область действия нового метода - С */
}
}

$b = new B();
$b->test();
$c = new C();
$c->test(); // потерпит ошибку
?>

Результат выполнения данного примера:

success!
success!
success!


Fatal error:  Call to private method C::foo() from context 'A' in /tmp/test.php on line 9

Замечание:

Разрешающая область позднего статического связывания будет фиксирована вычисляющем её статическим вызовом. С другой стороны, статические вызовы с использованием таких директив как parent:: или self:: перенаправляют информацию вызова.

Пример #4 Перенаправленные и неперенаправленные вызовы

<?php
class A {
public static function
foo() {
static::
who();
}

public static function
who() {
echo
__CLASS__."\n";
}
}

class
B extends A {
public static function
test() {
A::foo();
parent::foo();
self::foo();
}

public static function
who() {
echo
__CLASS__."\n";
}
}
class
C extends B {
public static function
who() {
echo
__CLASS__."\n";
}
}

C::test();
?>

Результат выполнения данного примера:

A
C
C



Объекты и ссылки

Одним из ключевых моментов объектно-ориентированной парадигмы PHP, который часто обсуждается, является "передача объектов по ссылке по умолчанию". Это не совсем верно. Данный раздел уточняет это понятие, используя некоторые примеры.

Ссылка в PHP - это псевдоним (алиас), который позволяет присвоить двум переменным одинаковое значение. В PHP объектная переменная больше не содержит сам объект как значение. Такая переменная содержит только идентификатор объекта, который позволяет найти конкретный объект при обращении к нему. Когда объект передаётся как аргумент функции, возвращается или присваивается другой переменной, то эти разные переменные не являются псевдонимами (алиасами): они содержат копию идентификатора, который указывает на один и тот же объект.

Пример #1 Ссылки и объекты

<?php
class A {
public
$foo = 1;
}

$a = new A;
$b = $a; // $a и $b - копии одного идентификатора
// ($a) = ($b) = <id>
$b->foo = 2;
echo
$a->foo."\n";


$c = new A;
$d = &$c; // $c и $d - ссылки
// ($c,$d) = <id>

$d->foo = 2;
echo
$c->foo."\n";


$e = new A;

function
foo($obj) {
// ($obj) = ($e) = <id>
$obj->foo = 2;
}

foo($e);
echo
$e->foo."\n";

?>

Результат выполнения данного примера:

2
2
2


Сериализация объектов

Сериализация объектов - сохранение объектов между сессиями

Функция serialize() возвращает строковое представление любого значения, которое может быть сохранено в PHP. Функция unserialize() может использовать эту строку для восстановления исходного значения переменной. Использование сериализации для сохранения объекта сохранит все его переменные. Методы в объекте не будут сохранены, только имя класса.

Для того, чтобы иметь возможность выполнить unserialize() для объекта, нужно, чтобы класс этого объекта был определён заранее. То есть, если у вас есть экземпляр класса А, и вы сделаете его сериализацию, вы получите его строковое представление, которое содержит значение всех переменных, содержащихся в нем. Для того, чтобы восстановить объект из строки в другом PHP-файле, класс A должен быть определён заранее. Это можно сделать, например, путём сохранения определения класса A в отдельный файл и подключить этот файл или использовать функцию spl_autoload_register() для автоматического подключения.

<?php
// classa.inc:

class A {
public
$one = 1;

public function
show_one() {
echo
$this->one;
}
}

// page1.php:

include("classa.inc");

$a = new A;
$s = serialize($a);
// сохраняем $s где-нибудь, откуда page2.php сможет его получить.
file_put_contents('store', $s);

// page2.php:

// это нужно для того, чтобы функция unserialize работала правильно.
include("classa.inc");

$s = file_get_contents('store');
$a = unserialize($s);

// теперь можно использовать метод show_one() объекта $a.
$a->show_one();
?>

Если в приложении производится сериализация объектов для последующего использования, настоятельно рекомендуется подключать определение класса для этого объекта во всем приложении. Невыполнение этого требования может привести к тому, что объект будет десериализован без определения класса, что приведёт к тому, что PHP будет использовать для этого объекта класс __PHP_Incomplete_Class_Name, который не имеет методов и сделает объект бесполезным.

Поэтому, если в приведённом выше примере $a стало частью сессии после запуска session_register("a"), вы должны подключать файл classa.inc на всех ваших страницах, а не только page1.php и page2.php.

Обратите внимание, что, кроме вышеприведённого совета, также можно подключиться к событиям сериализации и десериализации объекта с помощью методов __sleep() и __wakeup(). Метод __sleep() также позволяет сериализовать лишь некоторое подмножество свойств объекта.



Ковариантность и контравариантность

В PHP 7.2.0 была добавлена частичная контравариантность путём устранения ограничений типа для параметров в дочернем методе. Начиная с PHP 7.4.0, добавлена полная поддержка ковариантности и контравариантности.

Ковариантность позволяет дочернему методу возвращать более конкретный тип, чем тип возвращаемого значения его родительского метода. В то время как контравариантность позволяет типу параметра в дочернем методе быть менее специфичным, чем в родительском.

Объявление типа считается более конкретным в следующем случае:

В противном случае класс типа считается менее конкретным.

Ковариантность

Чтобы проиллюстрировать, как работает ковариантность, создадим простой абстрактный родительский класс Animal. Animal будет расширен за счёт дочерних классов Cat и Dog.

<?php

abstract class Animal
{
protected
string $name;

public function
__construct(string $name)
{
$this->name = $name;
}

abstract public function
speak();
}

class
Dog extends Animal
{
public function
speak()
{
echo
$this->name . " лает";
}
}

class
Cat extends Animal
{
public function
speak()
{
echo
$this->name . " мяукает";
}
}

Обратите внимание, что в примере нет методов, которые возвращают значения. Будет добавлено несколько фабрик, которые возвращают новый объект типа класса Animal, Cat или Dog.

<?php

interface AnimalShelter
{
public function
adopt(string $name): Animal;
}

class
CatShelter implements AnimalShelter
{
public function
adopt(string $name): Cat // Возвращаем класс Cat вместо Animal
{
return new
Cat($name);
}
}

class
DogShelter implements AnimalShelter
{
public function
adopt(string $name): Dog // Возвращаем класс Dog вместо Animal
{
return new
Dog($name);
}
}

$kitty = (new CatShelter)->adopt("Рыжик");
$kitty->speak();
echo
"\n";

$doggy = (new DogShelter)->adopt("Бобик");
$doggy->speak();

Результат выполнения данного примера:

Рыжик мяукает
Бобик лает

Контравариантность

В продолжение предыдущего примера, где мы использовали классы Animal, Cat и Dog, мы введём новые классы Food и AnimalFood и добавим в абстрактный класс Animal новый метод eat(AnimalFood $food).

<?php

class Food {}

class
AnimalFood extends Food {}

abstract class
Animal
{
protected
string $name;

public function
__construct(string $name)
{
$this->name = $name;
}

public function
eat(AnimalFood $food)
{
echo
$this->name . " ест " . get_class($food);
}
}

Чтобы увидеть суть контравариантности, мы переопределим метод eat класса Dog таким образом, чтобы он мог принимать любой объект класса Food. Класс Cat оставим без изменений.

<?php

class Dog extends Animal
{
public function
eat(Food $food) {
echo
$this->name . " ест " . get_class($food);
}
}

Следующий пример покажет поведение контравариантности.

<?php

$kitty
= (new CatShelter)->adopt("Рыжик");
$catFood = new AnimalFood();
$kitty->eat($catFood);
echo
"\n";

$doggy = (new DogShelter)->adopt("Бобик");
$banana = new Food();
$doggy->eat($banana);

Результат выполнения данного примера:

Рыжик ест AnimalFood
Бобик ест Food

Но что случится, если $kitty попробует съесть (eat()) банан ($banana)?

$kitty->eat($banana);

Результат выполнения данного примера:

Fatal error: Uncaught TypeError: Argument 1 passed to Animal::eat() must be an instance of AnimalFood, instance of Food given


Журнал изменений ООП

Здесь перечислены изменения модели ООП в PHP. Описания и другие примечания этих возможностей можно найти в документации ООП PHP.

Версия Описание
8.1.0 Добавлено: Поддержка модификатора final для констант класса. Кроме того, константы интерфейса по умолчанию становятся переопределяемыми.
8.0.0 Добавлено: Поддержка оператора Nullsafe ?-> для доступа к свойствам и методам объектов, которые могут быть равны null.
7.4.0 Изменено: Теперь можно выбрасывать исключение в функции __toString().
7.4.0 Добавлено: поддержка ограниченной ковариантности типов возвращаемого значения и типов аргументов. Поддержка полной вариативности производится только если используется автозагрузка. Внутри одного файла возможны только нециклические ссылки на типы.
7.4.0 Добавлено: Теперь можно задавать тип для свойств класса.
7.3.0 Несовместимость: распаковка аргументов для Traversable с нецелочисленными ключами больше не поддерживается. Такое поведение изначально не планировалось и теперь удалено.
7.3.0 Несовместимость: в прошлых версиях можно было разделить статические свойства при помощи присваивания по ссылке. Теперь нельзя.
7.3.0 Изменено: теперь оператор instanceof допускает литералы в качестве первого операнда. В этом случае всегда будет возвращено false.
7.2.0 Устарело: метод __autoload() объявлен устаревшим в пользу spl_autoload_register().
7.2.0 Изменено: для имён классов, интерфейсов и трейтов нельзя использовать слово object.
7.2.0 Изменено: для группового use теперь можно добавлять висящую запятую в конце списка.
7.2.0 Изменено: Типы параметров из переопределённых методов и реализации интерфейсов теперь указывать не обязательно
7.2.0 Изменено: если один абстрактный класс наследует от другого абстрактного класса, то он может переопределять его абстрактные методы.
7.1.0 Изменено: для имён классов, интерфейсов и трейтов нельзя использовать слова: void и iterable.
7.1.0 Добавлено: теперь можно задавать область видимости для констант классов.
7.0.0 Устарело: Статический вызов нестатических методов.
7.0.0 Устарело: конструктор в стиле PHP 4. Т.е. метод с именем идентичным имени класса, в котором он объявлен.
7.0.0 Добавлено: групповая декларация use: классы, функции и константы, которые надо импортировать из одного и того же пространства имён теперь могут быть сгруппированы в одном выражении use.
7.0.0 Добавлено: добавлена поддержка анонимных классов с помощью new class.
7.0.0 Несовместимость: итерирование объектов не реализующих Traversable теперь ведёт себя аналогично итерированию массива по ссылке.
7.0.0 Изменено: Определение одинаковых (полностью совпадающих) свойств в двух трейтах больше не вызывает ошибку.
5.6.0 Добавлено: метод __debugInfo().
5.5.0 Добавлено: магическая константа ::class.
5.5.0 Добавлено: finally в обработчик исключений.
5.4.0 Добавлено: трейты.
5.4.0 Изменено: Если абстрактный класс определяет сигнатуру для конструктора, то она будет принудительно применяться.
5.3.3 Изменено: Методы с тем же именем, что и последний элемент пространства имён класса больше не будут рассматриваться как конструктор. Это изменение не влияет классы, не использующие пространства имён.
5.3.0 Изменено: Больше не требуется, чтобы классы, реализующие интерфейсы с методами, которые имеют значения по умолчанию в прототипе, соответствовали значениям по умолчанию в интерфейсе.
5.3.0 Изменено: Теперь стало возможным ссылаться на класс, используя переменную (например, echo $classname::constant;). Значение переменной не может быть ключевым словом (например, self, parent или static).
5.3.0 Изменено: Ошибка E_WARNING происходит, если магические перегруженные методы объявлены как статические. Это также усиливает требование, что эти методы должны быть общедоступными.
5.3.0 Изменено: До 5.3.0, исключения в функции __autoload() не могли быть перехвачены в блоке catch и приводили к фатальной ошибке. Сейчас исключения в функции __autoload могут быть перехвачены в блоке catch, но с одной оговоркой. Если перехватывается пользовательское исключение, то класс, обрабатывающий это исключение, должен быть доступен. Функция __autoload может быть использована рекурсивно для автозагрузки пользовательского класса обработки исключения.
5.3.0 Добавлено: Метод __callStatic.
5.3.0 Добавлено: Поддержка heredoc и nowdoc для констант и определений свойств класса. Примечание: Значение heredoc должны следовать тем же правилам, что и строки в двойных кавычках (например, без переменных внутри).
5.3.0 Добавлено: Позднее статическое связывание.
5.3.0 Добавлено: метод __invoke().
5.2.0 Изменено: Метод __toString() вызывался только, когда он напрямую объединён с echo или print. Сейчас он вызывается в любом контексте строки (например, в printf() с модификатором %s), но не в других типах контекста (например, с модификатором %d). С PHP 5.2.0, преобразование объектов без метода __toString в строку выдаёт ошибку уровня E_RECOVERABLE_ERROR.
5.1.3 Изменено: В предыдущих версиях PHP 5 использование var считалось устаревшим и выдавало ошибку E_STRICT. Сейчас это не считается устаревшим, поэтому ошибка больше не выдаётся.
5.1.0 Изменено: Статический метод __set_state() теперь вызывается для классов, экспортируемых функцией var_export().
5.1.0 Добавлены: методы __isset() и __unset().




Пространства имён

Содержание


Обзор пространств имён

(PHP 5 >= 5.3.0, PHP 7, PHP 8)

Что такое пространства имён? В широком смысле - это один из способов инкапсуляции элементов. Такое абстрактное понятие можно увидеть во многих местах. Например, в любой операционной системе директории служат для группировки связанных файлов и выступают в качестве пространства имён для находящихся в них файлов. В качестве конкретного примера файл foo.txt может находиться сразу в обеих директориях: /home/greg и /home/other, но две копии foo.txt не могут существовать в одной директории. Кроме того, для доступа к foo.txt извне директории /home/greg, мы должны добавить имя директории перед именем файла используя разделитель, чтобы получить /home/greg/foo.txt. Этот же принцип распространяется и на пространства имён в программировании.

В PHP пространства имён используются для решения двух проблем, с которыми сталкиваются авторы библиотек и приложений при создании повторно используемых элементов кода, таких как классы и функции:

  1. Конфликт имён между вашим кодом и внутренними классами/функциями/константами PHP или сторонними.
  2. Возможность создавать псевдонимы (или сокращения) для Ну_Очень_Длинных_Имён, чтобы облегчить первую проблему и улучшить читаемость исходного кода.

Пространства имён в PHP предоставляют возможность группировать логически связанные классы, интерфейсы, функции и константы.

Пример #1 Пример синтаксиса, использующего пространство имён

<?php
namespace my\name; // смотрите раздел "Определение пространств имён"
class MyClass {}
function
myfunction() {}
const
MYCONST = 1;

$a = new MyClass;
$c = new \my\name\MyClass; // смотрите раздел "Глобальная область видимости"

$a = strlen('hi'); // смотрите раздел "Использование пространств имён: возврат
// к глобальной функции/константе"

$d = namespace\MYCONST; // смотрите раздел "оператор пространства имён и
// константа __NAMESPACE__"
$d = __NAMESPACE__ . '\MYCONST';
echo
constant($d); // смотрите раздел "Пространства имён и динамические особенности языка"
?>

Замечание: Имена пространств имён регистронезависимы.

Замечание:

Пространства имён PHP или составные имена, начинающиеся с этого слова (например, такие как PHP\Classes), зарезервированы для нужд языка, их не следует использовать в пользовательском коде.



Определение пространств имён

(PHP 5 >= 5.3.0, PHP 7, PHP 8)

Хотя любой корректный PHP-код может находиться внутри пространства имён, только классы (включая абстрактные и трейты), интерфейсы, функции и константы зависят от него.

Пространства имён объявляются с помощью зарезервированного слова namespace. Файл, содержащий пространство имён, должен содержать его объявление в начале перед любым другим кодом, кроме зарезервированного слова declare.

Пример #1 Объявление единого пространства имён

<?php
namespace MyProject;

const
CONNECT_OK = 1;
class
Connection { /* ... */ }
function
connect() { /* ... */ }

?>

Замечание: Абсолютные имена (т.е. имена, начинающиеся с обратной косой черты) не допускаются в объявлениях пространства имён, поскольку такие конструкции интерпретируются как относительные выражения пространства имён.

Только выражение declare может находиться перед объявлением пространства имён для указания кодировки файла. Кроме того, объявлению пространства имён не должен предшествовать не PHP-код, в том числе лишние пробелы:

Пример #2 Объявление простого пространства имён

<html>
<?php
namespace MyProject; // fatal error - объявление пространства имён должно быть первым выражением в скрипте
?>

Кроме того, в отличие от любой другой конструкции PHP, одно и то же пространство имён можно определять в нескольких файлах, что позволяет распределять их содержимое по файловой системе.



Определение подпространств имён

(PHP 5 >= 5.3.0, PHP 7, PHP 8)

Так же как файлы и каталоги, пространства имён PHP позволяют создавать иерархию имён. Таким образом, имя пространства может быть определено с подуровнями:

Пример #1 Определение пространства имён с иерархией

<?php
namespace MyProject\Sub\Level;

const
CONNECT_OK = 1;
class
Connection { /* ... */ }
function
connect() { /* ... */ }

?>
Вышеприведённый пример создаёт константу MyProject\Sub\Level\CONNECT_OK, класс MyProject\Sub\Level\Connection и функцию MyProject\Sub\Level\connect.



Описание нескольких пространств имён в одном файле

(PHP 5 >= 5.3.0, PHP 7, PHP 8)

Несколько пространств имён также можно описать в одном файле с помощью двух допустимых синтаксических конструкций.

Пример #1 Описание нескольких пространств имён, простой синтаксис

<?php
namespace MyProject;

const
CONNECT_OK = 1;
class
Connection { /* ... */ }
function
connect() { /* ... */ }

namespace
AnotherProject;

const
CONNECT_OK = 1;
class
Connection { /* ... */ }
function
connect() { /* ... */ }
?>

Данный синтаксис не рекомендуется для комбинирования пространств имён в одном файле. Вместо этого рекомендуется использовать альтернативный синтаксис со скобками.

Пример #2 Описание нескольких пространств имён, синтаксис со скобками

<?php
namespace MyProject {

const
CONNECT_OK = 1;
class
Connection { /* ... */ }
function
connect() { /* ... */ }
}

namespace
AnotherProject {

const
CONNECT_OK = 1;
class
Connection { /* ... */ }
function
connect() { /* ... */ }
}
?>

Настоятельно не рекомендуется при программировании комбинировать несколько пространств имён в один файл. Основным применением этому может быть объединение нескольких PHP-файлов в один файл.

Для объединения кода в глобальном пространстве имён с кодом в других пространствах имён, используется только синтаксис со скобками. Глобальный код должен быть помещён в конструкцию описания пространства имён без указания имени:

Пример #3 Описание глобального и обычного пространства имён в одном файле

<?php
namespace MyProject {

const
CONNECT_OK = 1;
class
Connection { /* ... */ }
function
connect() { /* ... */ }
}

namespace {
// глобальный код
session_start();
$a = MyProject\connect();
echo
MyProject\Connection::start();
}
?>

PHP-код не может находиться вне скобок конструкции пространства имён, кроме начального выражения declare.

Пример #4 Описание глобального и обычного пространства имён в одном файле

<?php
declare(encoding='UTF-8');
namespace
MyProject {

const
CONNECT_OK = 1;
class
Connection { /* ... */ }
function
connect() { /* ... */ }
}

namespace {
// глобальный код
session_start();
$a = MyProject\connect();
echo
MyProject\Connection::start();
}
?>



Использование пространства имён: основы

(PHP 5 >= 5.3.0, PHP 7, PHP 8)

До обсуждения использования пространств имён важно понять, как PHP узнает, какие элементы из пространства имён запрашиваются в вашем коде. Можно провести аналогию между пространствами имён PHP и файловой системой. Есть три способа обратиться к файлу в файловой системе:

  1. Относительное имя файла, такое как foo.txt, преобразуемое в currentdirectory/foo.txt, где currentdirectory - текущая директория, в которой мы находимся. Тогда, если текущая директория /home/foo, то имя преобразуется в /home/foo/foo.txt.
  2. Относительное имя пути, такое как subdirectory/foo.txt, преобразуется в currentdirectory/subdirectory/foo.txt.
  3. Абсолютное имя пути, такое как /main/foo.txt, которое остаётся таким же: /main/foo.txt.
Тот же принцип применим и к элементам из пространств имён PHP. Например, имя класса может быть указано тремя способами:
  1. Неполные имена (имена классов без префикса), такие как $a = new foo(); или foo::staticmethod();. Если текущее пространство имён currentnamespace, то эти имена преобразуются в currentnamespace\foo. Если код находится в глобальном пространстве имён, то имена остаются такими же: foo. Предупреждение: неполные имена для функций и констант будут определяться в глобальном пространстве имён, если они не определены в текущем пространстве имён. Подробнее в Использование пространств имён: доступ к глобальным функциям и классам.
  2. Полные имена (имена классов с префиксами), такие как $a = new subnamespace\foo(); или subnamespace\foo::staticmethod();. Если текущее пространство имён currentnamespace, то эти имена преобразуются в currentnamespace\subnamespace\foo. Если код находится в глобальном пространстве имён, то имена преобразуются в subnamespace\foo.
  3. Абсолютные имена или имена с предшествующим префиксом, обозначающим глобальное пространство. $a = new \currentnamespace\foo(); или \currentnamespace\foo::staticmethod();. Имена всегда определяются так же, как и записаны: currentnamespace\foo.

Ниже приведён пример трёх вариантов синтаксиса в реальном коде:

file1.php

<?php
namespace Foo\Bar\subnamespace;

const
FOO = 1;
function
foo() {}
class
foo
{
static function
staticmethod() {}
}
?>

file2.php

<?php
namespace Foo\Bar;
include
'file1.php';

const
FOO = 2;
function
foo() {}
class
foo
{
static function
staticmethod() {}
}

/* Неполные имена */
foo(); // определяется как функция Foo\Bar\foo
foo::staticmethod(); // определяется как класс Foo\Bar\foo с методом staticmethod
echo FOO; // определяется как константа Foo\Bar\FOO

/* Полные имена */
subnamespace\foo(); // определяется как функция Foo\Bar\subnamespace\foo
subnamespace\foo::staticmethod(); // определяется как класс Foo\Bar\subnamespace\foo
// c методом staticmethod
echo subnamespace\FOO; // определяется как константа Foo\Bar\subnamespace\FOO

/* Абсолютные имена */
\Foo\Bar\foo(); // определяется как функция Foo\Bar\foo
\Foo\Bar\foo::staticmethod(); // определяется как класс Foo\Bar\foo с методом staticmethod
echo \Foo\Bar\FOO; // определяется как константа Foo\Bar\FOO
?>

Обратите внимание, что для доступа к любым глобальным классам, функциям или константам, может использоваться абсолютное имя, такое как \strlen(), или \Exception, или \INI_ALL.

Пример #1 Доступ к глобальным классам, функциям и константам из пространства имён

<?php
namespace Foo;

function
strlen() {}
const
INI_ALL = 3;
class
Exception {}

$a = \strlen('hi'); // вызывает глобальную функцию strlen
$b = \INI_ALL; // получает доступ к глобальной константе INI_ALL
$c = new \Exception('error'); // Создаёт экземпляр глобального класса Exception
?>



Пространства имён и динамические особенности языка

(PHP 5 >= 5.3.0, PHP 7, PHP 8)

На реализацию пространств имён в PHP повлияли и динамические особенности языка. Преобразуем нижеследующий код для использования пространств имён:

Пример #1 Динамически доступные элементы

example1.php:

<?php
class classname
{
function
__construct()
{
echo
__METHOD__,"\n";
}
}
function
funcname()
{
echo
__FUNCTION__,"\n";
}
const
constname = "global";

$a = 'classname';
$obj = new $a; // выводит classname::__construct
$b = 'funcname';
$b(); // выводит funcname
echo constant('constname'), "\n"; // выводит global
?>
Необходимо использовать абсолютное имя (имя класса с префиксом пространства имён). Обратите внимание, что нет никакой разницы между полным именем и абсолютным внутри динамического имени класса, функции или константы. Начальный обратный слеш не является необходимым.

Пример #2 Динамически доступные элементы пространства имён

<?php
namespace namespacename;
class
classname
{
function
__construct()
{
echo
__METHOD__,"\n";
}
}
function
funcname()
{
echo
__FUNCTION__,"\n";
}
const
constname = "namespaced";

include
'example1.php';

$a = 'classname';
$obj = new $a; // выводит classname::__construct
$b = 'funcname';
$b(); // выводит funcname
echo constant('constname'), "\n"; // выводит global

/* обратите внимание, что при использовании двойных кавычек символ обратного слеша должен быть заэкранирован. Например, "\\namespacename\\classname" */
$a = '\namespacename\classname';
$obj = new $a; // выводит namespacename\classname::__construct
$a = 'namespacename\classname';
$obj = new $a; // также выводит namespacename\classname::__construct
$b = 'namespacename\funcname';
$b(); // выводит namespacename\funcname
$b = '\namespacename\funcname';
$b(); // также выводит namespacename\funcname
echo constant('\namespacename\constname'), "\n"; // выводит namespaced
echo constant('namespacename\constname'), "\n"; // также выводит namespaced
?>

Обязательно прочитайте примечание об экранировании имён пространства имён в строках.



Ключевое слово namespace и константа __NAMESPACE__

(PHP 5 >= 5.3.0, PHP 7, PHP 8)

PHP поддерживает два способа доступа к абстрактным элементам в текущем пространстве имён таким, как магическая константа __NAMESPACE__ и ключевое слово namespace.

Значение константы __NAMESPACE__ - это строка, которая содержит имя текущего пространства имён. В глобальном пространстве, вне пространства имён, она содержит пустую строку.

Пример #1 Пример использование константы __NAMESPACE__ в коде с пространством имён

<?php
namespace MyProject;

echo
'"', __NAMESPACE__, '"'; // выводит "MyProject"
?>

Пример #2 Пример использование константы __NAMESPACE__ в глобальном пространстве

<?php

echo '"', __NAMESPACE__, '"'; // выводит ""
?>
Константа __NAMESPACE__ полезна для динамически конструируемых имён, например:

Пример #3 использование константы __NAMESPACE__ для динамического конструирования имени

<?php
namespace MyProject;

function
get($classname)
{
$a = __NAMESPACE__ . '\\' . $classname;
return new
$a;
}
?>

Ключевое слово namespace может быть использовано для явного запроса элемента из текущего пространства имён или из подпространства. Это эквивалент оператора self для классов в пространстве имён.

Пример #4 Оператор namespace, внутри пространства имён

<?php
namespace MyProject;

use
blah\blah as mine; // смотрите "Использование пространств имён: импорт/создание псевдонима имени"

blah\mine(); // вызывает функцию MyProject\blah\mine()
namespace\blah\mine(); // вызывает функцию MyProject\blah\mine()

namespace\func(); // вызывает функцию MyProject\func()
namespace\sub\func(); // вызывает функцию MyProject\sub\func()
namespace\cname::method(); // вызывает статический метод "method" класса MyProject\cname
$a = new namespace\sub\cname(); // Создаёт экземпляр класса MyProject\sub\cname
$b = namespace\CONSTANT; // присваивает значение константы MyProject\CONSTANT переменной $b
?>

Пример #5 Оператор namespace в глобальном коде

<?php

namespace\func(); // вызывает функцию func()
namespace\sub\func(); // вызывает функцию sub\func()
namespace\cname::method(); // вызывает статический метод "method" класса cname
$a = new namespace\sub\cname(); // Создаёт экземпляр класса sub\cname
$b = namespace\CONSTANT; // присваивает значение константы CONSTANT переменной $b
?>



Использование пространств имён: импорт/создание псевдонима имени

(PHP 5 >= 5.3.0, PHP 7, PHP 8)

Возможность ссылаться на внешнее абсолютное имя по псевдониму или импортированию - это важная особенность пространств имён. Это похоже на возможность файловых систем unix создавать символические ссылки на файл или директорию.

PHP может создавать псевдонимы имени/импортировать константы, функции, классы, интерфейсы, трейты, перечисления и пространства имён.

Создание псевдонима имени выполняется с помощью оператора use. Вот пример, показывающий 5 типов импорта:

Пример #1 импорт/создание псевдонима имени с помощью оператора use

<?php
namespace foo;
use
My\Full\Classname as Another;

// это тоже самое, что и использование My\Full\NSname as NSname
use My\Full\NSname;

// импортирование глобального класса
use ArrayObject;

// импортирование функции
use function My\Full\functionName;

// псевдоним функции
use function My\Full\functionName as func;

// импортирование константы
use const My\Full\CONSTANT;

$obj = new namespace\Another; // создаёт экземпляр класса foo\Another
$obj = new Another; // создаёт объект класса My\Full\Classname
NSname\subns\func(); // вызывает функцию My\Full\NSname\subns\func
$a = new ArrayObject(array(1)); // создаёт объект класса ArrayObject
// без выражения "use ArrayObject" мы создадим объект класса foo\ArrayObject
func(); // вызывает функцию My\Full\functionName
echo CONSTANT; // выводит содержимое константы My\Full\CONSTANT
?>
Обратите внимание, что для имён в пространстве имён (абсолютные имена, содержащие разделитель пространств имён, такие как Foo\Bar, в отличие от глобальных имён, которые его не содержат, такие как FooBar) нет необходимости в начальном обратном слеше (\) и его присутствие там не рекомендуется, так как импортируемые имена должны быть абсолютными и не обрабатываются относительно текущего пространства имён.

PHP дополнительно поддерживает удобное сокращение для задания нескольких операторов use в одной и той же строке

Пример #2 импорт/создание псевдонима имени с помощью оператора use, комбинирование нескольких операторов use

<?php
use My\Full\Classname as Another, My\Full\NSname;

$obj = new Another; // создаёт объект класса My\Full\Classname
NSname\subns\func(); // вызывает функцию My\Full\NSname\subns\func
?>

Импорт выполняется во время компиляции и поэтому не влияет на имена динамических классов, функций или констант.

Пример #3 Импорт и динамические имена

<?php
use My\Full\Classname as Another, My\Full\NSname;

$obj = new Another; // создаёт объект класса My\Full\Classname
$a = 'Another';
$obj = new $a; // создаёт объект класса Another
?>

В дополнение, импорт распространяется только на неполные и полные имена. Абсолютные имена не затрагиваются операцией импорта.

Пример #4 Импортирование и абсолютные имена

<?php
use My\Full\Classname as Another, My\Full\NSname;

$obj = new Another; // создаёт объект класса My\Full\Classname
$obj = new \Another; // создаёт объект класса Another
$obj = new Another\thing; // создаёт объект класса My\Full\Classname\thing
$obj = new \Another\thing; // создаёт объект класса Another\thing
?>

Обзор правил для импорта

Ключевое слово use должно быть указано в самом начале файла (в глобальной области) или внутри объявления пространства имён. Это необходимо потому, что импорт выполняется во время компиляции, а не во время исполнения, поэтому оно не может быть заключено в блок. Следующий пример показывает недопустимое применение ключевого слова use:

Пример #5 Недопустимое правило импорта

<?php
namespace Languages;

function
toGreenlandic()
{
use
Languages\Danish;

//...
}
?>

Замечание:

Правила импорта задаются на каждый файл отдельно. Это означает, что присоединяемые файлы НЕ будут наследовать правила импорта из родительского файла.

Описание группирования в одном операторе use

Классы, функции и константы, импортируемые из одного и того же namespace, могут группироваться в одном операторе use.

<?php

use some\namespace\ClassA;
use
some\namespace\ClassB;
use
some\namespace\ClassC as C;

use function
some\namespace\fn_a;
use function
some\namespace\fn_b;
use function
some\namespace\fn_c;

use const
some\namespace\ConstA;
use const
some\namespace\ConstB;
use const
some\namespace\ConstC;

// Эквивалентно следующему групповому использованию
use some\namespace\{ClassA, ClassB, ClassC as C};
use function
some\namespace\{fn_a, fn_b, fn_c};
use const
some\namespace\{ConstA, ConstB, ConstC};


Глобальное пространство

(PHP 5 >= 5.3.0, PHP 7, PHP 8)

Без определения пространства имён, определения всех классов и функций находятся в глобальном пространстве - так же, как это было в PHP до введения пространств имён. Добавление префикса \ к именам означает, что это имя должно находиться в глобальном пространстве, даже если вы находитесь в контексте определённого пространства имён.

Пример #1 Использование глобального пространства и его задание

<?php
namespace A\B\C;

/* Эта функция является A\B\C\fopen */
function fopen() {
/* ... */
$f = \fopen(...); // вызов глобальной функции fopen
return $f;
}
?>



Использование пространств имён: переход к глобальной функции/константе

(PHP 5 >= 5.3.0, PHP 7, PHP 8)

Внутри пространства имён, когда PHP встречает неполное имя класса, функции или константы, он преобразует эти имена с разными приоритетами. Имена классов всегда преобразуются к текущему имени пространства имён. Таким образом, чтобы получить доступ ко внутреннему классу или пользовательскому классу вне пространства имён, необходимо ссылаться по их абсолютному имени. Например:

Пример #1 Доступ к глобальным классам внутри пространства имён

<?php
namespace A\B\C;
class
Exception extends \Exception {}

$a = new Exception('hi'); // $a - это объект класса A\B\C\Exception
$b = new \Exception('hi'); // $b - это объект класса Exception

$c = new ArrayObject; // фатальная ошибка, класс A\B\C\ArrayObject не найден
?>

Для функций и констант, PHP будет прибегать к глобальным функциям или константам, если функция или константа не существует в пространстве имён.

Пример #2 Необходимость прибегнуть к глобальным функциям/константам внутри пространства имён

<?php
namespace A\B\C;

const
E_ERROR = 45;
function
strlen($str)
{
return \
strlen($str) - 1;
}

echo
E_ERROR, "\n"; // выводит "45"
echo INI_ALL, "\n"; // выводит "7" - прибегнет к глобальной INI_ALL

echo strlen('hi'), "\n"; // выводит "1"
if (is_array('hi')) { // выводит строку "это не массив"
echo "это массив\n";
} else {
echo
"это не массив\n";
}
?>



Правила разрешения имён

(PHP 5 >= 5.3.0, PHP 7, PHP 8)

Для этих правил здесь приведены несколько важных определений:

Определения имени пространства имён
Неполное имя

Это идентификатор без разделителя пространств имён, например, Foo

Полное имя

Это идентификатор с разделителем пространств имён, например, Foo\Bar

Абсолютное имя

Это идентификатор с разделителем пространств имён, который начинается с разделителя пространств имён, например, \Foo\Bar. Пространство имён \Foo также является абсолютным именем.

Относительное имя

Это идентификатор, начинающийся с namespace, такой как namespace\Foo\Bar.

Имена разрешаются согласно следующим правилам:

  1. Абсолютные имена всегда разрешаются без ведущего разделителя пространства имён. Например, \A\B разрешается в A\B.
  2. Относительные имена всегда разрешаются в имена с заменой namespace на текущее пространство имён. Если имя встречается в глобальном пространстве имён, префикс namespace\ просто удаляется. К примеру namespace\A внутри пространства имён X\Y разрешается в X\Y\A. То же самое имя в глобальном пространстве имён разрешается в A.
  3. Для полных имён первый сегмент преобразуется в соответствии с текущей таблицей импорта класса или пространства имён. Например, пространство имён A\B\C импортировано как C, тогда имя C\D\E преобразуется в A\B\C\D\E.
  4. Для полных имён, если не применяется никакого правила импорта, текущее пространство имён добавляется к имени. Например, имя C\D\E внутри пространства имён A\B, преобразуется в A\B\C\D\E.
  5. Для неполных имён имена преобразуются текущей таблице импорта в зависимости от типа элемента. Это означает, что имена классов преобразуются согласно таблице импорта классов, имена функций - согласно таблице импорта функций и константы согласно таблице импорта констант. К примеру, после use A\B\C;, использование new C() разрешается как A\B\C(). Аналогично, после use function A\B\fn;, использование fn() разрешается как A\B\fn.
  6. Неполные имена, если отсутствуют ограничения в таблице импорта и если они используются как класс, то они разрешаются с префиксом текущего пространства имён. Например, new C() внутри пространства имён A\B разрешаются как A\B\C.
  7. Неполные имена, если отсутствуют ограничения в таблице импорта и если они используются как функция или константа, а код находится не в глобальном пространстве имён, имена разрешаются во время исполнения. Например код, в пространстве имён A\B, вызывающий функцию foo(), разрешается так:
    1. Производится поиск функции из текущего пространства имён: A\B\foo().
    2. PHP пытается найти и вызвать функцию глобального пространства foo().

Пример #1 Примеры разрешения имён

<?php
namespace A;
use
B\D, C\E as F;

// вызовы функций

foo(); // сперва пытается вызвать "foo", определённую в пространстве имён "A",
// затем вызывает глобальную функцию "foo"

\foo(); // вызывает функцию "foo", определённую в глобальном пространстве

my\foo(); // вызывает функцию "foo", определённую в пространстве "A\my"

F(); // сперва пытается вызвать "F", определённую в пространстве имён "A",
// затем вызывает глобальную функцию "F"

// ссылки на классы

new B(); // создаёт объект класса "B", определённого в пространстве имён "A".
// если не найден, то пытается сделать автозагрузку класса "A\B"

new D(); // используя правила импорта, создаёт объект класса "D", определённого в пространстве имён "B"
// если не найден, то пытается сделать автозагрузку класса "B\D"

new F(); // используя правила импорта, создаёт объект класса "E", определённого в пространстве имён "C"
// если не найден, то пытается сделать автозагрузку класса "C\E"

new \B(); // создаёт объект класса "B", определённого в глобальном пространстве,
// если не найден, то пытается сделать автозагрузку класса "B"

new \D(); // создаёт объект класса "D", определённого в глобальном пространстве,
// если не найден, то пытается сделать автозагрузку класса "D"

new \F(); // создаёт объект класса "F", определённого в глобальном пространстве,
// если не найден, то пытается сделать автозагрузку класса "F"

// статические методы/функции пространства имён из другого пространства имён

B\foo(); // вызывает функцию "foo" из пространства имён "A\B"

B::foo(); // вызывает метод "foo" из класса "B", определённого в пространстве имён "A"
// если класс "A\B" не найден, то пытается сделать автозагрузку класса "A\B"

D::foo(); // используя правила импорта, вызывает метод "foo" класса "D", определённого в пространстве имён "B"
// если класс "B\D" не найден, то пытается сделать автозагрузку класса "B\D"

\B\foo(); // вызывает функцию "foo" из пространства имён "B"

\B::foo(); // вызывает метод "foo" класса "B" из глобального пространства
// если класс "B" не найден, то пытается сделать автозагрузку класса "B"

// статические методы/функции пространства имён из текущего пространства имён

A\B::foo(); // вызывает метод "foo" класса "B" из пространства имён "A\A"
// если класс "A\A\B" не найден, то пытается сделать автозагрузку класса "A\A\B"

\A\B::foo(); // вызывает метод "foo" класса "B" из пространства имён "A"
// если класс "A\B" не найден, то пытается сделать автозагрузку класса "A\B"
?>


Часто задаваемые вопросы (FAQ): вещи, которые вам необходимо знать о пространствах имён

(PHP 5 >= 5.3.0, PHP 7, PHP 8)

Этот список вопросов разделён на две части: общие вопросы и некоторые особенности реализации, которые полезны для более полного понимания.

Сперва, общие вопросы.

  1. Если я не использую пространства имён, следует ли считать что-либо из этого важным?
  2. Как мне использовать внутренние или глобальные классы в пространстве имён?
  3. Как мне использовать функции классов в пространствах имён, или константы в их собственном пространстве имён?
  4. Как такое имя как \my\name или \name преобразуется?
  5. Как такое имя, как my\name преобразуется?
  6. Как неполное имя класса такое как name преобразуется?
  7. Как неполное имя функции или неполное имя константы такое как name преобразуется?

Некоторые детали реализации пространств имён, которые полезно понимать.

  1. Импортируемые имена не должны конфликтовать с классами, определёнными в том же файле.
  2. Вложенные пространства имён недопустимы.
  3. Динамические имена пространств имён (идентификаторы, взятые в кавычки) должны экранировать символ обратного слеша.
  4. Ссылаться на неопределённые константы, используя обратный слеш, нельзя. Выводится фатальная ошибка
  5. Невозможно переопределить специальные константы, такие как NULL, TRUE, FALSE, ZEND_THREAD_SAFE или ZEND_DEBUG_BUILD

Если я не использую пространства имён, следует ли считать что-либо из этого важным?

Нет. Пространства имён не оказывают никакого влияния ни на какой существующий код ни в каком виде или на любой написанный код, который не содержит пространств имён. Вы можете написать такой код, если желаете:

Пример #1 Доступ к глобальным классам вне пространства имён

<?php
$a
= new \stdClass;
?>

Это функционально эквивалентно следующему:

Пример #2 Доступ к глобальным классам вне пространства имён

<?php
$a
= new stdClass;
?>

Как мне использовать внутренние или глобальные классы в пространстве имён?

Пример #3 Доступ ко внутренним классам в пространствах имён

<?php
namespace foo;
$a = new \stdClass;

function
test(\ArrayObject $parameter_type_example = null) {}

$a = \DirectoryIterator::CURRENT_AS_FILEINFO;

// расширение внутреннего или глобального класса
class MyException extends \Exception {}
?>

Как мне использовать функции классов в пространствах имён или константы в их собственном пространстве имён?

Пример #4 Доступ ко внутренним классам, функциям или константам в пространствах имён

<?php
namespace foo;

class
MyClass {}

// использование класса из текущего пространства имен в качестве типа параметра
function test(MyClass $parameter_type_example = null) {}
// другой способ использовать класс из текущего пространства имен в качестве типа параметра
function test(\foo\MyClass $parameter_type_example = null) {}

// расширение класса из текущего пространства имён
class Extended extends MyClass {}

// доступ к глобальной функции
$a = \globalfunc();

// доступ к глобальной константе
$b = \INI_ALL;
?>

Как такое имя как \my\name или \name преобразуется?

Имена, которые начинаются с \ всегда преобразуются к тому как они выглядят, т.е. \my\name - это на самом деле my\name, и \Exception - это Exception.

Пример #5 Абсолютные имена

<?php
namespace foo;
$a = new \my\name(); // создаёт экземпляр класса "my\name"
echo \strlen('hi'); // вызывает функцию "strlen"
$a = \INI_ALL; // переменной $a присваивается значение константы "INI_ALL"
?>

Как такое имя, как my\name преобразуется?

Имена, которые содержат обратный слеш, но не начинаются с него, такие как my\name могут быть преобразованы двумя различными способами.

Если присутствует импортирующее выражение, которое создаёт синоним my другого имени, то этот синоним применяется к my в my\name.

В ином случае, текущее имя пространства имён становится префиксом к my\name.

Пример #6 Полные имена

<?php
namespace foo;
use
blah\blah as foo;

$a = new my\name(); // создаёт экземпляр класса "foo\my\name"
foo\bar::name(); // вызывает статический метод "name" в классе "blah\blah\bar"
my\bar(); // вызывает функцию "foo\my\bar"
$a = my\BAR; // присваивает переменной $a значение константы "foo\my\BAR"
?>

Как неполное имя класса такое как name преобразуется?

Имена классов, которые не содержат обратный слеш, такие как name могут быть преобразованы двумя различными способами.

Если присутствует импортирующее выражение, которое создаёт синоним name другого имени, то применяется этот синоним.

В ином случае, текущее имя пространства имён становится префиксом к name.

Пример #7 Неполные имена классов

<?php
namespace foo;
use
blah\blah as foo;

$a = new name(); // создаёт экземпляр класса "foo\name"
foo::name(); // вызывает статический метод "name" в классе "blah\blah"
?>

Как неполное имя функции или неполное имя константы такое как name преобразуется?

Имена функций или констант, которые не содержат обратного слеша, такие как name могут быть преобразованы двумя различными способами.

Сперва, текущее имя пространства имён становится префиксом к name.

Затем, если константа или функция name не существует в текущем пространстве имён, используется глобальная константа или функция name, если она существует.

Пример #8 Неполные имена функций или констант

<?php
namespace foo;
use
blah\blah as foo;

const
FOO = 1;

function
my() {}
function
foo() {}
function
sort(&$a)
{
\
sort($a); // вызывает глобальную функцию "sort"
$a = array_flip($a);
return
$a;
}

my(); // вызывает "foo\my"
$a = strlen('hi'); // вызывает глобальную функцию "strlen", потому что "foo\strlen" не существует
$arr = array(1,3,2);
$b = sort($arr); // вызывает функцию "foo\sort"
$c = foo(); // вызывает функцию "foo\foo" - импорт не применяется

$a = FOO; // присваивает переменной $a значение константы "foo\FOO" - импорт не применяется
$b = INI_ALL; // присваивает переменной $b значение глобальной константы "INI_ALL"
?>

Импортируемые имена не должны конфликтовать с классами, определёнными в том же файле.

Следующие комбинации скриптов допустимы:

file1.php

<?php
namespace my\stuff;
class
MyClass {}
?>

another.php

<?php
namespace another;
class
thing {}
?>

file2.php

<?php
namespace my\stuff;
include
'file1.php';
include
'another.php';

use
another\thing as MyClass;
$a = new MyClass; // создаёт экземпляр класса "thing" из пространства имён "another"
?>

Конфликт имён отсутствует даже несмотря на то, что класс MyClass существует внутри пространства имён my\stuff, потому что определение MyClass находится в отдельном файле. Однако следующий пример приводит к фатальной ошибке с конфликтом имён, потому что класс MyClass определён в том же файле, где находится оператор use.

<?php
namespace my\stuff;
use
another\thing as MyClass;
class
MyClass {} // фатальная ошибка: MyClass конфликтует с выражением импорта
$a = new MyClass;
?>

Вложенные пространства имён недопустимы.

PHP не позволяет вложение пространств имён одно в другое

<?php
namespace my\stuff {
namespace
nested {
class
foo {}
}
}
?>
Однако, можно сымитировать вложенные пространства имён так:
<?php
namespace my\stuff\nested {
class
foo {}
}
?>

Динамические имена пространств имён (идентификаторы, взятые в кавычки) должны экранировать символ обратного слеша.

Очень важно представлять это, потому что обратный слеш используется как экранирующий символ внутри строк. Он всегда должен быть продублирован, когда используется внутри строки, иначе появляется риск возникновения неумышленных последствий:

Пример #9 Подводные камни при использовании имени пространства имён внутри строки с двойными кавычками

<?php
$a
= "dangerous\name"; // \n - это переход на новую строку внутри строки с двойными кавычками!
$obj = new $a;

$a = 'not\at\all\dangerous'; // а тут нет проблем.
$obj = new $a;
?>
Внутри строк, заключённых в одинарные кавычки, обратный слеш в качестве разделителя более безопасен, но по-прежнему рекомендуемая практика экранирования обратного слеша во всех строках является наилучшим вариантом.

Ссылаться на неопределённые константы, используя обратный слеш, нельзя. Выводится фатальная ошибка

Любая неопределённая константа, являющаяся неполным именем, как FOO, будет приводить к выводу сообщения о том, что PHP предположил, что FOO было значение константы. Любая константа, с полным или абсолютным именем, которая содержит символ обратного слеша будет приводить к фатальной ошибке, если не будет найдена.

Пример #10 Неопределённые константы

<?php
namespace bar;
$a = FOO; // выводит предупреждение: undefined constants "FOO" assumed "FOO";
$a = \FOO; // фатальная ошибка: undefined namespace constant FOO
$a = Bar\FOO; // фатальная ошибка: undefined namespace constant bar\Bar\FOO
$a = \Bar\FOO; // фатальная ошибка: undefined namespace constant Bar\FOO
?>

Невозможно переопределить специальные константы, такие как NULL, TRUE, FALSE, ZEND_THREAD_SAFE или ZEND_DEBUG_BUILD

Любая попытка определить константу пространства имён, которая совпадает с названиями специальных встроенных констант, приведёт к фатальной ошибке.

Пример #11 Неопределённые константы

<?php
namespace bar;
const
NULL = 0; // Фатальная ошибка;
const true = 'stupid'; // также фатальная ошибка;
// и т.д.
?>




Перечисления

Содержание


Обзор перечислений

(PHP 8 >= 8.1.0)

Перечисления или "Enums" позволяют разработчику определять настраиваемый тип, который ограничен одним из дискретного числа возможных значений. Это может быть особенно полезно при определении модели предметной области, поскольку позволяет "сделать неверные состояния недопустимыми".

Перечисления представлены во многих языках программирования с множеством различных функций. В PHP перечисления - это особый вид объектов. Сами перечисления являются классами и все его возможные случаи являются объектами одного экземпляра этого класса. Это означает, что варианты перечисления являются допустимыми объектами и могут использоваться везде, где можно использовать объект, включая проверки типов.

Самым популярным примером перечислений является встроенный логический тип, который представляет собой перечислимый тип с допустимыми значениями true и false. Перечисления позволяют разработчикам определять свои собственные произвольно надёжные перечисления.



Основы перечислений

Перечисления похожи на классы и используют те же пространства имён, что и классы, интерфейсы и трейты. Они также могут быть загружены автоматически. Перечисления определяют новый тип, который имеет фиксированное ограниченное количество возможных допустимых значений.

<?php
enum Suit
{
case
Hearts;
case
Diamonds;
case
Clubs;
case
Spades;
}
?>

Это объявление создаёт новый перечислимый тип с именем Suit, у которого четыре и только четыре допустимых значения: Suit::Hearts, Suit::Diamonds, Suit::Clubs и Suit::Spades. Переменным может быть присвоено одно из этих допустимых значений. Тип функции может быть проверен на соответствие типу перечисления и в этом случае могут быть переданы только значения этого типа.

<?php
function pick_a_card(Suit $suit) { ... }

$val = Suit::Diamonds;

// OK
pick_a_card($val);
// OK
pick_a_card(Suit::Clubs);
// TypeError: pick_a_card(): Argument #1 ($suit) must be of type Suit, string given
pick_a_card('Spades');
?>

Перечисление может иметь ноль или более вариантов case без ограничений. Перечисление без вариантов синтаксически корректно, хотя и бесполезно.

Для вариантов перечисления применяются те же правила синтаксиса, что и для любой метки в PHP, смотрите Константы.

По умолчанию варианты не поддерживаются скалярным значением. То есть Suit::Hearts не равно "0". Вместо этого каждый вариант поддерживается одноэлементным объектом с таким именем. Это означает, что:

<?php
$a
= Suit::Spades;
$b = Suit::Spades;

$a === $b; // true

$a instanceof Suit; // true
?>

Это также означает, что значения перечисления никогда не являются < или > друг с другом, поскольку эти сравнения не имеют смысла для объектов. Сравнения всегда будут возвращать false при работе с вариантами перечисления.

Тип варианта без связанных данных называется "Чистый вариант". Перечисление, которое содержит только чистые варианты, называется чистым перечислением.

Все чистые варианты реализованы как экземпляры своего типа перечисления. Тип перечисления внутренне представлен как класс.

У всех обращений есть свойство, доступное только для чтения, name, которое является именем самого варианта, чувствительным к регистру.

<?php
print Suit::Spades->name;
// prints "Spades"
?>

Также можно использовать функции defined() и constant() для проверки существования или чтения регистра перечисления, если имя получено динамически. Однако это не рекомендуется, так как для большинства случаев использования перечислений лучше использовать Типизированные перечисления.



Типизированные перечисления

По умолчанию у вариантов перечислений нет скалярного эквивалента. Это просто одноэлементные объекты. Однако существует множество случаев, когда варианты перечислений должны иметь возможность обращаться к базе данных или аналогичному хранилищу данных и обратно, поэтому полезно иметь встроенный скалярный (и, следовательно, тривиально сериализуемый) эквивалент, определённый внутренне.

Чтобы определить скалярный эквивалент для перечислений, используйте следующий синтаксис:

<?php

enum Suit
: string
{
case
Hearts = 'H';
case
Diamonds = 'D';
case
Clubs = 'C';
case
Spades = 'S';
}
?>

Вариант, имеющий скалярный эквивалент, называется типизированным, поскольку он "поддерживается" более простым значением. Перечисление, у которого все варианты типизированные, называется "типизированным перечислением". Типизированное перечисление может содержать только типизированные варианты. Чистое перечисление может содержать только чистые варианты.

Типизированное перечисление может поддерживаться типами int или string и данное перечисление поддерживает только один тип за раз (то есть не допускается объединение int|string). Если перечисление помечено как имеющее скалярный эквивалент, тогда все варианты должны иметь определённый явно уникальный скалярный эквивалент. Не существует автоматически генерируемых скалярных эквивалентов (например, последовательных целых чисел). Типизированные варианты должны быть уникальными; два варианта типизированного перечисления не могут иметь одного и того же скалярного эквивалента. Однако константа может относиться к варианту, фактически создавая псевдоним. Смотрите Константы перечислений.

Эквивалентные значения должны быть строками или строковыми выражениями. Константы и постоянные выражения не поддерживаются. То есть 1 + 1 разрешено, а 1 + SOME_CONST - нет.

У типизированных вариантов есть дополнительное свойство, доступное только для чтения, value, которое является значением, указанным в определении.

<?php
print Suit::Clubs->value;
// Выведет "C"
?>

Чтобы сделать свойство value доступным только для чтения, нельзя назначить переменную в качестве ссылки на неё. То есть следующий код выдаст ошибку:

<?php
$suit
= Suit::Clubs;
$ref = &$suit->value;
// Error: Cannot acquire reference to property Suit::$value
?>

Типизированные перечисления реализуют внутренний интерфейс BackedEnum, который предоставляет два дополнительных метода:

  • from(int|string): self возьмёт скаляр и вернёт соответствующий вариант перечисления. Если вариант не найден, метод выдаст ValueError. Это полезно в тех случаях, когда входной скаляр является доверенным, а отсутствие значения перечисления следует рассматривать как ошибку остановки приложения.
  • tryFrom(int|string): ?self возьмёт скаляр и вернёт соответствующий вариант перечисления. Если вариант не найден, метод вернёт null. Это полезно в тех случаях, когда входной скаляр не является доверенным и вызывающая функция хочет реализовать свою собственную обработку ошибок или логику значения по умолчанию.

Методы from() и tryFrom() следуют стандартным правилам слабой/строгой типизации. В режиме слабой типизации допустима передача целого числа или строки и система соответствующим образом преобразует значение. Передача числа с плавающей точкой также будет работать с принудительным преобразованием. В режиме строгой типизации передача целого числа в from() в перечислении со строковой типизацией (или наоборот) приведёт к TypeError, как и передача числа с плавающей точкой при любых обстоятельствах. Все остальные типы параметров вызовут ошибку TypeError в обоих режимах.

<?php
$record
= get_stuff_from_database($id);
print
$record['suit'];

$suit = Suit::from($record['suit']);

// Недопустимые данные выдают ошибку ValueError: "X" не является допустимым скалярным значением для перечисления "Suit"
print $suit->value;

$suit = Suit::tryFrom('A') ?? Suit::Spades;

// Недопустимые данные возвращают значение null, поэтому вместо этого используется Suit::Spades.
print $suit->value;
?>

Ручное определение метода from() или tryFrom() в типизированных перечислениях приведёт к фатальной ошибке.



Методы перечислений

Перечисления (как чистые перечисления, так и типизированные перечисления) могут содержать методы и могут реализовывать интерфейсы. Если перечисление реализует интерфейс, то любая проверка типа для этого интерфейса также будет принимать все варианты этого перечисления.

<?php

interface Colorful
{
public function
color(): string;
}

enum Suit implements Colorful
{
case
Hearts;
case
Diamonds;
case
Clubs;
case
Spades;

// Выполняет интерфейсный контракт.
public function color(): string
{
return
match($this) {
Suit::Hearts, Suit::Diamonds => 'Красный',
Suit::Clubs, Suit::Spades => 'Чёрный'
};
}

// Не является частью интерфейса; хорошо.
public function shape(): string
{
return
"Rectangle";
}
}

function
paint(Colorful $c) { ... }

paint(Suit::Clubs); // Работает

print Suit::Diamonds->shape(); // выведет "Rectangle"
?>

В этом примере у всех четырёх экземпляров Suit есть два метода: color() и shape(). Что касается вызывающего кода и проверки типов, они ведут себя точно так же, как и любой другой экземпляр объекта.

В типизированных перечислениях объявление интерфейса идёт после объявления типа.

<?php
interface Colorful
{
public function
color(): string;
}

enum Suit: string implements Colorful
{
case
Hearts = 'H';
case
Diamonds = 'D';
case
Clubs = 'C';
case
Spades = 'S';

// Выполняет интерфейсный контракт.
public function color(): string
{
return
match($this) {
Suit::Hearts, Suit::Diamonds => 'Красный',
Suit::Clubs, Suit::Spades => 'Чёрный'
};
}
}
?>

Внутри метода определяется переменная $this, которая ссылается на экземпляр варианта.

Методы могут быть сколь угодно сложными, но на практике обычно возвращают статическое значение или match для $this, чтобы предоставить разные результаты для разных случаев.

Обратите внимание, что в этом случае было бы лучше также определить тип перечисления SuitColor со значениями Red и Black и вернуть его вместо этого. Однако это усложнило бы этот пример.

Вышеупомянутая иерархия логически похожа на следующую структуру классов (хотя это не фактический исполняемый код):

<?php
interface Colorful
{
public function
color(): string;
}

final class
Suit implements UnitEnum, Colorful
{
public const
Hearts = new self('Hearts');
public const
Diamonds = new self('Diamonds');
public const
Clubs = new self('Clubs');
public const
Spades = new self('Spades');

private function
__construct(public readonly string $name) {}

public function
color(): string
{
return
match($this) {
Suit::Hearts, Suit::Diamonds => 'Красный',
Suit::Clubs, Suit::Spades => 'Чёрный'
};
}

public function
shape(): string
{
return
"Прямоугольник";
}

public static function
cases(): array
{
// Недопустимый метод, поскольку определение метода cases() в перечислениях вручную запрещено.
// Смотрите также раздел "Список значений".
}
}
?>

Методы могут быть общедоступными, закрытыми или защищёнными, хотя на практике закрытые и защищённые эквивалентны, поскольку наследование не допускается.



Статические методы перечислений

Перечисления также могут иметь статические методы. Использование статических методов в самом перечислении в первую очередь предназначено для альтернативных конструкторов. Например:

<?php
enum Size
{
case
Small;
case
Medium;
case
Large;

public static function
fromLength(int $cm): static
{
return
match(true) {
$cm < 50 => static::Small,
$cm < 100 => static::Medium,
default => static::
Large,
};
}
}
?>

Статические методы могут быть общедоступными, закрытыми или защищёнными, хотя на практике закрытые и защищённые эквивалентны, поскольку наследование не допускается.



Константы перечислений

Перечисления могут содержать константы, которые могут быть общедоступными, закрытыми или защищёнными, хотя на практике закрытые и защищённые эквивалентны, поскольку наследование не допускается.

Константа перечисления может относиться к варианту перечисления:

<?php
enum Size
{
case
Small;
case
Medium;
case
Large;

public const
Huge = self::Large;
}
?>


Трейты

Перечисления могут использовать трейты, которые будут вести себя так же, как и классы. Предостережение заключается в том, что трейты, используемые (use) в перечислении не должны содержать свойств. Они могут включать только методы и статические методы. Трейт со свойствами приведёт к фатальной ошибке.

<?php
interface Colorful
{
public function
color(): string;
}

trait
Rectangle
{
public function
shape(): string {
return
"Прямоугольник";
}
}

enum Suit implements Colorful
{
use
Rectangle;

case
Hearts;
case
Diamonds;
case
Clubs;
case
Spades;

public function
color(): string
{
return
match($this) {
Suit::Hearts, Suit::Diamonds => 'Красный',
Suit::Clubs, Suit::Spades => 'Чёрный',
};
}
}
?>


Значения перечисления в постоянных выражениях

Поскольку варианты представлены как константы в самом перечислении, они могут использоваться как статические значения в большинстве константных выражений: значения по умолчанию для свойств, значения по умолчанию для статических переменных, значения по умолчанию для параметров, глобальные значения и значения констант класса. Они не могут использоваться в других значениях варианта перечисления, но обычные константы могут относиться к варианту перечисления.

Однако неявные вызовы магических методов, таких как ArrayAccess в перечислениях, не допускаются в статических или константных определениях, поскольку мы не можем абсолютно гарантировать, что результирующее значение будет детерминированным или что вызов метода не будет иметь побочных эффектов. Вызовы функций, вызовы методов и доступ к свойствам по-прежнему являются недопустимыми операциями в постоянных выражениях.

<?php
// Это полностью законное определение перечисления.
enum Direction implements ArrayAccess
{
case
Up;
case
Down;

public function
offsetGet($val) { ... }
public function
offsetExists($val) { ... }
public function
offsetSet($val) { throw new Exception(); }
public function
offsetUnset($val) { throw new Exception(); }
}

class
Foo
{
// Это разрешено.
const Bar = Direction::Down;

// Это запрещено, так как не может быть детерминированным.
const Bar = Direction::Up['short'];
// Fatal error: Cannot use [] on enums in constant expression
}

// Это совершенно законно, потому что это не постоянное выражение.
$x = Direction::Up['short'];
?>


Отличия от объектов

Хотя перечисления построены на классах и объектах, они не поддерживают все функциональные возможности, связанные с объектами. В частности, вариантам перечислений запрещено иметь состояние.

  • Конструкторы и деструкторы запрещены.
  • Наследование не поддерживается. Перечисления не могут наследовать или наследоваться.
  • Статические свойства или свойства объекта не допускаются.
  • Клонирование варианта перечисления не поддерживается, так как варианты должны быть одноэлементными экземплярами.
  • Магические методы, кроме перечисленных ниже, запрещены.
  • Перечисления всегда должны быть объявлены до их использования.

Доступны следующие функциональные возможности объекта, которые ведут себя так же, как и для любого другого объекта:

  • Методы public, private и protected.
  • Статические методы public, private и protected.
  • Константы public, private и protected.
  • Перечисления могут реализовывать любое количество интерфейсов.
  • К перечислениям и вариантам могут быть добавлены атрибуты. Целевой фильтр TARGET_CLASS включает сами перечисления. Целевой фильтр TARGET_CLASS_CONST включает варианты перечислений.
  • Магические методы __call, __callStatic, и __invoke.
  • Константы __CLASS__ и __FUNCTION__ ведут себя как обычно.

Магическая константа ::class для типа перечисления оценивает имя типа, включая любое пространство имён, точно так же, как объект. Магическая константа ::class в экземпляре варианта также оценивается как тип перечисления, поскольку она является экземпляром этого типа.

Кроме того, варианты перечисления не могут быть созданы напрямую с помощью new или с помощью ReflectionClass::newInstanceWithoutConstructor(). Оба способа приведут к ошибке.

<?php
$clovers
= new Suit();
// Error: Cannot instantiate enum Suit
$horseshoes = (new ReflectionClass(Suit::class))->newInstanceWithoutConstructor()
// Error: Cannot instantiate enum Suit
?>


Список значений

И чистые перечисления, и типизированные перечисления реализуют внутренний интерфейс с именем UnitEnum. UnitEnum включает статический метод cases(). cases() возвращает упакованный массив всех определённых вариантов в порядке объявления.

<?php
Suit
::cases();
// Produces: [Suit::Hearts, Suit::Diamonds, Suit::Clubs, Suit::Spades]
?>

Ручное определение метода cases() в перечислении приведёт к фатальной ошибке.



Сериализация

Перечисления сериализуются иначе, чем объекты. В частности, у них есть новый код сериализации, "E", который указывает имя варианта перечисления. Затем процедура десериализации может использовать это для установки переменной в существующее одноэлементное значение. Это гарантирует, что:

<?php
Suit
::Hearts === unserialize(serialize(Suit::Hearts));

print
serialize(Suit::Hearts);
// E:11:"Suit:Hearts";
?>

При десериализации, если не удаётся найти перечисление и сопоставить с соответствующим сериализованным значением, будет выдано предупреждение и будет возвращено false.

Если чистое перечисление сериализуется в JSON, будет выдана ошибка. Если типизированное перечисление сериализуется в JSON, оно будет представлено только его скаляром значений в соответствующем типе. Поведение обоих способов может быть изменено путём реализации JsonSerializable.

Для print_r() вывод варианта перечисления немного отличается от объектов, чтобы свести к минимуму путаницу.

<?php
enum Foo
{
case
Bar;
}

enum Baz: int {
case
Beep = 5;
}

print_r(Foo::Bar);
print_r(Baz::Beep);

/* Выводит

Foo Enum (
[name] => Bar
)
Baz Enum:int {
[name] => Beep
[value] => 5
}
*/
?>


Почему перечисления не расширяемы

У классов есть контракты на их методы:

<?php

class A {}
class
B extends A {}

function
foo(A $a) {}

function
bar(B $b) {
foo($b);
}
?>

Этот код безопасен для типов, поскольку B следует контракту A, и, благодаря магии ковариантности и контравариантности, любое ожидание, которое может быть у человека в отношении методов, будет сохранено, за исключением исключений.

У перечислений есть контракты их варианты, а не методы:

<?php
enum ErrorCode
{
case
SOMETHING_BROKE;
}

function
quux(ErrorCode $errorCode)
{
// Кажется, что этот код охватывает все варианты
match ($errorCode) {
ErrorCode::SOMETHING_BROKE => true,
}
}

?>

Оператор match в функции quux может быть статически проанализирован, чтобы охватить все случаи в ErrorCode.

Но представьте, что было бы разрешено расширять перечисления:

<?php
// Экспериментальный код, в котором перечисления не являются конечными.
// Обратите внимание, что это не будет работать в PHP.
enum MoreErrorCode extends ErrorCode {
case
PEBKAC;
}

function
fot(MoreErrorCode $errorCode) {
quux($errorCode);
}

fot(MoreErrorCode::PEBKAC);

?>

Согласно обычным правилам наследования, класс, расширяющий другой класс, пройдёт проверку типа.

Проблема заключается в том, что оператор match в quux() уже не охватывает все случаи. Поскольку оно не знает о MoreErrorCode::PEBKAC, match выбросит исключение.

Из-за этого перечисления являются окончательными и не могут быть расширены.



Примеры

Пример #1 Основные ограниченные значения

<?php
enum SortOrder
{
case
Asc;
case
Desc;
}

function
query($fields, $filter, SortOrder $order = SortOrder::Asc) { ... }
?>

Функция query() теперь может безопасно работать, зная, что $order гарантированно будет либо SortOrder::Asc, либо SortOrder::Desc. Любое другое значение привело бы к TypeError, поэтому дальнейшая проверка ошибок или тестирование не требуется.

Пример #2 Расширенные эксклюзивные значения

<?php
enum UserStatus
: string
{
case
Pending = 'P';
case
Active = 'A';
case
Suspended = 'S';
case
CanceledByUser = 'C';

public function
label(): string
{
return
match($this) {
static::
Pending => 'В ожидании',
static::
Active => 'Активный',
static::
Suspended => 'Приостановленный',
static::
CanceledByUser => 'Отменено пользователем',
};
}
}
?>

В этом примере статус пользователя может быть одним из следующих: UserStatus::Pending, UserStatus::Active, UserStatus::Suspended или UserStatus::CanceledByUser. Функция может ввести параметр UserStatus и затем принять только эти четыре значения, точка.

У всех четырёх значений есть метод label(), который возвращает читаемую строку. Эта строка не зависит от скалярной эквивалентной строки "machine name", которую можно использовать, например, в поле базы данных или поле выбора HTML.

<?php
foreach (UserStatus::cases() as $case) {
printf('<option value="%s">%s</option>\n', $case->value, $case->label());
}
?>




Ошибки

Содержание

Введение

К сожалению, как бы мы ни были аккуратны при написании кода, ошибки являются частью нашей жизни. PHP будет сообщать об ошибках, предупреждениях и уведомлениях о самых распространённых проблемах кода и времени исполнения, но знания, как разобраться в ошибках и как их обработать, могут сильно упростить процесс отладки.


Основы

PHP сообщает об ошибках в ответ на некоторые внутренние ошибочные обстоятельства. Они могут быть использованы для уведомления о разных состояниях, а также могут выводиться на экран и записываться в логи по желанию.

Каждая ошибка, генерируемая PHP, обязательно содержит информацию о своём типе. В этом списке перечислены все типы ошибок, а также описания их поведений и провоцирующие их причины.

Обработка ошибок

PHP, по умолчанию, может обрабатывать любые ошибки в соответствии со своей конфигурацией, если обработчик ошибок не установлен. О каких ошибках сообщать и какие ошибки игнорировать указывается в параметре error_reporting конфигурации php.ini, или во время исполнения программы с помощью вызова error_reporting(). Настоятельно рекомендуется заранее конфигурировать php.ini, так как некоторые ошибки могут произойти до начала выполнения вашего скрипта.

На стадии разработки, обязательно настройте параметр error_reporting на значение E_ALL, так как вам необходимо знать обо всех ошибках для их решения на этой стадии. Когда продукт готов, вы можете изменить значение на менее подробное, вроде E_ALL & ~E_NOTICE & ~E_DEPRECATED, но во многих случаях значение E_ALL также желательно, так как оно может предупреждать заранее о других возможных ошибках.

Дальнейшая работа PHP с появившимися ошибками зависит от двух других параметров в php.ini. Параметр display_errors определяет, включать ли данные ошибки в вывод скрипта или нет. Когда продукт готов, обязательно выключите этот параметр, так как в описании ошибки может содержаться конфиденциальная информация, вроде паролей базы данных. Во время разработки данный параметр лучше включить для решения проблем, провоцирующих ошибки.

Кроме отображения ошибок, их можно записывать в лог с помощью включённого параметра log_errors. Файл лога указывается в параметре error_log. Данная функция незаменима на стадии конечного продукта, так как позволяет видеть информацию об ошибках и составлять основанные на них отчёты вдали от глаз пользователя.

Пользовательская обработка ошибок

Если вас не устраивает работа предустановленного обработчика ошибок, вы также можете обрабатывать множество видов ошибки с помощью своего обработчика, который можно установить вызовом функции set_error_handler(). Некоторые ошибки не могут обрабатываться пользовательским обработчиком, но те, которые могут, обрабатываются по вашему желанию: например, ваш скрипт может выдавать пользователю любую отдельную страницу ошибки, а подробную информацию записывать в лог или отсылать по почте.



Ошибки в PHP 7

В PHP 7 механизм сообщения об ошибках был сильно изменён. Традиционное оповещение об ошибке в PHP 5 было заменено новым механизмом, в котором большинство ошибок вызываются с помощью исключений класса Error.

Как и обычные исключения, исключения Error вызываются до появления первого соответствующего блока catch. Если соответствующие блоки не предусмотрены, то будет вызван любой обработчик исключений, установленный с помощью set_exception_handler(). В случае отсутствия обработчика по умолчанию, исключение будет конвертировано в фатальную ошибку и будет обработано как традиционная ошибка.

Поскольку класс Error не наследуется от класса Exception, блок catch (Exception $e) { ... } для обработки неперехваченных исключений PHP 5 не может перехватить исключения Error. Для их перехвата используйте блок catch (Error $e) { ... } или установите обработчик исключений с помощью set_exception_handler().




Исключения

Содержание

В PHP реализована модель исключений, аналогичная тем, что используются в других языках программирования. Исключение в PHP может быть выброшено (throw) и поймано (catch). Код может быть заключён в блок try, чтобы облегчить обработку потенциальных исключений. У каждого блока try должен быть как минимум один соответствующий блок catch или finally.

Если выброшено исключение, а в текущей области видимости функции нет блока catch, исключение будет "подниматься" по стеку вызовов к вызывающей функции, пока не найдёт подходящий блок catch. Все блоки finally, которые встретятся на этом пути, будут выполнены. Если стек вызовов разворачивается до глобальной области видимости, не встречая подходящего блока catch, программа завершается с неисправимой ошибкой, если не был установлен глобальный обработчик исключений.

Выброшенный объект должен наследовать (instanceof) интерфейс Throwable. Попытка выбросить объект, который таковым не является, приведёт к неисправимой ошибке PHP.

Начиная с PHP 8.0.0, ключевое слово throw является выражением и может быть использовано в любом контексте выражения. В предыдущих версиях оно было утверждением и должно было располагаться в отдельной строке.

catch

Блок catch определяет, как реагировать на выброшенное исключение. Блок catch определяет один или несколько типов исключений или ошибок, которые он может обработать, и, по желанию, переменную, которой можно присвоить исключение (указание переменной было обязательно до версии PHP 8.0.0). Первый блок catch, с которым столкнётся выброшенное исключение или ошибка и соответствует типу выброшенного объекта, обработает объект.

Несколько блоков catch могут быть использованы для перехвата различных классов исключений. Нормальное выполнение (когда исключение не выброшено в блоке try) будет продолжаться после последнего блока catch, определённого в последовательности. Исключения могут быть выброшены (throw) (или повторно выброшены) внутри блока catch. В противном случае выполнение будет продолжено после блока catch, который был вызван.

При возникновении исключения, код, следующий за утверждением, не будет выполнен, а PHP попытается найти первый подходящий блок catch. Если исключение не поймано, будет выдана неисправимая ошибка PHP с сообщением "Uncaught Exception ...", если только обработчик не был определён с помощью функции set_exception_handler().

Начиная с версии PHP 7.1.0, в блоке catch можно указывать несколько исключений, используя символ |. Это полезно, когда разные исключения из разных иерархий классов обрабатываются одинаково.

Начиная с версии PHP 8.0.0, имя переменной для пойманного исключения является необязательным. Если оно не указано, блок catch будет выполнен, но не будет иметь доступа к выброшенному объекту.

finally

Блок finally также может быть указан после или вместо блоков catch. Код в блоке finally всегда будет выполняться после блоков try и catch, независимо от того, было ли выброшено исключение и до возобновления нормального выполнения.

Одно из заметных взаимодействий происходит между блоком finally и оператором return. Если оператор return встречается внутри блоков try или catch, блок finally всё равно будет выполнен. Более того, оператор return выполнится, когда встретится, но результат будет возвращён после выполнения блока finally. Кроме того, если блок finally также содержит оператор return, возвращается значение из блока finally.

Глобальный обработчик исключений

Если исключению разрешено распространяться на глобальную область видимости, оно может быть перехвачено глобальным обработчиком исключений, если он установлен. Функция set_exception_handler() может задать функцию, которая будет вызвана вместо блока catch, если не будет вызван никакой другой блок. Эффект по сути такой же, как если бы вся программа была обёрнута в блок try-catch с этой функцией в качестве catch.

Примечания

Замечание:

Внутренние функции PHP в основном используют отчёт об ошибках, только современные объектно-ориентированные модули используют исключения. Однако ошибки можно легко перевести в исключения с помощью класса ErrorException. Однако эта техника работает только с исправляемыми ошибками.

Пример #1 Преобразование отчётов об ошибках в исключения

<?php
function exceptions_error_handler($severity, $message, $filename, $lineno) {
throw new
ErrorException($message, 0, $severity, $filename, $lineno);
}

set_error_handler('exceptions_error_handler');
?>

Подсказка

Библиотека Стандартная библиотека PHP (SPL) предоставляет большое количество встроенных исключений.

Примеры

Пример #2 Выбрасывание исключения

<?php
function inverse($x) {
if (!
$x) {
throw new
Exception('Деление на ноль.');
}
return
1/$x;
}

try {
echo
inverse(5) . "\n";
echo
inverse(0) . "\n";
} catch (
Exception $e) {
echo
'Выброшено исключение: ', $e->getMessage(), "\n";
}

// Продолжение выполнения
echo "Привет, мир\n";
?>

Результат выполнения данного примера:

0.2
Выброшено исключение: Деление на ноль.
Привет, мир

Пример #3 Обработка исключений с помощью блока finally

<?php
function inverse($x) {
if (!
$x) {
throw new
Exception('Деление на ноль.');
}
return
1/$x;
}

try {
echo
inverse(5) . "\n";
} catch (
Exception $e) {
echo
'Поймано исключение: ', $e->getMessage(), "\n";
} finally {
echo
"Первый блок finally.\n";
}

try {
echo
inverse(0) . "\n";
} catch (
Exception $e) {
echo
'Поймано исключение: ', $e->getMessage(), "\n";
} finally {
echo
"Второй блок finally.\n";
}

// Продолжение нормального выполнения
echo "Привет, мир\n";
?>

Результат выполнения данного примера:

0.2
Первый блок finally.
Поймано исключение: Деление на ноль.
Второй блок finally.
Привет, мир

Пример #4 Взаимодействие между блоками finally и return

<?php

function test() {
try {
throw new
Exception('foo');
} catch (
Exception $e) {
return
'catch';
} finally {
return
'finally';
}
}

echo
test();
?>

Результат выполнения данного примера:

finally

Пример #5 Вложенные исключения

<?php

class MyException extends Exception { }

class
Test {
public function
testing() {
try {
try {
throw new
MyException('foo!');
} catch (
MyException $e) {
// повторный выброс исключения
throw $e;
}
} catch (
Exception $e) {
var_dump($e->getMessage());
}
}
}

$foo = new Test;
$foo->testing();

?>

Результат выполнения данного примера:

string(4) "foo!"

Пример #6 Обработка нескольких исключений в одном блоке catch

<?php

class MyException extends Exception { }

class
MyOtherException extends Exception { }

class
Test {
public function
testing() {
try {
throw new
MyException();
} catch (
MyException | MyOtherException $e) {
var_dump(get_class($e));
}
}
}

$foo = new Test;
$foo->testing();

?>

Результат выполнения данного примера:

string(11) "MyException"

Пример #7 Пример блока catch без указания переменной

Допустимо начиная с PHP 8.0.0

<?php

class SpecificException extends Exception {}

function
test() {
throw new
SpecificException('Ой!');
}

try {
test();
} catch (
SpecificException) {
print
"Было поймано исключение SpecificException, но нам безразлично, что у него внутри.";
}
?>

Пример #8 Throw как выражение

Допустимо начиная с PHP 8.0.0

<?php

function test() {
do_something_risky() or throw new Exception('Всё сломалось');
}

try {
test();
} catch (
Exception $e) {
print
$e->getMessage();
}
?>

Наследование исключений

Определённый пользователем класс исключения должен быть определён, как класс расширяющий (наследующий) встроенный класс Exception. Ниже приведены методы и свойства класса Exception, доступные дочерним классам.

Пример #1 Встроенный класс Exception

<?php
class Exception implements Throwable
{
protected
$message = 'Unknown exception'; // сообщение об исключении
private $string; // свойство для __toString
protected $code = 0; // пользовательский код исключения
protected $file; // файл, в котором было выброшено исключение
protected $line; // строка, в которой было выброшено исключение
private $trace; // трассировка вызовов методов и функций
private $previous; // предыдущее исключение, если исключение вложенное

public function __construct($message = '', $code = 0, Throwable $previous = null);

final private function
__clone(); // запрещает клонирования исключения

final public function getMessage(); // сообщение исключения
final public function getCode(); // код исключения
final public function getFile(); // файл, где выброшено исключение
final public function getLine(); // строка, на которой выброшено исключение
final public function getTrace(); // массив backtrace()
final public function getPrevious(); // предыдущее исключение
final public function getTraceAsString(); // отформатированная строка трассировки

// Переопределяемый
public function __toString(); // отформатированная строка для отображения
}
?>

Если класс, наследуемый от Exception переопределяет конструктор, необходимо вызвать в конструкторе parent::__construct(), чтобы быть уверенным, что все доступные данные были правильно присвоены. Метод __toString() может быть переопределён, чтобы обеспечить нужный вывод, когда объект преобразуется в строку.

Замечание:

Исключения нельзя клонировать. Попытка клонировать исключение приведёт к неисправимой ошибке E_ERROR.

Пример #2 Наследование класса Exception

<?php
/**
* Определим свой класс исключения
*/
class MyException extends Exception
{
// Переопределим исключение так, что параметр message станет обязательным
public function __construct($message, $code = 0, Throwable $previous = null) {
// некоторый код

// убедитесь, что все передаваемые параметры верны
parent::__construct($message, $code, $previous);
}

// Переопределим строковое представление объекта.
public function __toString() {
return
__CLASS__ . ": [{$this->code}]: {$this->message}\n";
}

public function
customFunction() {
echo
"Мы можем определять новые методы в наследуемом классе\n";
}
}


/**
* Создадим класс для тестирования исключения
*/
class TestException
{
public
$var;

const
THROW_NONE = 0;
const
THROW_CUSTOM = 1;
const
THROW_DEFAULT = 2;

function
__construct($avalue = self::THROW_NONE) {

switch (
$avalue) {
case
self::THROW_CUSTOM:
// Выбрасываем собственное исключение
throw new MyException('1 - неправильный параметр', 5);
break;

case
self::THROW_DEFAULT:
// Выбрасываем встроеное исключение
throw new Exception('2 - недопустимый параметр', 6);
break;

default:
// Никаких исключений, объект будет создан.
$this->var = $avalue;
break;
}
}
}

// Пример 1
try {
$o = new TestException(TestException::THROW_CUSTOM);
} catch (
MyException $e) { // Будет перехвачено
echo "Поймано собственное переопределённое исключение\n", $e;
$e->customFunction();
} catch (
Exception $e) { // Будет пропущено
echo "Поймано встроенное исключение\n", $e;
}

// Отсюда будет продолжено выполнение программы
var_dump($o); // Null
echo "\n\n";


// Пример 2
try {
$o = new TestException(TestException::THROW_DEFAULT);
} catch (
MyException $e) { // Тип исключения не совпадёт
echo "Поймано переопределённое исключение\n", $e;
$e->customFunction();
} catch (
Exception $e) { // Будет перехвачено
echo "Перехвачено встроенное исключение\n", $e;
}

// Отсюда будет продолжено выполнение программы
var_dump($o); // Null
echo "\n\n";


// Пример 3
try {
$o = new TestException(TestException::THROW_CUSTOM);
} catch (
Exception $e) { // Будет перехвачено
echo "Поймано встроенное исключение\n", $e;
}

// Продолжение исполнения программы
var_dump($o); // Null
echo "\n\n";


// Пример 4
try {
$o = new TestException();
} catch (
Exception $e) { // Будет пропущено, т.к. исключение не выбрасывается
echo "Поймано встроенное исключение\n", $e;
}

// Продолжение выполнения программы
var_dump($o); // TestException
echo "\n\n";
?>



Fibers

Обзор файберов

(PHP 8 >= 8.1.0)

Файберы представляют собой прерываемые функции полного цикла. Файберы могут быть приостановлены из любого места цикла, приостанавливая выполнение в файбере до тех пор, пока файбер не будет возобновлён в будущем.

Файберы приостанавливают весь цикл выполнения, поэтому вызывающему функцию напрямую не нужно менять способ её вызова.

Выполнение может быть прервано в любом месте цикла с помощью метода Fiber::suspend() (то есть вызов Fiber::suspend() может находиться в глубоко вложенной функции или даже вообще не существовать).

В отличие от генераторов (Generator) без стека, у каждого объекта Fiber есть свой собственный стек вызовов, позволяющий приостанавливать их внутри глубоко вложенных вызовов функций. Функция, объявляющая точку прерывания (то есть вызов метода Fiber::suspend()), не должна изменять свой возвращаемый тип, в отличие от функции, использующей yield, который должен возвращать экземпляр Generator.

Файберы могут быть приостановлены при вызове любой функции, включая те, которые вызываются из виртуальной машины PHP, например, функции, предоставляемые array_map(), или методы, вызываемые foreach для объекта Iterator.

После приостановки выполнение файбера может быть возобновлено с любым значением с помощью метода Fiber::resume() или путём передачи исключения в файбер с помощью Fiber::throw(). Значение возвращается (или выбрасывается исключение) из метода Fiber::suspend().

Замечание: Из-за текущих ограничений невозможно переключать файбер в деструкторе объекта.

Пример #1 Простой пример

<?php
$fiber
= new Fiber(function (): void {
$value = Fiber::suspend('fiber');
echo
"Значение возобновлённого файбера: ", $value, PHP_EOL;
});

$value = $fiber->start();

echo
"Значение приостановленного файбера: ", $value, PHP_EOL;

$fiber->resume('test');
?>

Результат выполнения данного примера:

Значение приостановленного файбера: fiber
Значение возобновлённого файбера: test


Генераторы

Содержание


Знакомство с генераторами

(PHP 5 >= 5.5.0, PHP 7, PHP 8)

Генераторы предоставляют лёгкий способ реализации простых итераторов без использования дополнительных ресурсов или сложностей, связанных с реализацией класса, реализующего интерфейс Iterator.

Генератор позволяет вам писать код, использующий foreach для перебора набора данных без необходимости создания массива в памяти, что может привести к превышению лимита памяти, либо потребует довольно много времени для его создания. Вместо этого, вы можете написать функцию-генератор, которая, по сути, является обычной функцией, за исключением того, что вместо возврата единственного значения, генератор может возвращать (yield) столько раз, сколько необходимо для генерации значений, позволяющих перебрать исходный набор данных.

Наглядным примером вышесказанного может послужить использование функции range() как генератора. Стандартная функция range() генерирует массив, состоящий из значений, и возвращает его, что может привести к генерации огромных массивов данных. Например, вызов range(0, 1000000) приведёт к использованию более 100 МБ оперативной памяти.

В качестве альтернативы мы можем создать генератор xrange(), который использует память только для создания объекта Iterator и сохранения текущего состояния, что потребует не больше 1 килобайта памяти.

Пример #1 Реализация range() как генератора

<?php
function xrange($start, $limit, $step = 1) {
if (
$start <= $limit) {
if (
$step <= 0) {
throw new
LogicException('Шаг должен быть положительным');
}

for (
$i = $start; $i <= $limit; $i += $step) {
yield
$i;
}
} else {
if (
$step >= 0) {
throw new
LogicException('Шаг должен быть отрицательным');
}

for (
$i = $start; $i >= $limit; $i += $step) {
yield
$i;
}
}
}

/* Обратите внимание, что и range() и xrange() дадут один и тот же вывод */

echo 'Нечётные однозначные числа с помощью range(): ';
foreach (
range(1, 9, 2) as $number) {
echo
"$number ";
}
echo
"\n";

echo
'Нечётные однозначные числа с помощью xrange(): ';
foreach (
xrange(1, 9, 2) as $number) {
echo
"$number ";
}
?>

Результат выполнения данного примера:

Нечётные однозначные числа с помощью range():  1 3 5 7 9
Нечётные однозначные числа с помощью xrange(): 1 3 5 7 9

Объект Generator

Когда функция генератор вызывается, она вернёт объект встроенного класса Generator. Этот объект реализует интерфейс Iterator, станет однонаправленным объектом итератора и предоставит методы, с помощью которых можно управлять его состоянием, включая передачу в него и возвращения из него значений.



Синтаксис генераторов

Генератор в целом выглядит как обычная функция, за исключением того, что вместо возвращения одного значения, генератор будет перебирать столько значений, сколько необходимо. Любая функция, содержащая yield, является функцией генератора.

Когда вызывается генератор, он возвращает объект, который можно итерировать. Когда вы итерируете этот объект (например, в цикле foreach), PHP вызывает методы итерации объекта каждый раз, когда вам нужно новое значение, после чего сохраняет состояние генератора и при следующем вызове возвращает следующее значение.

Когда все значения в генераторе закончились, генератор просто завершит работу, ничего не вернув. После этого основной код продолжит работу, как если бы в массиве закончились элементы для перебора.

Замечание:

Генераторы могут возвращать значения, которые можно получить с помощью Generator::getReturn().

Ключевое слово yield

Вся суть генератора заключается в ключевом слове yield. В самом простом варианте оператор "yield" можно рассматривать как оператор "return", за исключением того, что вместо прекращения работы функции, "yield" только приостанавливает её выполнение и возвращает текущее значение, и при следующем вызове функции она возобновит выполнение с места, на котором прервалась.

Пример #1 Простой пример выдачи значений

<?php
function gen_one_to_three() {
for (
$i = 1; $i <= 3; $i++) {
// Обратите внимание, что $i сохраняет своё значение между вызовами.
yield $i;
}
}

$generator = gen_one_to_three();
foreach (
$generator as $value) {
echo
"$value\n";
}
?>

Результат выполнения данного примера:

1
2
3

Замечание:

Последовательность целых чисел будет связана с получаемыми от генератора значениями, как будто перебирается неассоциативный массив.

Получение значений с ключами

PHP поддерживает ассоциативные массивы, и генераторы не являются исключением. Так же как можно получать простые значения, как показано выше, вы можете получать значения с ключами.

Синтаксис получения ключ/значение очень похож на синтаксис ассоциативных массивов, как показано ниже.

Пример #2 Получение пар ключ/значение

<?php
/* $input содержит пары ключ/значение разделённые точкой с запятой */

$input = <<<'EOF'
1;PHP;Любит знаки доллара
2;Python;Любит пробелы
3;Ruby;Любит блоки
EOF;

function
input_parser($input) {
foreach (
explode("\n", $input) as $line) {
$fields = explode(';', $line);
$id = array_shift($fields);

yield
$id => $fields;
}
}

foreach (
input_parser($input) as $id => $fields) {
echo
"$id:\n";
echo
" $fields[0]\n";
echo
" $fields[1]\n";
}
?>

Результат выполнения данного примера:

1:
    PHP
    Любит знаки доллара
2:
    Python
    Любит пробелы
3:
    Ruby
    Любит блоки

Получение NULL

Для получения null нужно вызвать "yield" без аргументов. Ключ сгенерируется автоматически.

Пример #3 Получение null

<?php
function gen_three_nulls() {
foreach (
range(1, 3) as $i) {
yield;
}
}

var_dump(iterator_to_array(gen_three_nulls()));
?>

Результат выполнения данного примера:

array(3) {
  [0]=>
  NULL
  [1]=>
  NULL
  [2]=>
  NULL
}

Получение значения по ссылке

Генераторы могут отдавать значения по ссылке. Это делается так же, как возврат ссылок из функций: добавлением амперсанда (&) перед именем функции.

Пример #4 Получение значений по ссылке

<?php
function &gen_reference() {
$value = 3;

while (
$value > 0) {
yield
$value;
}
}

/* Обратите внимание, что мы можем изменять $number в цикле, и
* так как генератор возвращает ссылку, $value
* в gen_reference() также изменится. */
foreach (gen_reference() as &$number) {
echo (--
$number).'... ';
}
?>

Результат выполнения данного примера:

2... 1... 0...

Делегирование генератора с помощью yield from

Делегирование генератора позволяет вам получать значения из другого генератора, объекта Traversable, или массива, используя yield from. Внешний генератор будет возвращать значения из внутреннего генератора, объекта или массива, до того момента, пока они их отдают, после чего продолжится выполнение внешнего генератора.

Если генератор используется с yield from, то выражение yield from также будет возвращать значения из внутреннего генератора.

Предостережение

Сохранение в массив (например, с помощью iterator_to_array())

yield from не сбрасывает ключи. Ключи, возвращённые из объекта Traversable или массива, сохранятся. Таким образом, некоторые значения, могут пересекаться по ключам с другими yield или yield from, что, при записи в массив, повлечёт за собой перезапись прежних значений.

Общий случай, когда это имеет значение, это когда iterator_to_array() возвращает массив с ключами по умолчанию. В этом случае можно получить неожиданный результат. iterator_to_array() имеет второй параметр preserve_keys, который можно установить в false, для генерации собственных ключей и игнорирования ключей, переданных из объекта Generator.

Пример #5 yield from с iterator_to_array()

<?php
function inner() {
yield
1; // ключ 0
yield 2; // ключ 1
yield 3; // ключ 2
}
function
gen() {
yield
0; // ключ 0
yield from inner(); // ключи 0-2
yield 4; // ключ 1
}
// Задайте false вторым параметром для получения массива [0, 1, 2, 3, 4]
var_dump(iterator_to_array(gen()));
?>

Результат выполнения данного примера:

array(3) {
  [0]=>
  int(1)
  [1]=>
  int(4)
  [2]=>
  int(3)
}

Пример #6 Основы использования yield from

<?php
function count_to_ten() {
yield
1;
yield
2;
yield from [
3, 4];
yield from new
ArrayIterator([5, 6]);
yield from
seven_eight();
yield
9;
yield
10;
}

function
seven_eight() {
yield
7;
yield from
eight();
}

function
eight() {
yield
8;
}

foreach (
count_to_ten() as $num) {
echo
"$num ";
}
?>

Результат выполнения данного примера:

1 2 3 4 5 6 7 8 9 10

Пример #7 yield from и возвращаемые значения

<?php
function count_to_ten() {
yield
1;
yield
2;
yield from [
3, 4];
yield from new
ArrayIterator([5, 6]);
yield from
seven_eight();
return yield from
nine_ten();
}

function
seven_eight() {
yield
7;
yield from
eight();
}

function
eight() {
yield
8;
}

function
nine_ten() {
yield
9;
return
10;
}

$gen = count_to_ten();
foreach (
$gen as $num) {
echo
"$num ";
}
echo
$gen->getReturn();
?>

Результат выполнения данного примера:

1 2 3 4 5 6 7 8 9 10


Сравнение генераторов с объектами класса Iterator

Главное преимущество генераторов - это их простота. Гораздо меньше шаблонного кода надо написать, по сравнению с реализацией объекта класса Iterator, и этот код гораздо более простой и понятный. К примеру, эта функция и класс делают одно и то же.

<?php
function getLinesFromFile($fileName) {
if (!
$fileHandle = fopen($fileName, 'r')) {
return;
}

while (
false !== $line = fgets($fileHandle)) {
yield
$line;
}

fclose($fileHandle);
}

// Против...

class LineIterator implements Iterator {
protected
$fileHandle;

protected
$line;
protected
$i;

public function
__construct($fileName) {
if (!
$this->fileHandle = fopen($fileName, 'r')) {
throw new
RuntimeException('Невозможно открыть файл "' . $fileName . '"');
}
}

public function
rewind() {
fseek($this->fileHandle, 0);
$this->line = fgets($this->fileHandle);
$this->i = 0;
}

public function
valid() {
return
false !== $this->line;
}

public function
current() {
return
$this->line;
}

public function
key() {
return
$this->i;
}

public function
next() {
if (
false !== $this->line) {
$this->line = fgets($this->fileHandle);
$this->i++;
}
}

public function
__destruct() {
fclose($this->fileHandle);
}
}
?>

Однако за эту простоту, впрочем, приходится платить: генераторы могут быть только однонаправленными итераторами. Их нельзя перемотать назад после старта итерации. Это также означает, что один и тот же генератор нельзя использовать несколько раз: генератор необходимо пересоздавать каждый раз, снова вызвав функцию генератора.

Смотрите также




Атрибуты

Содержание


Введение в атрибуты

(PHP 8)

Атрибуты предлагают возможность добавлять структурированные, машиночитаемые метаданные для следующих деклараций в коде: классы, методы, функции, параметры, свойства и константы класса. Привязанные метаданные можно получить во время исполнения, используя Reflection API. Таким образом, атрибуты можно рассматривать как язык конфигурации, встроенный непосредственно в код.

С помощью атрибутов можно разделить абстрактную реализацию какой-либо функциональности и особенности её использования в коде. В некотором смысле это можно сравнить с разделением интерфейса и его реализаций. Но интерфейсы и реализации - это про код, а атрибуты - про добавление дополнительной информации и конфигурацию. Интерфейсы могут реализовываться только классами, тогда как атрибуты также применимы для методов, функций, параметров, свойств и констант классов. Таким образом, они представляют собой гораздо более гибкий механизм, чем интерфейсы.

Давайте разберём использование атрибутов на простом примере реализации опциональных методов для интерфейса. Допустим, что интерфейс ActionHandler описывает некую операцию в приложении. Одни реализации этого интерфейса требуют предварительной настройки, а другие - нет. И вместо того, чтобы вносить в интерфейс ActionHandler дополнительный метод setUp(), который для части реализаций будет пустым, можно использовать атрибут. Одним из преимуществ этого подхода является то, что мы можем использовать атрибут несколько раз.

Пример #1 Реализация опциональных методов интерфейса с помощью атрибутов

<?php
interface ActionHandler
{
public function
execute();
}

#[Attribute]
class SetUp {}

class
CopyFile implements ActionHandler
{
public
string $fileName;
public
string $targetDirectory;

#[SetUp]
public function fileExists()
{
if (!
file_exists($this->fileName)) {
throw new
RuntimeException("File does not exist");
}
}

#[SetUp]
public function targetDirectoryExists()
{
if (!
file_exists($this->targetDirectory)) {
mkdir($this->targetDirectory);
} elseif (!
is_dir($this->targetDirectory)) {
throw new
RuntimeException("Target directory $this->targetDirectory is not a directory");
}
}

public function
execute()
{
copy($this->fileName, $this->targetDirectory . '/' . basename($this->fileName));
}
}

function
executeAction(ActionHandler $actionHandler)
{
$reflection = new ReflectionObject($actionHandler);

foreach (
$reflection->getMethods() as $method) {
$attributes = $method->getAttributes(SetUp::class);

if (
count($attributes) > 0) {
$methodName = $method->getName();

$actionHandler->$methodName();
}
}

$actionHandler->execute();
}

$copyAction = new CopyFile();
$copyAction->fileName = "/tmp/foo.jpg";
$copyAction->targetDirectory = "/home/user";

executeAction($copyAction);


Синтаксис атрибутов

Синтаксис атрибутов состоит из нескольких частей. Для начала декларация атрибута всегда начинается с символа #[ и заканчивается ]. Внутри перечисление из одного или более, разделённых запятой, атрибутов. Атрибуты можно задавать с помощью неполных, полных и абсолютных имён, как описано в разделе Использование пространства имён: основы. Аргументы атрибутов опциональны, но если они есть, то заключаются в скобки (). Аргументы атрибутов могут быть либо конкретными значениями, либо константными выражениями. Для аргументов можно использовать как позиционный синтаксис, так и синтаксис именованных аргументов.

Когда атрибут запрашивается с помощью Reflection API, его имя трактуется как имя класса, а аргументы передаются в его конструктор. Таким образом, для каждого атрибута должен существовать соответствующий класс.

Пример #1 Синтаксис атрибутов

<?php
// a.php
namespace MyExample;

use
Attribute;

#[Attribute]
class MyAttribute
{
const
VALUE = 'value';

private
$value;

public function
__construct($value = null)
{
$this->value = $value;
}
}

// b.php

namespace Another;

use
MyExample\MyAttribute;

#[MyAttribute]
#[\MyExample\MyAttribute]
#[MyAttribute(1234)]
#[MyAttribute(value: 1234)]
#[MyAttribute(MyAttribute::VALUE)]
#[MyAttribute(array("key" => "value"))]
#[MyAttribute(100 + 200)]
class Thing
{
}

#[MyAttribute(1234), MyAttribute(5678)]
class AnotherThing
{
}


Чтение атрибутов с помощью Reflection API

Для доступа к атрибутам классов, методов, функций, параметров, свойств и констант класса, в Reflection API присутствует метод getAttributes() для каждого из перечисленных объектов рефлексии. Этот метод возвращает массив экземпляров ReflectionAttribute, у каждого из которых можно запросить имя атрибута и его аргументы, а также создать объект, представляющего атрибут.

Такое отделение свойств атрибута от явного создания объекта даёт программисту более полный контроль над обработкой ошибок, связанных с отсутствующим классом атрибута и некорректностью его аргументов. Объект атрибута будет создан и проверен на корректность аргументов только после вызова ReflectionAttribute::newInstance(), не раньше.

Пример #1 Чтение атрибутов с помощью Reflection API

<?php

#[Attribute]
class MyAttribute
{
public
$value;

public function
__construct($value)
{
$this->value = $value;
}
}

#[MyAttribute(value: 1234)]
class Thing
{
}

function
dumpAttributeData($reflection) {
$attributes = $reflection->getAttributes();

foreach (
$attributes as $attribute) {
var_dump($attribute->getName());
var_dump($attribute->getArguments());
var_dump($attribute->newInstance());
}
}

dumpAttributeData(new ReflectionClass(Thing::class));
/*
string(11) "MyAttribute"
array(1) {
["value"]=>
int(1234)
}
object(MyAttribute)#3 (1) {
["value"]=>
int(1234)
}
*/

Вместо того, чтобы последовательно перебирать все атрибуты объекта рефлексии, можно указать имя класса в качестве аргумента и получить только подходящие атрибуты.

Пример #2 Чтение конкретных атрибутов с помощью Reflection API

<?php

function dumpMyAttributeData($reflection) {
$attributes = $reflection->getAttributes(MyAttribute::class);

foreach (
$attributes as $attribute) {
var_dump($attribute->getName());
var_dump($attribute->getArguments());
var_dump($attribute->newInstance());
}
}

dumpMyAttributeData(new ReflectionClass(Thing::class));


Объявление классов атрибутов

Создавать классы для атрибутов не обязательно, но крайне рекомендуется. В самом простом случае требуется просто пустой класс с атрибутом #[Attribute], который можно импортировать из глобального пространства имён с помощью оператора use.

Пример #1 Простой класс с атрибутом

<?php

namespace Example;

use
Attribute;

#[Attribute]
class MyAttribute
{
}

Для ограничения того, с каким типом деклараций можно использовать конкретный атрибут, можно передать битовую маску первым параметром в #[Attribute].

Пример #2 Ограничение допустимых сущностей для использования атрибута

<?php

namespace Example;

use
Attribute;

#[Attribute(Attribute::TARGET_METHOD | Attribute::TARGET_FUNCTION)]
class MyAttribute
{
}

После этого аннотирование атрибутом MyAttribute чего-либо, отличающегося от метода или функции, приведёт к выбрасыванию исключения при вызове ReflectionAttribute::newInstance().

Можно указать следующие сущности:

  • Attribute::TARGET_CLASS
  • Attribute::TARGET_FUNCTION
  • Attribute::TARGET_METHOD
  • Attribute::TARGET_PROPERTY
  • Attribute::TARGET_CLASS_CONSTANT
  • Attribute::TARGET_PARAMETER
  • Attribute::TARGET_ALL

По умолчанию атрибут можно использовать только один раз для каждой сущности. Если нужна возможность указывать несколько одинаковых атрибутов для одной сущности - можно выставить соответствующий флаг в битовой маске для декларации #[Attribute].

Пример #3 Использование IS_REPEATABLE для разрешения использовать атрибут в объявлении несколько раз

<?php

namespace Example;

use
Attribute;

#[Attribute(Attribute::TARGET_METHOD | Attribute::TARGET_FUNCTION | Attribute::IS_REPEATABLE)]
class MyAttribute
{
}



Объяснение ссылок

Содержание


Что такое ссылки

Ссылки в PHP - это средство доступа к содержимому одной переменной под разными именами. Они не похожи на указатели C; например, вы не можете выполнять над ними адресную арифметику, они не являются реальными адресами в памяти и т.д. Для получения дополнительной информации смотрите Чем ссылки не являются. Вместо этого указатели в PHP - это псевдонимы в таблице имён переменных. В PHP имя переменной и её содержимое - это разные вещи, поэтому одно содержимое может иметь разные имена. Можно провести аналогию с именами файлов и файлами в Unix: имена переменных - записи в каталоге, а содержимое переменной - это сам файл. Ссылки в PHP - аналог жёстких ссылок в файловых системах Unix.



Что делают ссылки

Есть три основных операции с использованием ссылок: присвоение по ссылке, передача по ссылке и возврат по ссылке. Данный раздел познакомит вас с этими операциями и предоставит ссылки для дальнейшего изучения.

Присвоение по ссылке

Первая из них - ссылки PHP позволяют создать две переменные указывающие на одно и то же значение. Таким образом, когда выполняется следующее:

<?php
$a
=& $b;
?>
то $a указывает на то же значение что и $b.

Замечание:

$a и $b здесь абсолютно эквивалентны, но это не означает, что $a указывает на $b или наоборот. Это означает, что $a и $b указывают на одно и то же значение.

Замечание:

При присвоении, передаче или возврате неинициализированной переменной по ссылке, происходит её создание.

Пример #1 Использование ссылок с неинициализированными переменными

<?php
function foo(&$var) { }

foo($a); // $a создана и равна null

$b = array();
foo($b['b']);
var_dump(array_key_exists('b', $b)); // bool(true)

$c = new stdClass;
foo($c->d);
var_dump(property_exists($c, 'd')); // bool(true)
?>

Такой же синтаксис может использоваться в функциях, возвращающими ссылки, и с оператором new:

<?php
$foo
=& find_var($bar);
?>

Использование того же синтаксиса с функцией, которая не возвращает по ссылке, приведёт к ошибке, так же как и её использование с результатом оператора new. Хотя объекты передаются как указатели, это не то же самое, что ссылки, как описано в разделе Объекты и ссылки.

Внимание

Если переменной, объявленной внутри функции как global, будет присвоена ссылка, она будет видна только в функции. Чтобы избежать этого, используйте массив $GLOBALS.

Пример #2 Присвоение ссылок глобальным переменным внутри функции

<?php
$var1
= "Пример переменной";
$var2 = "";

function
global_references($use_globals)
{
global
$var1, $var2;
if (!
$use_globals) {
$var2 =& $var1; // только локально
} else {
$GLOBALS["var2"] =& $var1; // глобально
}
}

global_references(false);
echo
"значение var2: '$var2'\n"; // значение var2: ''
global_references(true);
echo
"значение var2: '$var2'\n"; // значение var2: 'Пример переменной'
?>
Думайте о global $var; как о сокращении от $var =& $GLOBALS['var'];. Таким образом, присвоение $var другой ссылки влияет лишь на локальную переменную.

Замечание:

При использовании переменной-ссылки в foreach, изменяется содержание, на которое она ссылается.

Пример #3 Ссылки и foreach

<?php
$ref
= 0;
$row =& $ref;
foreach (array(
1, 2, 3) as $row) {
// сделать что-нибудь
}
echo
$ref; // 3 - последнее значение, используемое в цикле
?>

Хотя в выражениях, создаваемых с помощью конструкции array(), нет явного присвоения по ссылке, тем не менее они могут вести себя как таковые, если указать префикс & для элементов массива. Пример:

<?php
$a
= 1;
$b = array(2, 3);
$arr = array(&$a, &$b[0], &$b[1]);
$arr[0]++; $arr[1]++; $arr[2]++;
/* $a == 2, $b == array(3, 4); */
?>

Однако следует отметить, что ссылки в массивах являются потенциально опасными. При обычном (не по ссылке) присвоении массива, ссылки внутри этого массива сохраняются. Это также относится и к вызовам функций, когда массив передаётся по значению. Пример:

<?php
/* Присвоение скалярных переменных */
$a = 1;
$b =& $a;
$c = $b;
$c = 7; //$c не ссылка и не изменяет значений $a и $b

/* Присвоение массивов */
$arr = array(1);
$a =& $arr[0]; // $a и $arr[0] ссылаются на одно значение
$arr2 = $arr; // присвоение не по ссылке!
$arr2[0]++;
/* $a == 2, $arr == array(2) */
/* Содержимое $arr изменилось, хотя было присвоено не по ссылке! */
?>
Иными словами, поведение отдельных элементов массива не зависит от типа присвоения этого массива.

Передача по ссылке

Второе, что делают ссылки - передача параметров по ссылке. При этом локальная переменная в функции и переменная в вызывающей области видимости ссылаются на одно и то же содержимое. Пример:

<?php
function foo(&$var) {
$var++;
}

$a = 5;
foo($a);
?>
Этот код присвоит $a значение 6. Это происходит, потому что в функции foo переменная $var ссылается на то же содержимое, что и переменная $a. Смотрите также детальное объяснение передачи по ссылке.

Возврат по ссылке

Третье, что могут делать ссылки - это возврат по ссылке.



Чем ссылки не являются

Как уже было сказано, ссылки не являются указателями. Это означает, что следующая конструкция не будет делать то, что вы ожидаете:

<?php
function foo(&$var) {
$var =& $GLOBALS["baz"];
}
foo($bar);
?>

Переменная $var в функции foo будет связана с $bar в вызывающем коде, но затем она будет перепривязана к $GLOBALS["baz"]. Нет способа связать $bar в области видимости вызывающем коде с чем-либо ещё путём использования механизма ссылок, поскольку $bar не доступна в функции foo (доступно лишь её значение через $var, но $var имеет только значение переменной и не имеет связи имя-значение в таблице имён переменных). Вы можете воспользоваться возвратом ссылок из функции для привязки внешней переменной к другому значению.



Передача по ссылке

Вы можете передать переменную по ссылке в качестве аргумента в функцию, чтобы эта функция могла изменять значение переменной. Синтаксис выглядит следующим образом:

<?php
function foo(&$var) {
$var++;
}

$a = 5;
foo($a);
// $a здесь равно 6
?>

Замечание: В вызове функции отсутствует знак ссылки - он есть только в определении функции. Этого достаточно для корректной передачи аргументов по ссылке.

По ссылке можно передавать:

  • Переменные, например foo($a)
  • Ссылки, возвращаемые функцией, например:

    <?php
    function foo(&$var) {
    $var++;
    }
    function &
    bar() {
    $a = 5;
    return
    $a;
    }
    foo(bar());
    ?>
    Смотрите также объяснение возврата по ссылке.

Любое другое выражение не должно передаваться по ссылке, так как результат не определён. Например, следующая передача по ссылке является неправильной:

<?php
function foo(&$var) {
$var++;
}
function
bar() { // Операция & отсутствует
$a = 5;
return
$a;
}
foo(bar()); // Вызывает предупреждение

foo($a = 5); // Выражение, а не переменная
foo(5); // Константа, а не переменная

class Foobar
{
}

foo(new Foobar()) // Вызывает уведомление с PHP 7.0.7
// Notice: Only variables should be passed by reference
?>



Возврат по ссылке

Возврат по ссылке используется в тех случаях, когда вы хотите использовать функцию для выбора переменной, с которой должна быть связана данная ссылка. Не используйте возврат по ссылке для увеличения производительности. Ядро PHP само занимается оптимизацией. Применяйте возврат по ссылке только имея технические причины на это. Для возврата по ссылке используйте такой синтаксис:

<?php
class foo {
public
$value = 42;

public function &
getValue() {
return
$this->value;
}
}

$obj = new foo;
$myValue = &$obj->getValue(); // $myValue указывает на $obj->value, равное 42.
$obj->value = 2;
echo
$myValue; // отобразит новое значение $obj->value, то есть 2.
?>
В этом примере устанавливается свойство объекта, возвращённого функцией getValue, а не его копии, как было бы без использования ссылок.

Замечание: В отличие от передачи параметров по ссылке, & здесь нужно использовать в обоих местах - для указания на то, что вы возвращаете ссылку, а не копию, как обычно, и для указания того, что происходит связывание по ссылке, а не обычное присвоение для $myValue.

Замечание: Если вы возвращаете ссылку из функции, используя следующий синтаксис: return ($this->value);, это не будет работать, так как вы возвращаете по ссылке результат выражения, а не переменную. По ссылке можно возвращать только переменные и ничего больше.

Для использования возвращаемой ссылки вы должны применять присвоение по ссылке:

<?php
function &collector() {
static
$collection = array();
return
$collection;
}
$collection = &collector();
$collection[] = 'foo';
?>
Для передачи возвращаемой ссылки в другую функцию, принимающую ссылку, вы можете использовать следующий синтаксис:
<?php
function &collector() {
static
$collection = array();
return
$collection;
}
array_push(collector(), 'foo');
?>

Замечание: Заметим, что array_push(&collector(), 'foo'); не сработает, а приведёт к неисправимой ошибке.



Сброс переменных-ссылок

При сбросе ссылки, просто разрывается связь имени и содержимого переменной. Это не означает, что содержимое переменной будет уничтожено. Например:

<?php
$a
= 1;
$b =& $a;
unset(
$a);
?>
Этот код не сбросит $b, а только $a.

Опять же, можно провести аналогию с вызовом unlink (в Unix).



Неявное использование механизма ссылок

Многие синтаксические конструкции PHP реализованы через механизм ссылок, поэтому всё сказанное выше о ссылочном связывании применимо также и к этим конструкциям. Некоторые конструкции, вроде передающих и возвращающих по ссылке, рассмотрены ранее. Другие конструкции, использующие ссылки:

Ссылки global

Если вы объявляете переменную как global $var, вы фактически создаёте ссылку на глобальную переменную. Это означает то же самое, что и:

<?php
$var
=& $GLOBALS["var"];
?>

Это значит, например, что сброс (unset) $var не приведёт к сбросу глобальной переменной.




Предопределённые переменные

PHP предоставляет всем скриптам большое количество предопределённых переменных. Эти переменные содержат всё, от внешних данных до переменных среды окружения, от текста сообщений об ошибках до последних полученных заголовков.


Суперглобальные переменные

Суперглобальные переменныеВстроенные переменные, которые всегда доступны во всех областях

Описание

Некоторые предопределённые переменные в PHP являются "суперглобальными", что означает, что они доступны в любом месте скрипта. Нет необходимости использовать синтаксис global $variable; для доступа к ним в функциях и методах.

Суперглобальными переменными являются:

Примечания

Замечание: Доступность переменных

По умолчанию все суперглобальные переменные доступны всегда, однако существуют настройки, которые могут на это влиять. За дальнейшей информацией обращайтесь к описанию директивы variables_order.

Замечание: Переменные переменных

Суперглобальные переменные не могут быть использованы в качестве переменных переменных внутри функций и методов.



$GLOBALS

(PHP 4, PHP 5, PHP 7, PHP 8)

$GLOBALSСсылки на все переменные глобальной области видимости

Описание

Ассоциативный массив (array), содержащий ссылки на все переменные, определённые в данный момент в глобальной области видимости скрипта. Имена переменных являются ключами массива.

Примеры

Пример #1 Пример использования $GLOBALS

<?php
function test() {
$foo = "локальная переменная";

echo
'$foo в глобальной области видимости: ' . $GLOBALS["foo"] . "\n";
echo
'$foo в текущей области видимости: ' . $foo . "\n";
}

$foo = "Пример содержимого";
test();
?>

Результатом выполнения данного примера будет что-то подобное:

$foo в глобальной области видимости: Пример содержимого
$foo в текущей области видимости: локальная переменная

Внимание

Начиная с PHP 8.1.0, доступ на запись ко всему массиву $GLOBALS больше не поддерживается:

Пример #2 запись всего $GLOBALS приведёт к ошибке

<?php
// Генерирует ошибку во время компиляции:
$GLOBALS = [];
$GLOBALS += [];
$GLOBALS =& $x;
$x =& $GLOBALS;
unset(
$GLOBALS);
array_pop($GLOBALS);
// ...и любые другие операции записи/чтения-записи в $GLOBALS
?>

Примечания

Замечание:

Это 'суперглобальная' или автоматическая глобальная переменная. Это просто означает, что она доступна во всех контекстах скрипта. Нет необходимости выполнять global $variable; для доступа к ней внутри метода или функции.

Замечание: Доступность переменной

В отличие от всех остальных суперглобальных переменных, $GLOBALS всегда доступна в PHP.

Замечание:

Начиная с PHP 8.1.0, массив $GLOBALS теперь является доступной только для чтения копией глобальной таблицы символов. То есть глобальные переменные не могут быть изменены с помощью его копии. Ранее массив $GLOBALS исключался из обычного поведения массивов PHP по значению и глобальные переменные можно было изменить с помощью его копии.

<?php
// До PHP 8.1.0
$a = 1;
$globals = $GLOBALS; // Как будто бы по значению копии
$globals['a'] = 2;
var_dump($a); // int(2)

// Начиная с PHP 8.1.0
// больше не изменяет значение $a. Предыдущее поведение нарушало семантику по значению
$globals = $GLOBALS;
$globals['a'] = 1;

// Чтобы восстановить предыдущее поведение, повторите его копию и присвойте каждому свойству значение $ GLOBALS.
foreach ($globals as $key => $value) {
$GLOBALS[$key] = $value;
}
?>



$_SERVER

(PHP 4 >= 4.1.0, PHP 5, PHP 7, PHP 8)

$_SERVERИнформация о сервере и среде исполнения

Описание

Переменная $_SERVER - это массив (array), содержащий такую информацию, как заголовки, пути и местоположения скриптов. Записи в этом массиве создаются веб-сервером, поэтому нет гарантии, что каждый веб-сервер будет предоставлять любую из этих переменных; серверы могут опускать некоторые из них или предоставлять другие, не указанные здесь. Однако большинство из этих переменных учтены в спецификации » CGI/1.1 и, скорее всего, будут определены.

Замечание: При запуске PHP в командной строке большинство из этих записей будут недоступны или не будут иметь никакого значения.

В дополнение к перечисленным ниже элементам, PHP будет создавать дополнительные элементы со значениями из заголовков запросов. У элементов будет имя HTTP_, за которым следует имя заголовка, написанное с заглавной буквы и с подчёркиванием вместо дефиса. Например, заголовок Accept-Language будет доступен как $_SERVER['HTTP_ACCEPT_LANGUAGE'].

Индексы

'PHP_SELF'
Имя файла скрипта, который сейчас выполняется, относительно корня документов. Например, $_SERVER['PHP_SELF'] в скрипте по адресу http://example.com/foo/bar.php будет /foo/bar.php. Константа __FILE__ содержит полный путь и имя файла текущего (то есть подключённого) файла. Если PHP запущен в командной строке, эта переменная содержит имя скрипта.
'argv'
Массив аргументов, переданных скрипту. Когда скрипт запущен в командой строке, это даёт C-подобный доступ к параметрам командной строки. Когда вызывается через метод GET, этот массив будет содержать строку запроса.
'argc'
Содержит количество параметров, переданных скрипту (если запуск произведён в командной строке).
'GATEWAY_INTERFACE'
Содержит используемую сервером версию спецификации CGI; к примеру 'CGI/1.1'..
'SERVER_ADDR'
IP-адрес сервера, на котором выполняется текущий скрипт.
'SERVER_NAME'
Имя хоста, на котором выполняется текущий скрипт. Если скрипт выполняется на виртуальном хосте, здесь будет содержатся имя, определённое для этого виртуального хоста.

Замечание: В Apache 2 необходимо установить UseCanonicalName = On и ServerName. В противном случае это значение отразит имя хоста, предоставленное клиентом, которое может быть подделано. Небезопасно полагаться на это значение в контексте, требующем безопасности.

'SERVER_SOFTWARE'
Строка идентификации сервера, указанная в заголовках, когда происходит ответ на запрос.
'SERVER_PROTOCOL'
Имя и версия информационного протокола, через который была запрошена страница; к примеру 'HTTP/1.0';
'REQUEST_METHOD'
Какой метод был использован для запроса страницы; к примеру 'GET', 'HEAD', 'POST', 'PUT'.

Замечание:

PHP-скрипт завершается после отправки заголовков (то есть после того, как осуществляется любой вывод без буферизации вывода), если метод запроса был HEAD.

'REQUEST_TIME'
Временная метка начала запроса.
'REQUEST_TIME_FLOAT'
Временная метка начала запроса с точностью до микросекунд.
'QUERY_STRING'
Строка запроса, если есть, через которую была открыта страница.
'DOCUMENT_ROOT'
Директория корня документов, в которой выполняется текущий скрипт, в точности та, которая указана в конфигурационном файле сервера.
'HTTPS'
Принимает непустое значение, если запрос был произведён через протокол HTTPS.
'REMOTE_ADDR'
IP-адрес, с которого пользователь просматривает текущую страницу.
'REMOTE_HOST'
Удалённый хост, с которого пользователь просматривает текущую страницу. Обратный поиск DNS основан на значении переменной REMOTE_ADDR.

Замечание: Сервер должен быть настроен, чтобы создавать эту переменную. Для примера, в Apache необходимо присутствие директивы HostnameLookups On в файле httpd.conf, чтобы эта переменная создавалась. Смотрите также gethostbyaddr().

'REMOTE_PORT'
Порт на удалённой машине, который используется для связи с сервером.
'REMOTE_USER'
Аутентифицированный пользователь.
'REDIRECT_REMOTE_USER'
Аутентифицированный пользователь, если запрос был перенаправлен изнутри.
'SCRIPT_FILENAME'

Абсолютный путь к исполняемому скрипту.

Замечание:

Если скрипт запускается в командной строке (CLI), используя относительный путь, такой как file.php или ../file.php, переменная $_SERVER['SCRIPT_FILENAME'] будет содержать относительный путь, указанный пользователем.

'SERVER_ADMIN'
Эта переменная получает своё значение (для Apache) из директивы конфигурационного файла сервера. Если скрипт запущен на виртуальном хосте, это будет значение, определённое для данного виртуального хоста.
'SERVER_PORT'
Порт на компьютере сервера, используемый сервером для соединения. Для установок по умолчанию, значение будет '80'; используя SSL, например, это значение будет таким, какое сконфигурировано для соединений безопасного HTTP.

Замечание: Чтобы получить физический (реальный) порт в Apache 2, необходимо установить UseCanonicalName = On и UseCanonicalPhysicalPort = On, иначе это значение может быть подменено и не вернуть реальной значение физического порта. Полагаться на это значение небезопасно в контексте приложений, требующих усиленной безопасности.

'SERVER_SIGNATURE'
Строка, содержащая версию сервера и имя виртуального хоста, которые добавляются к генерируемым сервером страницам, если включено.
'PATH_TRANSLATED'
Путь файловой системы (не document root) к текущему скрипту, после того как сервер выполнил отображение virtual-to-real.

Замечание: Пользователи Apache 2 могут использовать директиву AcceptPathInfo = On в конфигурационном файле httpd.conf для задания переменной PATH_INFO.

'SCRIPT_NAME'
Содержит путь к текущему исполняемому скрипту. Это полезно для страниц, которые должны указывать на самих себя. Константа __FILE__ содержит полный путь и имя текущего (то есть включённого) файла.
'REQUEST_URI'
URI, который был предоставлен для доступа к этой странице. Например, '/index.html'.
'PHP_AUTH_DIGEST'
При выполнении аутентификации HTTP Digest этой переменной присваивается заголовок 'Authorization', отправленный клиентом (который затем следует использовать для проведения соответствующей проверки).
'PHP_AUTH_USER'
При выполнении HTTP-аутентификации этой переменной присваивается имя пользователя, предоставленное пользователем.
'PHP_AUTH_PW'
При выполнении HTTP-аутентификации этой переменной присваивается пароль, предоставленный пользователем.
'AUTH_TYPE'
При выполнении HTTP-аутентификации этой переменной присваивается тип аутентификации, который используется.
'PATH_INFO'
Содержит любой предоставленный пользователем путь, содержащийся после имени скрипта, но до строки запроса, если она есть. Например, если текущий скрипт запрошен по URL http://www.example.com/php/path_info.php/some/stuff?foo=bar, то переменная $_SERVER['PATH_INFO'] будет содержать /some/stuff.
'ORIG_PATH_INFO'
Исходное значение переменной 'PATH_INFO' перед обработкой PHP.

Примеры

Пример #1 Пример использования $_SERVER

<?php
echo $_SERVER['SERVER_NAME'];
?>

Результатом выполнения данного примера будет что-то подобное:

www.example.com

Примечания

Замечание:

Это 'суперглобальная' или автоматическая глобальная переменная. Это просто означает, что она доступна во всех контекстах скрипта. Нет необходимости выполнять global $variable; для доступа к ней внутри метода или функции.

Смотрите также



$_GET

(PHP 4 >= 4.1.0, PHP 5, PHP 7, PHP 8)

$_GETПеременные HTTP GET

Описание

Ассоциативный массив переменных, переданных скрипту через параметры URL (известные также как строка запроса). Обратите внимание, что массив не только заполняется для GET-запросов, а скорее для всех запросов со строкой запроса.

Примеры

Пример #1 Пример использования $_GET

<?php
echo 'Привет, ' . htmlspecialchars($_GET["name"]) . '!';
?>

Подразумевается, что пользователь ввёл в браузере адрес http://example.com/?name=Иван

Результатом выполнения данного примера будет что-то подобное:

Привет, Иван!

Примечания

Замечание:

Это 'суперглобальная' или автоматическая глобальная переменная. Это просто означает, что она доступна во всех контекстах скрипта. Нет необходимости выполнять global $variable; для доступа к ней внутри метода или функции.

Замечание:

Параметры GET обрабатываются urldecode().



$_POST

(PHP 4 >= 4.1.0, PHP 5, PHP 7, PHP 8)

$_POSTПеременные HTTP POST

Описание

Ассоциативный массив данных, переданных скрипту через HTTP методом POST при использовании application/x-www-form-urlencoded или multipart/form-data в заголовке Content-Type запроса HTTP.

Примеры

Пример #1 Пример использования $_POST

<?php
echo 'Привет ' . htmlspecialchars($_POST["name"]) . '!';
?>

Подразумевается, что пользователь отправил через POST name=Иван

Результатом выполнения данного примера будет что-то подобное:

Привет, Иван!

Примечания

Замечание:

Это 'суперглобальная' или автоматическая глобальная переменная. Это просто означает, что она доступна во всех контекстах скрипта. Нет необходимости выполнять global $variable; для доступа к ней внутри метода или функции.



$_FILES

(PHP 4 >= 4.1.0, PHP 5, PHP 7, PHP 8)

$_FILESПеременные файлов, загруженных по HTTP

Описание

Ассоциативный массив (array) элементов, загруженных в текущий скрипт через метод HTTP POST. Структура этого массива описана в разделе Загрузка файлов методом POST.

Примечания

Замечание:

Это 'суперглобальная' или автоматическая глобальная переменная. Это просто означает, что она доступна во всех контекстах скрипта. Нет необходимости выполнять global $variable; для доступа к ней внутри метода или функции.

Смотрите также



$_REQUEST

(PHP 4 >= 4.1.0, PHP 5, PHP 7, PHP 8)

$_REQUESTПеременные HTTP-запроса

Описание

Ассоциативный массив (array), который по умолчанию содержит данные переменных $_GET, $_POST и $_COOKIE.

Примечания

Замечание:

Это 'суперглобальная' или автоматическая глобальная переменная. Это просто означает, что она доступна во всех контекстах скрипта. Нет необходимости выполнять global $variable; для доступа к ней внутри метода или функции.

Замечание:

При работе в командной строке переменные argv и argc не включаются в данный массив - они присутствуют в массиве $_SERVER.

Замечание:

Переменные в массиве $_REQUEST передаются в скрипт посредством методов GET, POST или COOKIE, поэтому им нельзя доверять, т.к. они могли быть изменены удалённым пользователем. Их наличие и порядок добавления данных в соответствующие массивы определяется директивой конфигурации PHP request_order и variables_order.



$_SESSION

(PHP 4 >= 4.1.0, PHP 5, PHP 7, PHP 8)

$_SESSIONПеременные сессии

Описание

Ассоциативный массив, содержащий переменные сессии, которые доступны для текущего скрипта. Смотрите документацию по функциям сессии для получения дополнительной информации.

Примечания

Замечание:

Это 'суперглобальная' или автоматическая глобальная переменная. Это просто означает, что она доступна во всех контекстах скрипта. Нет необходимости выполнять global $variable; для доступа к ней внутри метода или функции.

Смотрите также

  • session_start() - Стартует новую сессию, либо возобновляет существующую



$_ENV

(PHP 4 >= 4.1.0, PHP 5, PHP 7, PHP 8)

$_ENVПеременные окружения

Описание

Ассоциативный массив (array) значений, переданных скрипту через переменные окружения.

Эти значения импортируются в глобальное пространство имён PHP из системных переменных окружения, в котором запущен парсер PHP. Большинство значений передаётся из командной оболочки, под которой запущен PHP, и в разных системах, вероятно, используются разные типы оболочек поэтому окончательный список невозможно представить. Пожалуйста, изучите документацию к вашей командной оболочке для получения списка переменных окружения.

Некоторые переменные окружения включают CGI-переменные, причём их наличие не зависит от того, запущен ли PHP как модуль сервера или как препроцессор CGI.

Примеры

Пример #1 Пример использования $_ENV

<?php
echo 'Моё имя пользователя: ' .$_ENV["USER"] . '!';
?>

Допустим, скрипт запустил "bjori"

Результатом выполнения данного примера будет что-то подобное:

Моё имя пользователя: bjori!

Примечания

Замечание:

Это 'суперглобальная' или автоматическая глобальная переменная. Это просто означает, что она доступна во всех контекстах скрипта. Нет необходимости выполнять global $variable; для доступа к ней внутри метода или функции.

Смотрите также



$_COOKIE

(PHP 4 >= 4.1.0, PHP 5, PHP 7, PHP 8)

$_COOKIEHTTP Cookies

Описание

Ассоциативный массив (array) значений, переданных скрипту через HTTP Cookies.

Примеры

Пример #1 Пример использования $_COOKIE

<?php
echo 'Привет, ' . htmlspecialchars($_COOKIE["name"]) . '!';
?>

Предположим, что значение куки с именем "name" было установлено ранее.

Результатом выполнения данного примера будет что-то подобное:

Привет, Иван!

Примечания

Замечание:

Это 'суперглобальная' или автоматическая глобальная переменная. Это просто означает, что она доступна во всех контекстах скрипта. Нет необходимости выполнять global $variable; для доступа к ней внутри метода или функции.



$php_errormsg

(PHP 4, PHP 5, PHP 7)

$php_errormsgПредыдущее сообщение об ошибке

Внимание

Данная функциональность объявлена УСТАРЕВШЕЙ, начиная с PHP 7.2.0 и её крайне не рекомендуется использовать.

Используйте функцию error_get_last().

Описание

$php_errormsg является переменной, содержащей текст последней ошибки, сгенерированной PHP. Эта переменная будет доступна только в блоке кода, в котором случилась ошибка, и только если включена конфигурационная опция track_errors (по умолчанию отключена).

Внимание

Если настроен пользовательский обработчик ошибок (set_error_handler()), то $php_errormsg устанавливается только в том случае, если обработчик ошибки возвращает false.

Список изменений

Версия Описание
8.0.0 Директива track_errors, из-за которой становится доступным $php_errormsg, была удалена.
7.2.0 Директива track_errors, из-за которой становится доступным $php_errormsg, была объявлена устаревшей.

Примеры

Пример #1 Пример использования $php_errormsg

<?php
@strpos();
echo
$php_errormsg;
?>

Результатом выполнения данного примера будет что-то подобное:

Wrong parameter count for strpos()

Смотрите также

  • error_get_last() - Получение информации о последней произошедшей ошибке



$http_response_header

(PHP 4 >= 4.0.4, PHP 5, PHP 7, PHP 8)

$http_response_headerЗаголовки ответов HTTP

Описание

Массив (array) $http_response_header похож на функцию get_headers(). При использовании обёртки HTTP, $http_response_header будет заполняться заголовками ответа HTTP. $http_response_header будет создан в локальной области видимости.

Примеры

Пример #1 Пример $http_response_header

<?php
function get_contents() {
file_get_contents("http://example.com");
var_dump($http_response_header);
}
get_contents();
var_dump($http_response_header);
?>

Результатом выполнения данного примера будет что-то подобное:

array(9) {
  [0]=>
  string(15) "HTTP/1.1 200 OK"
  [1]=>
  string(35) "Date: Sat, 12 Apr 2008 17:30:38 GMT"
  [2]=>
  string(29) "Server: Apache/2.2.3 (CentOS)"
  [3]=>
  string(44) "Last-Modified: Tue, 15 Nov 2005 13:24:10 GMT"
  [4]=>
  string(27) "ETag: "280100-1b6-80bfd280""
  [5]=>
  string(20) "Accept-Ranges: bytes"
  [6]=>
  string(19) "Content-Length: 438"
  [7]=>
  string(17) "Connection: close"
  [8]=>
  string(38) "Content-Type: text/html; charset=UTF-8"
}
NULL



$argc

(PHP 4, PHP 5, PHP 7, PHP 8)

$argcКоличество аргументов, переданных скрипту

Описание

Содержит количество аргументов, переданных текущему скрипту при запуске из командной строки.

Замечание: Имя файла скрипта всегда передаётся в качестве первого аргумента, таким образом минимальное значение $argc равно 1.

Замечание: Эта переменная недоступна, если register_argc_argv отключён.

Примеры

Пример #1 Пример использования $argc

<?php
var_dump
($argc);
?>

Запустим пример в командной строке: php script.php arg1 arg2 arg3

Результатом выполнения данного примера будет что-то подобное:

int(4)

Примечания

Замечание:

Также доступно как $_SERVER['argc'].

Смотрите также

  • getopt() - Получает параметры из списка аргументов командной строки
  • $argv



$argv

(PHP 4, PHP 5, PHP 7, PHP 8)

$argvМассив переданных скрипту аргументов

Описание

Содержит массив (array) всех аргументов, переданных скрипту при запуске из командной строки.

Замечание: Первый аргумент $argv[0] всегда содержит имя файла запущенного скрипта.

Замечание: Эта переменная недоступна, если register_argc_argv отключён.

Примеры

Пример #1 Пример использования $argv

<?php
var_dump
($argv);
?>

Запустим пример в командной строке: php script.php arg1 arg2 arg3

Результатом выполнения данного примера будет что-то подобное:

array(4) {
  [0]=>
  string(10) "script.php"
  [1]=>
  string(4) "arg1"
  [2]=>
  string(4) "arg2"
  [3]=>
  string(4) "arg3"
}

Примечания

Замечание:

Также доступно как $_SERVER['argv'].

Смотрите также

  • getopt() - Получает параметры из списка аргументов командной строки
  • $argc


Содержание

  • Суперглобальные переменные — Встроенные переменные, которые всегда доступны во всех областях
  • $GLOBALS — Ссылки на все переменные глобальной области видимости
  • $_SERVER — Информация о сервере и среде исполнения
  • $_GET — Переменные HTTP GET
  • $_POST — Переменные HTTP POST
  • $_FILES — Переменные файлов, загруженных по HTTP
  • $_REQUEST — Переменные HTTP-запроса
  • $_SESSION — Переменные сессии
  • $_ENV — Переменные окружения
  • $_COOKIE — HTTP Cookies
  • $php_errormsg — Предыдущее сообщение об ошибке
  • $http_response_header — Заголовки ответов HTTP
  • $argc — Количество аргументов, переданных скрипту
  • $argv — Массив переданных скрипту аргументов


Предопределённые исключения

Содержание

Смотрите также "Исключения SPL"


Exception

(PHP 5, PHP 7, PHP 8)

Введение

Exception — это базовый класс для всех пользовательских исключений.

Обзор классов

class Exception implements Throwable {
/* Свойства */
protected string $message = "";
private string $string = "";
protected int $code;
protected string $file = "";
protected int $line;
private array $trace = [];
private ?Throwable $previous = null;
/* Методы */
public __construct(string $message = "", int $code = 0, ?Throwable $previous = null)
final public getMessage(): string
final public getPrevious(): ?Throwable
final public getCode(): int
final public getFile(): string
final public getLine(): int
final public getTrace(): array
final public getTraceAsString(): string
public __toString(): string
private __clone(): void
}

Свойства

message

Текст исключения

code

Код исключения

file

Имя файла, в котором было вызвано исключение

line

Номер строки, в которой было вызвано исключение

previous

Ранее выброшенное исключение

string

Строковое представление трассировки стека

trace

Трассировка стека в виде массива


Exception::__construct

(PHP 5, PHP 7, PHP 8)

Exception::__constructСоздать исключение

Описание

public Exception::__construct(string $message = "", int $code = 0, ?Throwable $previous = null)

Создаёт исключение.

Список параметров

message

Текст сообщения.

code

Код исключения.

previous

Предыдущее исключение. Используется при создания цепочки исключений.

Замечание: Вызов конструктора класса Exception из его подкласса, игнорирует аргументы по умолчанию, если свойства $code и $message уже установлены.

Примечания

Замечание:

Параметр message не является бинарно-безопасным.



Exception::getMessage

(PHP 5, PHP 7, PHP 8)

Exception::getMessageПолучает сообщение исключения

Описание

final public Exception::getMessage(): string

Возвращает сообщение исключения.

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Возвращает сообщение исключения в виде строки.

Примеры

Пример #1 Пример использования Exception::getMessage()

<?php
try {
throw new
Exception("Какое-нибудь сообщение об ошибке");
} catch(
Exception $e) {
echo
$e->getMessage();
}
?>

Результатом выполнения данного примера будет что-то подобное:

Какое-нибудь сообщение об ошибке

Смотрите также



Exception::getPrevious

(PHP 5 >= 5.3.0, PHP 7, PHP 8)

Exception::getPreviousВозвращает предыдущий объект, реализующий Throwable

Описание

final public Exception::getPrevious(): ?Throwable

Возвращает предыдущий объект, реализующий Throwable (переданный третьим параметром в Exception::__construct()).

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Возвращает предыдущий объект, реализующий Throwable или null, если такового нет.

Примеры

Пример #1 Пример использования Exception::getPrevious()

Проход и печать цепи исключений.

<?php
class MyCustomException extends Exception {}

function
doStuff() {
try {
throw new
InvalidArgumentException("Ты делаешь это неправильно!", 112);
} catch(
Exception $e) {
throw new
MyCustomException("Что-то случилось", 911, $e);
}
}


try {
doStuff();
} catch(
Exception $e) {
do {
printf("%s:%d %s (%d) [%s]\n", $e->getFile(), $e->getLine(), $e->getMessage(), $e->getCode(), get_class($e));
} while(
$e = $e->getPrevious());
}
?>

Результатом выполнения данного примера будет что-то подобное:

/home/bjori/ex.php:8 Что-то случилось (911) [MyCustomException]
/home/bjori/ex.php:6 Ты делаешь это неправильно! (112) [InvalidArgumentException]

Смотрите также



Exception::getCode

(PHP 5, PHP 7, PHP 8)

Exception::getCodeПолучает код исключения

Описание

final public Exception::getCode(): int

Возвращает код исключения.

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Возвращает код исключения типа int у класса Exception, но у потомков класса Exception может быть другой тип (например, типа string в PDOException).

Примеры

Пример #1 Пример использования Exception::getCode()

<?php
try {
throw new
Exception("Какое-нибудь сообщение об ошибке", 30);
} catch(
Exception $e) {
echo
"Код исключения: " . $e->getCode();
}
?>

Результатом выполнения данного примера будет что-то подобное:

Код исключения: 30

Смотрите также



Exception::getFile

(PHP 5, PHP 7, PHP 8)

Exception::getFileПолучает файл, в котором возникло исключение

Описание

final public Exception::getFile(): string

Получить имя файла, где исключение было создано.

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Возвращает имя файла, в котором исключение было создано.

Примеры

Пример #1 Пример использования Exception::getFile()

<?php
try {
throw new
Exception;
} catch(
Exception $e) {
echo
$e->getFile();
}
?>

Результатом выполнения данного примера будет что-то подобное:

/home/bjori/tmp/ex.php

Смотрите также

  • Throwable::getFile() - Возвращает файл, в котором выброшено исключение



Exception::getLine

(PHP 5, PHP 7, PHP 8)

Exception::getLineПолучает строку, в которой возникло исключение

Описание

final public Exception::getLine(): int

Получить номер строки, где исключение было создано

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Возвращает номер строки, где было создано исключение.

Примеры

Пример #1 Пример использования Exception::getLine()

<?php
try {
throw new
Exception("Какое-нибудь сообщение об ошибке");
} catch(
Exception $e) {
echo
"Исключение было создано на строке: " . $e->getLine();
}
?>

Результатом выполнения данного примера будет что-то подобное:

Исключение было создано на строке: 3

Смотрите также

  • Throwable::getLine() - Получает строку скрипта, в которой данный объект был выброшен



Exception::getTrace

(PHP 5, PHP 7, PHP 8)

Exception::getTraceПолучает трассировку стека

Описание

final public Exception::getTrace(): array

Возвращает трассировку стека исключения.

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Возвращает трассировку стека исключения в виде массива (array).

Примеры

Пример #1 Пример использования Exception::getTrace()

<?php
function test() {
throw new
Exception;
}

try {
test();
} catch(
Exception $e) {
var_dump($e->getTrace());
}
?>

Результатом выполнения данного примера будет что-то подобное:

array(1) {
  [0]=>
  array(4) {
    ["file"]=>
    string(22) "/home/bjori/tmp/ex.php"
    ["line"]=>
    int(7)
    ["function"]=>
    string(4) "test"
    ["args"]=>
    array(0) {
    }
  }
}

Смотрите также



Exception::getTraceAsString

(PHP 5, PHP 7, PHP 8)

Exception::getTraceAsStringПолучает трассировку стека в виде строки

Описание

final public Exception::getTraceAsString(): string

Возвращает трассировку стека исключения в виде строки.

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Возвращает трассировку стека исключения в виде строки.

Примеры

Пример #1 Пример использования Exception::getTraceAsString()

<?php
function test() {
throw new
Exception;
}

try {
test();
} catch(
Exception $e) {
echo
$e->getTraceAsString();
}
?>

Результатом выполнения данного примера будет что-то подобное:

#0 /home/bjori/tmp/ex.php(7): test()
#1 {main}

Смотрите также



Exception::__toString

(PHP 5, PHP 7, PHP 8)

Exception::__toStringСтроковое представление исключения

Описание

public Exception::__toString(): string

Возвращает исключение в виде строки (string).

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Возвращает исключение в виде строки (string).

Примеры

Пример #1 Пример использования Exception::__toString()

<?php
try {
throw new
Exception("Какое-нибудь сообщение об ошибке");
} catch(
Exception $e) {
echo
$e;
}
?>

Результатом выполнения данного примера будет что-то подобное:

exception 'Exception' with message 'Какое-нибудь сообщение об ошибке' in /home/bjori/tmp/ex.php:3
Stack trace:
#0 {main}

Смотрите также

  • Throwable::__toString() - Получает строковое представление выброшенного объекта



Exception::__clone

(PHP 5, PHP 7, PHP 8)

Exception::__cloneКлонировать исключение

Описание

private Exception::__clone(): void

Исключения Exception не могут быть клонированы, а попытка сделать это выбросит ошибку Error.

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Функция не возвращает значения после выполнения.

Ошибки

Исключения не поддаются клонированию.

Список изменений

Версия Описание
8.1.0 Метод Exception::__clone() больше не является окончательным (final).

Содержание



ErrorException

(PHP 5 >= 5.1.0, PHP 7, PHP 8)

Введение

Исключение в случае возникновения ошибки.

Обзор классов

class ErrorException extends Exception {
/* Свойства */
protected int $severity = E_ERROR;
/* Наследуемые свойства */
protected string $message = "";
private string $string = "";
protected int $code;
protected string $file = "";
protected int $line;
private array $trace = [];
private ?Throwable $previous = null;
/* Методы */
public __construct(
    string $message = "",
    int $code = 0,
    int $severity = E_ERROR,
    ?string $filename = null,
    ?int $line = null,
    ?Throwable $previous = null
)
final public getSeverity(): int
/* Наследуемые методы */
final public Exception::getMessage(): string
final public Exception::getCode(): int
final public Exception::getFile(): string
final public Exception::getLine(): int
final public Exception::getTrace(): array
final public Exception::getTraceAsString(): string
public Exception::__toString(): string
private Exception::__clone(): void
}

Свойства

severity

Серьёзность исключения

Примеры

Пример #1 Использование set_error_handler() для изменения сообщений об ошибках в ErrorException.

<?php
function exception_error_handler($severity, $message, $file, $line) {
if (!(
error_reporting() & $severity)) {
// Этот код ошибки не входит в error_reporting
return;
}
throw new
ErrorException($message, 0, $severity, $file, $line);
}
set_error_handler("exception_error_handler");

/* вызываем исключение */
strpos();
?>

Результатом выполнения данного примера будет что-то подобное:

Fatal error: Uncaught exception 'ErrorException' with message 'strpos() expects at least 2 parameters, 0 given' in /home/bjori/tmp/ex.php:12
Stack trace:
#0 [internal function]: exception_error_handler(2, 'strpos() expect...', '/home/bjori/php...', 12, Array)
#1 /home/bjori/php/cleandocs/test.php(12): strpos()
#2 {main}
  thrown in /home/bjori/tmp/ex.php on line 12


ErrorException::__construct

(PHP 5 >= 5.1.0, PHP 7, PHP 8)

ErrorException::__constructСоздаёт исключение

Описание

public ErrorException::__construct(
    string $message = "",
    int $code = 0,
    int $severity = E_ERROR,
    ?string $filename = null,
    ?int $line = null,
    ?Throwable $previous = null
)

Создаёт исключение.

Список параметров

message

Текст исключения.

code

Код исключения.

severity

Уровень серьёзности исключения.

Замечание:

В то время, как уровень серьёзности может быть любым целым числом (int), предполагается, что для её указания будут использованы константы ошибок.

filename

Имя файла, где вызвано исключение.

line

Номер строки, где вызвано исключение.

previous

Предыдущее исключение. Используется для создания цепочки исключений.

Список изменений

Версия Описание
8.0.0 filename и line теперь допускают значение null. Ранее их значениями по умолчанию были __FILE__ и __LINE__, соответственно.


ErrorException::getSeverity

(PHP 5 >= 5.1.0, PHP 7, PHP 8)

ErrorException::getSeverityПолучает серьёзность исключения

Описание

final public ErrorException::getSeverity(): int

Возвращает серьёзность исключения.

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Возвращает уровень серьёзности исключения.

Примеры

Пример #1 Пример использования ErrorException::getSeverity()

<?php
try {
throw new
ErrorException("Сообщение об исключении", 0, E_USER_ERROR);
} catch(
ErrorException $e) {
echo
"Серьёзность этого исключения равна: " . $e->getSeverity();
var_dump($e->getSeverity() === E_USER_ERROR);
}
?>

Результатом выполнения данного примера будет что-то подобное:

Серьёзность этого исключения равна: 256
bool(true)


Содержание



Error

(PHP 7, PHP 8)

Введение

Error - базовый класс для всех внутренних ошибок PHP.

Обзор классов

class Error implements Throwable {
/* Свойства */
protected string $message = "";
private string $string = "";
protected int $code;
protected string $file = "";
protected int $line;
private array $trace = [];
private ?Throwable $previous = null;
/* Методы */
public __construct(string $message = "", int $code = 0, ?Throwable $previous = null)
final public getMessage(): string
final public getPrevious(): ?Throwable
final public getCode(): int
final public getFile(): string
final public getLine(): int
final public getTrace(): array
final public getTraceAsString(): string
public __toString(): string
private __clone(): void
}

Свойства

message

Сообщение об ошибке

code

Код ошибки

file

Имя файла, в котором произошла ошибка

line

Номер строки, в которой произошла ошибка

previous

Ранее выброшенное исключение

string

Строковое представление трассировки стека

trace

Трассировка стека в виде массива


Error::__construct

(PHP 7, PHP 8)

Error::__constructСоздаёт объект класса Error

Описание

public Error::__construct(string $message = "", int $code = 0, ?Throwable $previous = null)

Создаёт объект класса Error.

Список параметров

message

Сообщение об ошибке.

code

Код ошибки.

previous

Предыдущий объект, реализующий интерфейс throwable, используется для создания цепочки исключений.

Примечания

Замечание:

Значение message НЕ является безопасным для бинарных данных, то есть в тексте сообщения нельзя использовать символ с кодом \0.



Error::getMessage

(PHP 7, PHP 8)

Error::getMessageПолучает сообщение об ошибке

Описание

final public Error::getMessage(): string

Возвращает сообщение об ошибке.

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Возвращает сообщение об ошибке в виде строки.

Примеры

Пример #1 Пример использования Error::getMessage()

<?php
try {
throw new
Error("Страшная ошибка");
} catch(
Error $e) {
echo
$e->getMessage();
}
?>

Результатом выполнения данного примера будет что-то подобное:

Страшная ошибка

Смотрите также



Error::getPrevious

(PHP 7, PHP 8)

Error::getPreviousВозвращает предыдущий Throwable

Описание

final public Error::getPrevious(): ?Throwable

Возвращает предыдущий объект Throwable (третий параметр конструктора Error::__construct()).

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Возвращает предыдущий объект Throwable, если он есть, и null, если его нет.

Примеры

Пример #1 Пример использования Error::getPrevious()

Проход и печать цепи исключений.

<?php
class MyCustomError extends Error {}

function
doStuff() {
try {
throw new
InvalidArgumentError("Вы делаете это неправильно!", 112);
} catch(
Error $e) {
throw new
MyCustomError("Что-то случилось", 911, $e);
}
}


try {
doStuff();
} catch(
Error $e) {
do {
printf("%s:%d %s (%d) [%s]\n", $e->getFile(), $e->getLine(), $e->getMessage(), $e->getCode(), get_class($e));
} while(
$e = $e->getPrevious());
}
?>

Результатом выполнения данного примера будет что-то подобное:

/home/bjori/ex.php:8 Что-то случилось (911) [MyCustomError]
/home/bjori/ex.php:6 Вы делаете это неправильно! (112) [InvalidArgumentError]

Смотрите также



Error::getCode

(PHP 7, PHP 8)

Error::getCodeВозвращает код ошибки

Описание

final public Error::getCode(): int

Возвращает код ошибки.

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Возвращает код ошибки типа int

Примеры

Пример #1 Пример использованияError::getCode()

<?php
try {
throw new
Error("Какое-то сообщение об ошибке", 30);
} catch(
Error $e) {
echo
"Код ошибки: " . $e->getCode();
}
?>

Результатом выполнения данного примера будет что-то подобное:

Код ошибки: 30

Смотрите также



Error::getFile

(PHP 7, PHP 8)

Error::getFileПолучает файл, в котором произошла ошибка

Описание

final public Error::getFile(): string

Получить имя файла, в котором произошла ошибка.

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Возвращает имя файла, в котором произошла ошибка.

Примеры

Пример #1 Пример использования Error::getFile()

<?php
try {
throw new
Error;
} catch(
Error $e) {
echo
$e->getFile();
}
?>

Результатом выполнения данного примера будет что-то подобное:

/home/bjori/tmp/ex.php

Смотрите также

  • Throwable::getFile() - Возвращает файл, в котором выброшено исключение



Error::getLine

(PHP 7, PHP 8)

Error::getLineПолучает номер строки, в которой произошла ошибка

Описание

final public Error::getLine(): int

Получить номер строки, в которой произошла ошибка.

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Возвращает номер строки, в которой произошла ошибка.

Примеры

Пример #1 Пример использованияError::getLine()

<?php
try {
throw new
Error("Какое-то сообщение об ошибке");
} catch(
Error $e) {
echo
"Ошибка создана в строке: " . $e->getLine();
}
?>

Результатом выполнения данного примера будет что-то подобное:

Ошибка создана в строке: 3

Смотрите также

  • Throwable::getLine() - Получает строку скрипта, в которой данный объект был выброшен



Error::getTrace

(PHP 7, PHP 8)

Error::getTraceПолучает трассировку стека

Описание

final public Error::getTrace(): array

Возвращает трассировку стека.

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Возвращает трассировку стека в виде массива (array).

Примеры

Пример #1 Пример использования Error::getTrace()

<?php
function test() {
throw new
Error;
}

try {
test();
} catch(
Error $e) {
var_dump($e->getTrace());
}
?>

Результатом выполнения данного примера будет что-то подобное:

array(1) {
  [0]=>
  array(4) {
    ["file"]=>
    string(22) "/home/bjori/tmp/ex.php"
    ["line"]=>
    int(7)
    ["function"]=>
    string(4) "test"
    ["args"]=>
    array(0) {
    }
  }
}

Смотрите также



Error::getTraceAsString

(PHP 7, PHP 8)

Error::getTraceAsStringПолучает трассировку стека в виде строки

Описание

final public Error::getTraceAsString(): string

Возвращает трассировку стека в виде строки.

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Возвращает трассировку стека в виде строки.

Примеры

Пример #1 Пример использования Error::getTraceAsString()

<?php
function test() {
throw new
Error;
}

try {
test();
} catch(
Error $e) {
echo
$e->getTraceAsString();
}
?>

Результатом выполнения данного примера будет что-то подобное:

#0 /home/bjori/tmp/ex.php(7): test()
#1 {main}

Смотрите также



Error::__toString

(PHP 7, PHP 8)

Error::__toStringСтроковое представление ошибки

Описание

public Error::__toString(): string

Возвращает строковое (string) представление ошибки.

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Возвращает строковое (string) представление ошибки.

Примеры

Пример #1 Пример использования Error::__toString()

<?php
try {
throw new
Error("Сообщение об ошибке");
} catch(
Error $e) {
echo
$e;
}
?>

Результатом выполнения данного примера будет что-то подобное:

Error: Сообщение об ошибке in /home/bjori/tmp/ex.php:3
Stack trace:
#0 {main}

Смотрите также

  • Throwable::__toString() - Получает строковое представление выброшенного объекта



Error::__clone

(PHP 7, PHP 8)

Error::__cloneКлонирует ошибку

Описание

private Error::__clone(): void

Объект класса Error нельзя клонировать, так что эта функция вызовет фатальную ошибку.

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Функция не возвращает значения после выполнения.

Ошибки

Объект класса Error нельзя клонировать.

Список изменений

Версия Описание
8.1.0 Метод Error::__clone() больше не является окончательным (final).

Содержание



ArgumentCountError

(PHP 7 >= PHP 7.1.0, PHP 8)

Введение

ArgumentCountError выбрасывается, когда в пользовательский метод или функцию передано недостаточное количество аргументов.

Эта ошибка также выбрасывается, если в невариативную встроенную функцию передаётся слишком много аргументов.

Обзор классов

class ArgumentCountError extends TypeError {
/* Наследуемые свойства */
protected string $message = "";
private string $string = "";
protected int $code;
protected string $file = "";
protected int $line;
private array $trace = [];
private ?Throwable $previous = null;
/* Наследуемые методы */
public Error::__construct(string $message = "", int $code = 0, ?Throwable $previous = null)
final public Error::getMessage(): string
final public Error::getPrevious(): ?Throwable
final public Error::getCode(): int
final public Error::getFile(): string
final public Error::getLine(): int
final public Error::getTrace(): array
final public Error::getTraceAsString(): string
public Error::__toString(): string
private Error::__clone(): void
}


ArithmeticError

(PHP 7, PHP 8)

Введение

ArithmeticError выбрасывается, когда возникает ошибка при выполнении математических операций. Такие ошибки возможно спровоцировать побитовым смещением на отрицательное значение или вызовом функции intdiv(), приводящей значение, не входящее в допустимый интервал целых чисел (int).

Обзор классов

class ArithmeticError extends Error {
/* Наследуемые свойства */
protected string $message = "";
private string $string = "";
protected int $code;
protected string $file = "";
protected int $line;
private array $trace = [];
private ?Throwable $previous = null;
/* Наследуемые методы */
public Error::__construct(string $message = "", int $code = 0, ?Throwable $previous = null)
final public Error::getMessage(): string
final public Error::getPrevious(): ?Throwable
final public Error::getCode(): int
final public Error::getFile(): string
final public Error::getLine(): int
final public Error::getTrace(): array
final public Error::getTraceAsString(): string
public Error::__toString(): string
private Error::__clone(): void
}


AssertionError

(PHP 7, PHP 8)

Введение

AssertionError выбрасывается, когда утверждение, сделанное с помощью assert(), терпит неудачу.

Обзор классов

class AssertionError extends Error {
/* Наследуемые свойства */
protected string $message = "";
private string $string = "";
protected int $code;
protected string $file = "";
protected int $line;
private array $trace = [];
private ?Throwable $previous = null;
/* Наследуемые методы */
public Error::__construct(string $message = "", int $code = 0, ?Throwable $previous = null)
final public Error::getMessage(): string
final public Error::getPrevious(): ?Throwable
final public Error::getCode(): int
final public Error::getFile(): string
final public Error::getLine(): int
final public Error::getTrace(): array
final public Error::getTraceAsString(): string
public Error::__toString(): string
private Error::__clone(): void
}


DivisionByZeroError

(PHP 7, PHP 8)

Введение

DivisionByZeroError выбрасывается при попытке поделить число на ноль.

Обзор классов

class DivisionByZeroError extends ArithmeticError {
/* Наследуемые свойства */
protected string $message = "";
private string $string = "";
protected int $code;
protected string $file = "";
protected int $line;
private array $trace = [];
private ?Throwable $previous = null;
/* Наследуемые методы */
public Error::__construct(string $message = "", int $code = 0, ?Throwable $previous = null)
final public Error::getMessage(): string
final public Error::getPrevious(): ?Throwable
final public Error::getCode(): int
final public Error::getFile(): string
final public Error::getLine(): int
final public Error::getTrace(): array
final public Error::getTraceAsString(): string
public Error::__toString(): string
private Error::__clone(): void
}


CompileError

(PHP 7 > 7.3.0, PHP 8)

Введение

Исключение CompileError выбрасывается при некоторых ошибках компиляции, которые ранее выдавали фатальную ошибку.

Обзор классов

class CompileError extends Error {
/* Наследуемые свойства */
protected string $message = "";
private string $string = "";
protected int $code;
protected string $file = "";
protected int $line;
private array $trace = [];
private ?Throwable $previous = null;
/* Наследуемые методы */
public Error::__construct(string $message = "", int $code = 0, ?Throwable $previous = null)
final public Error::getMessage(): string
final public Error::getPrevious(): ?Throwable
final public Error::getCode(): int
final public Error::getFile(): string
final public Error::getLine(): int
final public Error::getTrace(): array
final public Error::getTraceAsString(): string
public Error::__toString(): string
private Error::__clone(): void
}


ParseError

(PHP 7, PHP 8)

Введение

ParseError выбрасывается, когда возникает ошибка при разборе PHP-кода, например, когда вызывается функция eval().

Замечание: Начиная с PHP 7.3.0, класс ParseError наследуется от CompileError. Ранее этот класс расширял класс Error.

Обзор классов

class ParseError extends CompileError {
/* Наследуемые свойства */
protected string $message = "";
private string $string = "";
protected int $code;
protected string $file = "";
protected int $line;
private array $trace = [];
private ?Throwable $previous = null;
/* Наследуемые методы */
public Error::__construct(string $message = "", int $code = 0, ?Throwable $previous = null)
final public Error::getMessage(): string
final public Error::getPrevious(): ?Throwable
final public Error::getCode(): int
final public Error::getFile(): string
final public Error::getLine(): int
final public Error::getTrace(): array
final public Error::getTraceAsString(): string
public Error::__toString(): string
private Error::__clone(): void
}


TypeError

(PHP 7, PHP 8)

Введение

Исключение TypeError может быть выброшено, если:

  • Значение, устанавливаемое для свойства класса, не соответствует соответствующему объявленному типу свойства.
  • Тип аргумента, переданного функции, не соответствует типу, объявленному в функции для этого аргумента.
  • Тип возвращённого функцией значения не соответствует типу возврата, объявленному в функции.

Обзор классов

class TypeError extends Error {
/* Наследуемые свойства */
protected string $message = "";
private string $string = "";
protected int $code;
protected string $file = "";
protected int $line;
private array $trace = [];
private ?Throwable $previous = null;
/* Наследуемые методы */
public Error::__construct(string $message = "", int $code = 0, ?Throwable $previous = null)
final public Error::getMessage(): string
final public Error::getPrevious(): ?Throwable
final public Error::getCode(): int
final public Error::getFile(): string
final public Error::getLine(): int
final public Error::getTrace(): array
final public Error::getTraceAsString(): string
public Error::__toString(): string
private Error::__clone(): void
}

Список изменений

Версия Описание
7.1.0 Исключение TypeError больше не выбрасывается, когда во встроенную PHP-функцию в режиме strict type передаётся недопустимое количество аргументов. Вместо этого выбрасывается ArgumentCountError.


ValueError

(PHP 8)

Введение

Ошибка ValueError выбрасывается, если тип аргумента правильный, но его значение неверно. Например, передача отрицательного целого числа, когда функция ожидает положительное, или передача пустой строки/массива, когда функция ожидает, что он не будет пустым.

Обзор классов

class ValueError extends Error {
/* Наследуемые свойства */
protected string $message = "";
private string $string = "";
protected int $code;
protected string $file = "";
protected int $line;
private array $trace = [];
private ?Throwable $previous = null;
/* Наследуемые методы */
public Error::__construct(string $message = "", int $code = 0, ?Throwable $previous = null)
final public Error::getMessage(): string
final public Error::getPrevious(): ?Throwable
final public Error::getCode(): int
final public Error::getFile(): string
final public Error::getLine(): int
final public Error::getTrace(): array
final public Error::getTraceAsString(): string
public Error::__toString(): string
private Error::__clone(): void
}


UnhandledMatchError

(PHP 8)

Введение

UnhandledMatchError выбрасывается, если субъект, переданный в выражение match, не обрабатывается ни одной из сторон выражения match.

Обзор классов

class UnhandledMatchError extends Error {
/* Наследуемые свойства */
protected string $message = "";
private string $string = "";
protected int $code;
protected string $file = "";
protected int $line;
private array $trace = [];
private ?Throwable $previous = null;
/* Наследуемые методы */
public Error::__construct(string $message = "", int $code = 0, ?Throwable $previous = null)
final public Error::getMessage(): string
final public Error::getPrevious(): ?Throwable
final public Error::getCode(): int
final public Error::getFile(): string
final public Error::getLine(): int
final public Error::getTrace(): array
final public Error::getTraceAsString(): string
public Error::__toString(): string
private Error::__clone(): void
}


FiberError

(PHP 8 >= 8.1.0)

Введение

FiberError выбрасывает, если в объекте Fiber выполняется недопустимая операция.

Обзор классов

final class FiberError extends Error {
/* Наследуемые свойства */
protected string $message = "";
private string $string = "";
protected int $code;
protected string $file = "";
protected int $line;
private array $trace = [];
private ?Throwable $previous = null;
/* Методы */
/* Наследуемые методы */
final public Error::getMessage(): string
final public Error::getPrevious(): ?Throwable
final public Error::getCode(): int
final public Error::getFile(): string
final public Error::getLine(): int
final public Error::getTrace(): array
final public Error::getTraceAsString(): string
public Error::__toString(): string
private Error::__clone(): void
}



Встроенные интерфейсы и классы

Содержание


Интерфейс Traversable

(PHP 5, PHP 7, PHP 8)

Введение

Интерфейс, определяющий, является ли класс обходимым (traversable) с использованием foreach.

Абстрактный базовый интерфейс, который не может быть реализован сам по себе. Вместо этого должен реализовываться IteratorAggregate или Iterator.

Обзор интерфейсов

interface Traversable {
}

Этот интерфейс не имеет методов, его единственная цель - быть базовым интерфейсом для всех обходимых классов.

Список изменений

Версия Описание
7.4.0 Интерфейс Traversable теперь может быть реализован абстрактными классами. Расширяемые классы должны реализовывать интерфейс Iterator или IteratorAggregate.

Примечания

Замечание:

Внутренние (встроенные) классы, реализующие этот интерфейс, могут быть использованы в конструкции foreach и не обязаны реализовывать интерфейс IteratorAggregate или Iterator.

Замечание:

До версии PHP 7.4.0 этот внутренний интерфейс движка не мог быть реализован в PHP-скриптах. Вместо него следует использовать либо интерфейс IteratorAggregate, либо Iterator.



Интерфейс Iterator

(PHP 5, PHP 7, PHP 8)

Введение

Интерфейс для внешних итераторов или объектов, которые могут повторять себя изнутри.

Обзор интерфейсов

interface Iterator extends Traversable {
/* Методы */
public current(): mixed
public key(): mixed
public next(): void
public rewind(): void
public valid(): bool
}

Предопределённые итераторы

PHP уже предоставляет некоторые итераторы для многих ежедневных задач. Смотрите список итераторов SPL для более детальной информации.

Примеры

Пример #1 Основы использования

Этот пример демонстрирует в каком порядке вызываются методы, когда используется с итератором оператор foreach.

<?php
class myIterator implements Iterator {
private
$position = 0;
private
$array = array(
"firstelement",
"secondelement",
"lastelement",
);

public function
__construct() {
$this->position = 0;
}

public function
rewind(): void {
var_dump(__METHOD__);
$this->position = 0;
}

#[\ReturnTypeWillChange]
public function current() {
var_dump(__METHOD__);
return
$this->array[$this->position];
}

#[\ReturnTypeWillChange]
public function key() {
var_dump(__METHOD__);
return
$this->position;
}

public function
next(): void {
var_dump(__METHOD__);
++
$this->position;
}

public function
valid(): bool {
var_dump(__METHOD__);
return isset(
$this->array[$this->position]);
}
}

$it = new myIterator;

foreach(
$it as $key => $value) {
var_dump($key, $value);
echo
"\n";
}
?>

Результатом выполнения данного примера будет что-то подобное:

string(18) "myIterator::rewind"
string(17) "myIterator::valid"
string(19) "myIterator::current"
string(15) "myIterator::key"
int(0)
string(12) "firstelement"

string(16) "myIterator::next"
string(17) "myIterator::valid"
string(19) "myIterator::current"
string(15) "myIterator::key"
int(1)
string(13) "secondelement"

string(16) "myIterator::next"
string(17) "myIterator::valid"
string(19) "myIterator::current"
string(15) "myIterator::key"
int(2)
string(11) "lastelement"

string(16) "myIterator::next"
string(17) "myIterator::valid"

Смотрите также

Смотрите также раздел Итераторы объектов.


Iterator::current

(PHP 5, PHP 7, PHP 8)

Iterator::currentВозврат текущего элемента

Описание

public Iterator::current(): mixed

Возвращает текущий элемент.

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Может возвращать любой тип.



Iterator::key

(PHP 5, PHP 7, PHP 8)

Iterator::keyВозвращает ключ текущего элемента

Описание

public Iterator::key(): mixed

Возвращает ключ текущего элемента.

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Возвращает скалярное значение (scalar) в случае успешного выполнения или null в случае возникновения ошибки.

Ошибки

Создаёт ошибку уровня E_NOTICE в случае возникновения ошибки.



Iterator::next

(PHP 5, PHP 7, PHP 8)

Iterator::nextПереходит к следующему элементу

Описание

public Iterator::next(): void

Передвигает текущую позицию к следующему элементу.

Замечание:

Метод вызывается после каждой итерации foreach.

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Любое возвращаемое значение игнорируется.



Iterator::rewind

(PHP 5, PHP 7, PHP 8)

Iterator::rewindВозвращает итератор на первый элемент

Описание

public Iterator::rewind(): void

Возвращает итератор обратно на первый элемент.

Замечание:

В начале цикла foreach этот метод вызывается первым. Метод не будет вызван после цикла foreach.

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Любое возвращаемое значение игнорируется.



Iterator::valid

(PHP 5, PHP 7, PHP 8)

Iterator::validПроверяет корректность текущей позиции

Описание

public Iterator::valid(): bool

Метод вызывается после функций Iterator::rewind() и Iterator::next() чтобы проверить, допустима ли текущая позиция.

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Возвращаемое значение будет приведено к логическому типу (bool) и затем использовано. Возвращает true в случае успешного выполнения или false в случае возникновения ошибки.


Содержание

  • Iterator::current — Возврат текущего элемента
  • Iterator::key — Возвращает ключ текущего элемента
  • Iterator::next — Переходит к следующему элементу
  • Iterator::rewind — Возвращает итератор на первый элемент
  • Iterator::valid — Проверяет корректность текущей позиции


Интерфейс IteratorAggregate

(PHP 5, PHP 7, PHP 8)

Введение

Интерфейс для создания внешнего итератора.

Обзор интерфейсов

interface IteratorAggregate extends Traversable {
/* Методы */
}

Пример #1 Основы использования

<?php
class myData implements IteratorAggregate {
public
$property1 = "Первое общедоступное свойство";
public
$property2 = "Второе общедоступное свойство";
public
$property3 = "Третье общедоступное свойство";
public
$property4 = "";

public function
__construct() {
$this->property4 = "последнее свойство";
}

public function
getIterator(): Traversable {
return new
ArrayIterator($this);
}
}

$obj = new myData;

foreach(
$obj as $key => $value) {
var_dump($key, $value);
echo
"\n";
}
?>

Результатом выполнения данного примера будет что-то подобное:

string(9) "property1"
string(56) "Первое общедоступное свойство"

string(9) "property2"
string(56) "Второе общедоступное свойство"

string(9) "property3"
string(56) "Третье общедоступное свойство"

string(9) "property4"
string(35) "последнее свойство"


IteratorAggregate::getIterator

(PHP 5, PHP 7, PHP 8)

IteratorAggregate::getIteratorПолучает внешний итератор

Описание

public IteratorAggregate::getIterator(): Traversable

Возвращает внешний итератор.

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Возвращает экземпляр объекта, реализующий Iterator или Traversable

Ошибки

Выбрасывает исключение Exception в случае возникновения ошибки.


Содержание



Класс InternalIterator

(PHP 8)

Введение

Класс для упрощения реализации интерфейса IteratorAggregate для внутренних классов.

Обзор классов

final class InternalIterator implements Iterator {
/* Методы */
private __construct()
public current(): mixed
public key(): mixed
public next(): void
public rewind(): void
public valid(): bool
}

InternalIterator::__construct

(PHP 8)

InternalIterator::__constructЗакрытый конструктор для запрета прямой инициализации

Описание

private InternalIterator::__construct()

Список параметров

У этой функции нет параметров.



InternalIterator::current

(PHP 8)

InternalIterator::currentВозвращает текущий элемент

Описание

public InternalIterator::current(): mixed

Возвращает текущий элемент.

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Возвращает текущий элемент.



InternalIterator::key

(PHP 8)

InternalIterator::keyВозвращает ключ текущего элемента

Описание

public InternalIterator::key(): mixed

Возвращает ключ текущего элемента.

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Возвращает ключ текущего элемента.



InternalIterator::next

(PHP 8)

InternalIterator::nextПереходит к следующему элементу

Описание

public InternalIterator::next(): void

Перемещает текущую позицию к следующему элементу.

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Функция не возвращает значения после выполнения.



InternalIterator::rewind

(PHP 8)

InternalIterator::rewindПерематывает итератор к первому элементу

Описание

public InternalIterator::rewind(): void

Возвращается к первому элементу итератора.

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Функция не возвращает значения после выполнения.



InternalIterator::valid

(PHP 8)

InternalIterator::validПроверяет, действительна ли текущая позиция

Описание

public InternalIterator::valid(): bool

Проверяет, действительна ли текущая позиция.

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Возвращает, действительна ли текущая позиция.


Содержание



Throwable

(PHP 7, PHP 8)

Введение

Throwable является родительским интерфейсом для всех объектов, выбрасывающихся с помощью выражения throw, включая классы Error и Exception.

Замечание:

Классы PHP не могут напрямую реализовать интерфейс Throwable. Вместо этого они могут наследовать подкласс Exception.

Обзор интерфейсов

interface Throwable extends Stringable {
/* Методы */
public getMessage(): string
public getCode(): int
public getFile(): string
public getLine(): int
public getTrace(): array
public getTraceAsString(): string
public __toString(): string
/* Наследуемые методы */
public Stringable::__toString(): string
}

Список изменений

Версия Описание
8.0.0 Класс Throwable теперь реализует интерфейс Stringable.

Throwable::getMessage

(PHP 7, PHP 8)

Throwable::getMessageПолучает сообщение ошибки

Описание

public Throwable::getMessage(): string

Возвращает сообщение ошибки данного выброшенного объекта.

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Возвращает строковое сообщение.

Смотрите также



Throwable::getCode

(PHP 7, PHP 8)

Throwable::getCodeВозвращает код исключения

Описание

public Throwable::getCode(): int

Возвращает код ошибки выброшенного объекта, к которому применена функция.

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Возвращает код исключения в виде целого числа (int) в Exception, но возможен и другой возвращаемый тип в классах, наследующих Exception (например, в виде строки (string), если тип ошибки PDOException).

Смотрите также



Throwable::getFile

(PHP 7, PHP 8)

Throwable::getFileВозвращает файл, в котором выброшено исключение

Описание

public Throwable::getFile(): string

Возвращает имя файла, в котором данный объект был выброшен.

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Возвращает строковое значение имени файла.

Смотрите также

  • Exception::getFile() - Получает файл, в котором возникло исключение



Throwable::getLine

(PHP 7, PHP 8)

Throwable::getLineПолучает строку скрипта, в которой данный объект был выброшен

Описание

public Throwable::getLine(): int

Возвращает номер строки, в которой данный объект был выброшен.

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Возвращает целочисленное значение строки.

Смотрите также

  • Exception::getLine() - Получает строку, в которой возникло исключение



Throwable::getTrace

(PHP 7, PHP 8)

Throwable::getTraceВозвращает трассировку стека

Описание

public Throwable::getTrace(): array

Возвращает трассировку стека в виде массива.

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Возвращает трассировку стека в виде массива в таком же формате, что и debug_backtrace().

Смотрите также



Throwable::getTraceAsString

(PHP 7, PHP 8)

Throwable::getTraceAsStringПолучает результаты трассировки стека в виде строки

Описание

public Throwable::getTraceAsString(): string

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Возвращает результаты трассировки стека в виде строки.

Смотрите также



Throwable::getPrevious

(PHP 7, PHP 8)

Throwable::getPreviousВозвращает предыдущий Throwable

Описание

public Throwable::getPrevious(): ?Throwable

Возвращает любой предыдущий Throwable (для примера, переданное третьим параметром в Exception::__construct()).

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Возвращает предыдущий Throwable, если он доступен, или null в противном случае.

Смотрите также



Throwable::__toString

(PHP 7, PHP 8)

Throwable::__toStringПолучает строковое представление выброшенного объекта

Описание

public Throwable::__toString(): string

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Возвращает строковое (string) представление выброшенного объекта.

Смотрите также


Содержание



Интерфейс ArrayAccess

(PHP 5, PHP 7, PHP 8)

Введение

Интерфейс обеспечивает доступ к объектам в виде массивов.

Обзор интерфейсов

interface ArrayAccess {
/* Методы */
public offsetExists(mixed $offset): bool
public offsetGet(mixed $offset): mixed
public offsetSet(mixed $offset, mixed $value): void
public offsetUnset(mixed $offset): void
}

Пример #1 Основы использования

<?php
class Obj implements ArrayAccess {
public
$container = [
"one" => 1,
"two" => 2,
"three" => 3,
];

public function
offsetSet($offset, $value): void {
if (
is_null($offset)) {
$this->container[] = $value;
} else {
$this->container[$offset] = $value;
}
}

public function
offsetExists($offset): bool {
return isset(
$this->container[$offset]);
}

public function
offsetUnset($offset): void {
unset(
$this->container[$offset]);
}

public function
offsetGet($offset): mixed {
return isset(
$this->container[$offset]) ? $this->container[$offset] : null;
}
}

$obj = new Obj;

var_dump(isset($obj["two"]));
var_dump($obj["two"]);
unset(
$obj["two"]);
var_dump(isset($obj["two"]));
$obj["two"] = "A value";
var_dump($obj["two"]);
$obj[] = 'Append 1';
$obj[] = 'Append 2';
$obj[] = 'Append 3';
print_r($obj);
?>

Результатом выполнения данного примера будет что-то подобное:

bool(true)
int(2)
bool(false)
string(7) "A value"
obj Object
(
    [container:obj:private] => Array
        (
            [one] => 1
            [three] => 3
            [two] => A value
            [0] => Append 1
            [1] => Append 2
            [2] => Append 3
        )

)

ArrayAccess::offsetExists

(PHP 5, PHP 7, PHP 8)

ArrayAccess::offsetExistsОпределяет, существует ли заданное смещение (ключ)

Описание

public ArrayAccess::offsetExists(mixed $offset): bool

Определяет, существует или нет данное смещение (ключ).

Данный метод выполняется при использовании isset() или empty() на объектах, реализующих интерфейс ArrayAccess.

Замечание:

При использовании функции empty(), вызывается метод ArrayAccess::offsetGet() и проверка на пустоту произойдёт, только если метод ArrayAccess::offsetExists() вернёт true.

Список параметров

offset

Смещение (ключ) для проверки.

Возвращаемые значения

Возвращает true в случае успешного выполнения или false в случае возникновения ошибки.

Замечание:

Возвращаемое значение будет приведено к логическому типу (bool), если возвращаемое значение не является логическим.

Примеры

Пример #1 Пример использования ArrayAccess::offsetExists()

<?php
class obj implements ArrayAccess {
public function
offsetSet($offset, $value): void {
var_dump(__METHOD__);
}

public function
offsetExists($var): bool {
var_dump(__METHOD__);
if (
$var == "foobar") {
return
true;
}
return
false;
}

public function
offsetUnset($var): void {
var_dump(__METHOD__);
}

#[\ReturnTypeWillChange]
public function offsetGet($var) {
var_dump(__METHOD__);
return
"value";
}
}

$obj = new obj;

echo
"Выполняется obj::offsetExists()\n";
var_dump(isset($obj["foobar"]));

echo
"\nВыполняется obj::offsetExists() и obj::offsetGet()\n";
var_dump(empty($obj["foobar"]));

echo
"\nВыполняется obj::offsetExists(), но *не* obj:offsetGet(), поскольку нечего возвращать\n";
var_dump(empty($obj["foobaz"]));
?>

Результатом выполнения данного примера будет что-то подобное:

Выполняется obj::offsetExists()
string(17) "obj::offsetExists"
bool(true)

Выполняется obj::offsetExists() и obj::offsetGet()
string(17) "obj::offsetExists"
string(14) "obj::offsetGet"
bool(false)

Выполняется obj::offsetExists(), но *не* obj:offsetGet(), поскольку нечего возвращать
string(17) "obj::offsetExists"
bool(true)



ArrayAccess::offsetGet

(PHP 5, PHP 7, PHP 8)

ArrayAccess::offsetGetВозвращает заданное смещение (ключ)

Описание

public ArrayAccess::offsetGet(mixed $offset): mixed

Возвращает заданное смещение (ключ).

Данный метод выполняется, когда проверяется смещение (ключ) на пустоту с помощью функции empty().

Список параметров

offset

Смещение (ключ) для возврата.

Возвращаемые значения

Может возвращать значение любого типа.

Примечания

Замечание:

Возможна реализация данного метода с возвращением по ссылке. Это делает возможным косвенную модификацию для величин массива перегруженного объекта ArrayAccess.

Явная модификация - это такая модификация, при которой полностью заменяется значение величины массива, как в случае $obj[6] = 7. С другой стороны, при косвенной модификации заменяется только часть величины, или происходит попытка присвоения величины по ссылке другой переменной, как в случае $obj[6][7] = 7 или $var =& $obj[6]. Увеличение с использованием оператора ++ и уменьшение с использованием оператора -- также реализуются с помощью способа, который требует косвенную модификацию.

В то время как, явная модификация запускает вызов метода ArrayAccess::offsetSet(), косвенная модификация запускает вызов метода ArrayAccess::offsetGet(). В таком случае, реализация метода ArrayAccess::offsetGet() должна быть в состоянии возвращать результат по ссылке, в противном случае будет вызвано сообщение об ошибке уровня E_NOTICE.

Смотрите также



ArrayAccess::offsetSet

(PHP 5, PHP 7, PHP 8)

ArrayAccess::offsetSetПрисваивает значение заданному смещению

Описание

public ArrayAccess::offsetSet(mixed $offset, mixed $value): void

Присваивает значение указанному смещению (ключу).

Список параметров

offset

Смещение (ключ), которому будет присваиваться значение.

value

Значение для присвоения.

Возвращаемые значения

Функция не возвращает значения после выполнения.

Примечания

Замечание:

Параметр offset будет установлен в null, если другое значение недоступно, как показано в следующем примере.

<?php
$arrayaccess
[] = "первое значение";
$arrayaccess[] = "второе значение";
print_r($arrayaccess);
?>

Результат выполнения данного примера:

Array
(
    [0] => first value
    [1] => second value
)

Замечание:

Данный метод не вызывается при присвоениях по ссылке и других косвенных изменений величин массива перегруженного объекта ArrayAccess (косвенные в том смысле, что они произведены не прямой заменой величины, а путём изменения часть элемента или свойства элемента массива, или присвоением элемента массива по ссылке другой переменой). Вместо этого, вызывается метод ArrayAccess::offsetGet(). Данная операция будет успешна только в том случае, если метод возвращает по ссылке.



ArrayAccess::offsetUnset

(PHP 5, PHP 7, PHP 8)

ArrayAccess::offsetUnsetУдаляет смещение

Описание

public ArrayAccess::offsetUnset(mixed $offset): void

Удаляет смещение (ключ).

Замечание:

Этот метод не будет вызван при приведении типа к (unset)

Список параметров

offset

Смещение (ключ) для удаления.

Возвращаемые значения

Функция не возвращает значения после выполнения.


Содержание



Интерфейс Serializable

(PHP 5 >= 5.1.0, PHP 7, PHP 8)

Введение

Интерфейс для индивидуальной сериализации.

Классы, реализующие этот интерфейс, больше не поддерживают __sleep() и __wakeup(). Метод serialize вызывается всякий раз, когда необходима сериализация экземпляру класса. Этот метод не вызывает __destruct() и не имеет никаких побочных действий кроме тех, которые запрограммированы внутри него. Когда данные десериализуются, класс известен и соответствующий метод unserialize() вызывается как конструктор вместо вызова __construct(). Если вам необходимо вызвать стандартный конструктор, вы можете это сделать в этом методе.

Внимание

Начиная с PHP 8.1.0, класс, который реализует Serializable без реализации __serialize() и __unserialize() выдаст предупреждение об устаревании.

Обзор интерфейсов

interface Serializable {
/* Методы */
public serialize(): ?string
public unserialize(string $data): void
}

Пример #1 Основы использования

<?php
class obj implements Serializable {
private
$data;
public function
__construct() {
$this->data = "Мои закрытые данные";
}
public function
serialize() {
return
serialize($this->data);
}
public function
unserialize($data) {
$this->data = unserialize($data);
}
public function
getData() {
return
$this->data;
}
}

$obj = new obj;
$ser = serialize($obj);

var_dump($ser);

$newobj = unserialize($ser);

var_dump($newobj->getData());
?>

Результатом выполнения данного примера будет что-то подобное:

string(59) "C:3:"obj":44:{s:36:"Мои закрытые данные";}"
string(36) "Мои закрытые данные"

Serializable::serialize

(PHP 5 >= 5.1.0, PHP 7, PHP 8)

Serializable::serializeПредставляет объект в виде строки

Описание

public Serializable::serialize(): ?string

Возвращает строковое представление объекта.

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Возвращает строковое представление объекта или null.

Ошибки

Выбрасывает исключение Exception при возвращении типов, отличных от строки или null.

Смотрите также



Serializable::unserialize

(PHP 5 >= 5.1.0, PHP 7, PHP 8)

Serializable::unserializeСоздаёт объект

Описание

public Serializable::unserialize(string $data): void

Вызывается во время десериализации объекта.

Замечание:

Метод действует как конструктор объекта. Метод __construct() не вызывается после этого метода.

Список параметров

data

Строковое представление объекта.

Возвращаемые значения

Возвращаемое значение метода игнорируется.

Смотрите также


Содержание



Класс Closure

(PHP 5 >= 5.3.0, PHP 7, PHP 8)

Введение

Класс, используемый для создания анонимных функций.

Анонимные функции выдают объекты этого типа. Класс получил методы, позволяющие контролировать анонимную функцию после её создания.

Кроме методов, описанных здесь, этот класс также имеет метод __invoke. Данный метод необходим только для совместимости с другими классами, в которых реализован магический вызов, так как этот метод не используется при вызове функции.

Обзор классов

final class Closure {
/* Методы */
private __construct()
public static bind(Closure $closure, ?object $newThis, object|string|null $newScope = "static"): ?Closure
public bindTo(?object $newThis, object|string|null $newScope = "static"): ?Closure
public call(object $newThis, mixed ...$args): mixed
public static fromCallable(callable $callback): Closure
}

Closure::__construct

(PHP 5 >= 5.3.0, PHP 7, PHP 8)

Closure::__constructКонструктор, запрещающий создание экземпляра

Описание

private Closure::__construct()

Этот метод существует только, чтобы запретить создание новых объектов класса Closure. Объекты этого класса создаются способом, описанным на странице анонимных функций.

Список параметров

У этой функции нет параметров.

Смотрите также



Closure::bind

(PHP 5 >= 5.4.0, PHP 7, PHP 8)

Closure::bind Дублирует замыкание с указанием конкретного связанного объекта и области видимости класса

Описание

public static Closure::bind(Closure $closure, ?object $newThis, object|string|null $newScope = "static"): ?Closure

Этот метод является статическим вариантом Closure::bindTo(). Смотрите документацию к указанному методу для подробной информации.

Список параметров

closure

Анонимная функция для привязывания к объекту.

newThis

Объект, к которому будет привязана переданная анонимная функция, или null для отсоединения функции от её текущего объекта.

newScope

Область видимости класса, с которой должно быть связано замыкание или 'static' для сохранения текущей области видимости. Если передан объект, то будет использован его класс. Этот параметр определяет видимость protected (защищённых) и private (закрытых) методов привязанного объекта. Запрещено в качестве этого параметра передавать (объектом) внутренний класс.

Возвращаемые значения

Возвращает новый объект Closure или null в случае возникновения ошибки.

Примеры

Пример #1 Пример Closure::bind()

<?php
class A {
private static
$sfoo = 1;
private
$ifoo = 2;
}
$cl1 = static function() {
return
A::$sfoo;
};
$cl2 = function() {
return
$this->ifoo;
};

$bcl1 = Closure::bind($cl1, null, 'A');
$bcl2 = Closure::bind($cl2, new A(), 'A');
echo
$bcl1(), "\n";
echo
$bcl2(), "\n";
?>

Результатом выполнения данного примера будет что-то подобное:

1
2

Смотрите также



Closure::bindTo

(PHP 5 >= 5.4.0, PHP 7, PHP 8)

Closure::bindTo Дублирует замыкание с указанием связанного объекта и области видимости класса

Описание

public Closure::bindTo(?object $newThis, object|string|null $newScope = "static"): ?Closure

Создаёт и возвращает новую анонимную функцию с тем же телом функции и связанными переменными, но с другим связанным объектом или новой областью видимости класса.

"Связанный объект" определяет значение $this, которое будет доступно в теле функции, а "область видимости класса" представляет собой класс, который определяет к каким protected (защищённым) и private (закрытым) элементам этого объекта будет иметь доступ анонимная функция. Если точнее, то это те элементы, как если бы анонимная функция была бы методом класса, переданного в параметре newScope.

Статические замыкания не могут иметь привязанный объект (значение параметра newThis должно быть равно null), но эта функция может всё равно использоваться для изменения его области видимости класса.

Данный метод гарантирует, что у нестатического замыкания с привязанным объектом будет задана область видимости и наоборот. Для выполнения этого условия применяются следующие правила: Для нестатического замыкания с указанной областью видимости и с null вместо объекта, будет создано статическое замыкание. Для нестатического замыкания с незаданной областью видимости, но с указанием объекта, создаётся замыкание с неуказанной областью видимости.

Замечание:

Если вам необходимо только дублировать анонимную функцию, то вы можете вместо данного метода использовать клонирование.

Список параметров

newThis

Объект, к которому будет привязана переданная анонимная функция, или null для отсоединения замыкания от её текущего объекта.

newScope

Область видимости класса, с которой должно быть связано замыкание или 'static' для сохранения текущей области видимости. Если передан объект, то будет использован его класс. Этот параметр определяет видимость protected (защищённых) и private (закрытых) методов привязанного объекта. Запрещается передавать в этот параметр внутренний класс (объект класса).

Возвращаемые значения

Возвращает новый объект Closure или null в случае возникновения ошибки.

Примеры

Пример #1 Пример Closure::bindTo()

<?php

class A {
private
$val;

function
__construct($val) {
$this->val = $val;
}

function
getClosure() {
//возвращает замыкание, связанное с текущими объектом и областью видимости
return function() { return $this->val; };
}
}

$ob1 = new A(1);
$ob2 = new A(2);

$cl = $ob1->getClosure();
echo
$cl(), "\n";
$cl = $cl->bindTo($ob2);
echo
$cl(), "\n";
?>

Результатом выполнения данного примера будет что-то подобное:

1
2

Смотрите также



Closure::call

(PHP 7, PHP 8)

Closure::callСвязывает и запускает замыкание

Описание

public Closure::call(object $newThis, mixed ...$args): mixed

Временно связывает замыкание с newThis и вызывает его с заданными параметрами.

Список параметров

newThis

Объект (object) для привязки к замыканию на время его вызова.

args

Ноль или больше параметров, которые передаются замыканию.

Возвращаемые значения

Возвращает возвращаемое значение замыкания

Примеры

Пример #1 Пример Closure::call()

<?php
class Value {
protected
$value;

public function
__construct($value) {
$this->value = $value;
}

public function
getValue() {
return
$this->value;
}
}

$three = new Value(3);
$four = new Value(4);

$closure = function ($delta) { var_dump($this->getValue() + $delta); };
$closure->call($three, 4);
$closure->call($four, 4);
?>

Результат выполнения данного примера:

int(7)
int(8)


Closure::fromCallable

(PHP 7 >= 7.1.0)

Closure::fromCallableКонвертирует callable в замыкание

Описание

public static Closure::fromCallable(callable $callback): Closure

Создаёт и возвращает новую анонимную функцию из заданного callback, используя текущую область видимости. Этот метод проверяет, что callback является типом callable в текущей области видимости и выбрасывает исключение TypeError, если это не так.

Замечание:

Начиная с PHP 8.1.0, у Callback-функций как объектов первого класса та же семантика, что и у этого метода.

Список параметров

callback

Объект типа callable.

Возвращаемые значения

Возвращает новый объект класса Closure или выбрасывает исключение TypeError, если callback не является объектом типа callable в текущей области видимости.


Содержание

  • Closure::__construct — Конструктор, запрещающий создание экземпляра
  • Closure::bind — Дублирует замыкание с указанием конкретного связанного объекта и области видимости класса
  • Closure::bindTo — Дублирует замыкание с указанием связанного объекта и области видимости класса
  • Closure::call — Связывает и запускает замыкание
  • Closure::fromCallable — Конвертирует callable в замыкание


Класс stdClass

(PHP 4, PHP 5, PHP 7, PHP 8)

Введение

Пустой класс общего назначения с динамическими свойствами.

Объекты класса могут быть инициализированы с помощью оператора new или созданы с помощью преобразования в объект. Некоторые функции PHP также создают экземпляры этого класса, например, функции json_decode(), mysqli_fetch_object() или PDOStatement::fetchObject().

Несмотря на отсутствие реализации магических методов __get()/__set(), класс позволяет использовать динамические свойства и не требует атрибута #[\AllowDynamicProperties].

Это не базовый класс, поскольку в PHP нет понятия универсального базового класса. Однако можно создать пользовательский класс, который расширяет stdClass и в результате наследует функциональность динамических свойств.

Обзор классов

class stdClass {
}

У класса нет методов или свойств по умолчанию.

Примеры

Пример #1 Создание в результате преобразования в объект

<?php
$obj
= (object) array('foo' => 'bar');
var_dump($obj);

Результат выполнения данного примера:

object(stdClass)#1 (1) {
  ["foo"]=>
  string(3) "bar"
}

Пример #2 Создание в результате работы функции json_decode()

<?php
$json
= '{"foo":"bar"}';
var_dump(json_decode($json));

Результат выполнения данного примера:

object(stdClass)#1 (1) {
  ["foo"]=>
  string(3) "bar"
}

Пример #3 Объявление динамических свойств

<?php
$obj
= new stdClass();
$obj->foo = 42;
$obj->{1} = 42;
var_dump($obj);

Результат выполнения данного примера:

object(stdClass)#1 (2) {
  ["foo"]=>
  int(42)
  ["1"]=>
  int(42)
}


Класс Generator

(PHP 5 >= 5.5.0, PHP 7, PHP 8)

Введение

Создание объектов типа Generator описано в разделе Генераторы.

Предостережение

Объекты Generator не могут быть созданы с помощью оператора new.

Обзор классов

final class Generator implements Iterator {
/* Методы */
public current(): mixed
public getReturn(): mixed
public key(): mixed
public next(): void
public rewind(): void
public send(mixed $value): mixed
public throw(Throwable $exception): mixed
public valid(): bool
public __wakeup(): void
}

Смотрите также

Смотрите также раздел Итераторы объектов.


Generator::current

(PHP 5 >= 5.5.0, PHP 7, PHP 8)

Generator::currentПолучить текущее значение генератора

Описание

public Generator::current(): mixed

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Возвращает текущее значение.



Generator::getReturn

(PHP 7, PHP 8)

Generator::getReturnПолучить значение, возвращаемое генератором

Описание

public Generator::getReturn(): mixed

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Получает возвращаемое значение генератора, после его завершения.

Примеры

Пример #1 Пример использования Generator::getReturn()

<?php

$gen
= (function() {
yield
1;
yield
2;

return
3;
})();

foreach (
$gen as $val) {
echo
$val, PHP_EOL;
}

echo
$gen->getReturn(), PHP_EOL;

Результат выполнения данного примера:

1
2
3



Generator::key

(PHP 5 >= 5.5.0, PHP 7, PHP 8)

Generator::keyПолучить ключ сгенерированного элемента

Описание

public Generator::key(): mixed

Получает ключ сгенерированного элемента.

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Возвращает ключ сгенерированного элемента.

Примеры

Пример #1 Пример использования Generator::key()

<?php

function Gen()
{
yield
'key' => 'value';
}

$gen = Gen();

echo
"{$gen->key()} => {$gen->current()}";

Результат выполнения данного примера:

key => value



Generator::next

(PHP 5 >= 5.5.0, PHP 7, PHP 8)

Generator::nextВозобновить работу генератора

Описание

public Generator::next(): void

Вызов Generator::next() имеет тот же эффект, что и вызов Generator::send() с null в качестве аргумента.

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Функция не возвращает значения после выполнения.



Generator::rewind

(PHP 5 >= 5.5.0, PHP 7, PHP 8)

Generator::rewindПеремотать итератор

Описание

public Generator::rewind(): void

Если итерация уже начата, то выбрасывает исключение.

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Функция не возвращает значения после выполнения.



Generator::send

(PHP 5 >= 5.5.0, PHP 7, PHP 8)

Generator::sendПередать значение в генератор

Описание

public Generator::send(mixed $value): mixed

Передача заданного значения в генератор как результат текущего выражения yield и возобновление его работы.

Если генератор ещё не дошёл до первого вызова оператора yield, он выполнится до момента первого вызова yield, прежде чем передаст в него значение. Так что нет необходимости вызывать генератор с помощью Generator::next() перед вызовом этого метода (как это делается в Python).

Список параметров

value

Значение, которое отправляется в генератор. Это значение будет текущим возвращаемым значением выражения yield генератора.

Возвращаемые значения

Возвращает сгенерированное значение.

Примеры

Пример #1 Использование Generator::send() для внедрения значений

<?php
function printer() {
echo
"I'm printer!".PHP_EOL;
while (
true) {
$string = yield;
echo
$string.PHP_EOL;
}
}

$printer = printer();
$printer->send('Hello world!');
$printer->send('Bye world!');
?>

Результат выполнения данного примера:

I'm printer!
Hello world!
Bye world!



Generator::throw

(PHP 5 >= 5.5.0, PHP 7, PHP 8)

Generator::throwБросить исключение в генератор

Описание

public Generator::throw(Throwable $exception): mixed

Выбрасывает исключение в генератор и возобновляет его выполнение. Поведение будет таким, как будто текущее значение yield заменили на выражение throw $exception.

Если к моменту вызова этого метода генератор закрыт, исключение будет выброшено в контексте вызывающего кода.

Список параметров

exception

Исключение, которое надо выбросить в генератор.

Возвращаемые значения

Возвращает сгенерированное значение.

Примеры

Пример #1 Выбрасывание исключения в итератор

<?php
function gen() {
echo
"Foo\n";
try {
yield;
} catch (
Exception $e) {
echo
"Exception: {$e->getMessage()}\n";
}
echo
"Bar\n";
}

$gen = gen();
$gen->rewind();
$gen->throw(new Exception('Test'));
?>

Результат выполнения данного примера:

Foo
Exception: Test
Bar



Generator::valid

(PHP 5 >= 5.5.0, PHP 7, PHP 8)

Generator::validПроверка, закрыт ли итератор

Описание

public Generator::valid(): bool

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Возвращает false, если итератор закрыт и true в обратном случае.



Generator::__wakeup

(PHP 5 >= 5.5.0, PHP 7, PHP 8)

Generator::__wakeupCallback-функция сериализации

Описание

public Generator::__wakeup(): void

Выбрасывает исключение, поскольку генераторы не могут быть сериализованы.

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Функция не возвращает значения после выполнения.


Содержание



Класс Fiber

(PHP 8 >= 8.1.0)

Введение

Файберы представляют собой прерываемые функции полного цикла. Файберы могут быть приостановлены из любого места цикла, приостанавливая выполнение в файбере до тех пор, пока файбер не будет возобновлён в будущем.

Обзор классов

final class Fiber {
/* Методы */
public __construct(callable $callback)
public start(mixed ...$args): mixed
public resume(mixed $value = null): mixed
public throw(Throwable $exception): mixed
public getReturn(): mixed
public isStarted(): bool
public isSuspended(): bool
public isRunning(): bool
public isTerminated(): bool
public static suspend(mixed $value = null): mixed
public static getCurrent(): ?Fiber
}

Смотрите также

Обзор файберов


Fiber::__construct

(PHP 8 >= 8.1.0)

Fiber::__constructСоздаёт новый экземпляр Fiber

Описание

public Fiber::__construct(callable $callback)

Список параметров

callback

callable-функция для вызова при запуске файбера. Аргументы для Fiber::start() будут предоставляется в качестве аргументов для данного вызываемого объекта.



Fiber::start

(PHP 8 >= 8.1.0)

Fiber::startНачинает выполнение файбера

Описание

public Fiber::start(mixed ...$args): mixed

Переменный список аргументов, передаваемый вызываемому объекту, используемый при построении файбера.

Если при вызове метода файбер уже был запущен, будет выброшено FiberError.

Список параметров

args

Аргументы, которые следует использовать при вызове вызываемого объекта, передаваемого конструктору файбера.

Возвращаемые значения

Значение, предоставленное при первом вызове Fiber::suspend() или null в случае возврата файбера. Если файбер выбросил исключение перед приостановкой, оно будет выброшено из вызова этого метода.



Fiber::resume

(PHP 8 >= 8.1.0)

Fiber::resumeВозобновляет выполнение файбера со значением

Описание

public Fiber::resume(mixed $value = null): mixed

Возобновляет файбер, используя заданное значение в результате текущего вызова Fiber::suspend().

Если файбер не приостановлен при вызове метода, будет выброшена ошибка FiberError.

Список параметров

value

Значение для возобновления файбера. Значение будет возвращаемым значением текущего вызова Fiber::suspend().

Возвращаемые значения

Значение, предоставленное для следующего вызова Fiber::suspend() или null в случае возврата файбера. Если файбер выбросил исключение перед приостановкой, оно будет выброшено из вызова этого метода.



Fiber::throw

(PHP 8 >= 8.1.0)

Fiber::throwВозобновляет выполнение файбера с исключением

Описание

public Fiber::throw(Throwable $exception): mixed

Возобновляет выполнение файбера, выбрасывая данное исключение из текущего вызова Fiber::suspend().

Если файбер не приостановлен при вызове метода, будет выброшена ошибка FiberError.

Список параметров

exception

Исключение, которое нужно передать в файбер из текущего вызова Fiber::suspend().

Возвращаемые значения

Значение, предоставленное при первом вызове Fiber::suspend() или null в случае возврата файбера. Если файбер выбросил исключение перед приостановкой, оно будет выброшено из вызова этого метода.



Fiber::getReturn

(PHP 8 >= 8.1.0)

Fiber::getReturnПолучает значение, возвращаемое файбером

Описание

public Fiber::getReturn(): mixed

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Возвращает значение, возвращаемое callable-функцией, предоставленной в Fiber::__construct(). Если файбер не вернул значение, либо потому, что он не было запущен, либо не был завершён, либо выбросил исключение, будет выброшено исключение FiberError.



Fiber::isStarted

(PHP 8 >= 8.1.0)

Fiber::isStartedОпределяет, запущен ли файбер

Описание

public Fiber::isStarted(): bool

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Возвращает true только после того, как файбер был запущен, в противном случае возвращает false.



Fiber::isSuspended

(PHP 8 >= 8.1.0)

Fiber::isSuspendedОпределяет, приостановлен ли файбер

Описание

public Fiber::isSuspended(): bool

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Возвращает true, если файбер в данный момент приостановлен, в противном случае возвращает false.



Fiber::isRunning

(PHP 8 >= 8.1.0)

Fiber::isRunningОпределяет, работает ли файбер

Описание

public Fiber::isRunning(): bool

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Возвращает true только если файбер работает. Файбер считается работающим после вызова Fiber::start(), Fiber::resume() или Fiber::throw(), который ещё не был возвращён. Возвращает false, если файбер не работает.



Fiber::isTerminated

(PHP 8 >= 8.1.0)

Fiber::isTerminatedОпределяет, завершён ли файбер

Описание

public Fiber::isTerminated(): bool

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Возвращает true только после того, как файбер завершился, либо путём возврата, либо выбросив исключение, в противном случае возвращает false.



Fiber::suspend

(PHP 8 >= 8.1.0)

Fiber::suspendПриостанавливает выполнение текущего файбера

Описание

public static Fiber::suspend(mixed $value = null): mixed

Приостанавливает выполнение текущего файбера. Значение, предоставленное этому методу, будет возвращено из вызова Fiber::start(), Fiber::resume() или Fiber::throw(), который переключил выполнение текущего файбера.

Когда выполнение файбера возобновляется, метод возвращает значение, предоставленное в Fiber::resume(). Если выполнение файбера возобновляется с использованием Fiber::throw, исключение, переданное этому методу, будет выброшено при вызове метода.

Если этот метод вызывается извне файбера, будет выброшена ошибка FiberError.

Список параметров

value

Значение, возвращаемое при вызове Fiber::start(), Fiber::resume() или Fiber::throw(), которые переключают выполнение текущего файбера.

Возвращаемые значения

Значение, предоставленное Fiber::resume().



Fiber::getCurrent

(PHP 8 >= 8.1.0)

Fiber::getCurrentПолучает текущий выполняющийся экземпляр Fiber

Описание

public static Fiber::getCurrent(): ?Fiber

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Возвращает выполняющийся в данный момент экземпляр Fiber или null, если метод вызывается извне файбера.


Содержание

  • Fiber::__construct — Создаёт новый экземпляр Fiber
  • Fiber::start — Начинает выполнение файбера
  • Fiber::resume — Возобновляет выполнение файбера со значением
  • Fiber::throw — Возобновляет выполнение файбера с исключением
  • Fiber::getReturn — Получает значение, возвращаемое файбером
  • Fiber::isStarted — Определяет, запущен ли файбер
  • Fiber::isSuspended — Определяет, приостановлен ли файбер
  • Fiber::isRunning — Определяет, работает ли файбер
  • Fiber::isTerminated — Определяет, завершён ли файбер
  • Fiber::suspend — Приостанавливает выполнение текущего файбера
  • Fiber::getCurrent — Получает текущий выполняющийся экземпляр Fiber


Класс WeakReference

(PHP 7 >= 7.4.0, PHP 8)

Введение

Класс WeakReference предоставляет способ доступа к объекту, не влияя при этом на количество ссылок на него, таким образом сборщик мусора сможет освободить этот объект.

Объект класса WeakReference не может быть сериализован.

Обзор классов

final class WeakReference {
/* Методы */
public __construct()
public static create(object $object): WeakReference
public get(): ?object
}

Примеры использования WeakReference

Пример #1 Пример #1. Простое использование WeakReference

<?php
$obj
= new stdClass;
$weakref = WeakReference::create($obj);
var_dump($weakref->get());
unset(
$obj);
var_dump($weakref->get());
?>

Результатом выполнения данного примера будет что-то подобное:

object(stdClass)#1 (0) {
}
NULL


WeakReference::__construct

(PHP 7 >= 7.4.0, PHP 8)

WeakReference::__constructКонструктор, который запрещает реализацию

Описание

public WeakReference::__construct()

Метод существует только для запрета создания экземпляров класса WeakReference. Слабые ссылки должны быть созданы с помощью фабричного метода WeakReference::create().

Список параметров

У этой функции нет параметров.

Смотрите также



WeakReference::create

(PHP 7 >= 7.4.0, PHP 8)

WeakReference::createСоздаёт новую слабую ссылку

Описание

public static WeakReference::create(object $object): WeakReference

Создаёт новый WeakReference.

Список параметров

object

Объект для слабой ссылки.

Возвращаемые значения

Возвращает только что созданный объект.



WeakReference::get

(PHP 7 >= 7.4.0, PHP 8)

WeakReference::getПолучает объект со слабой ссылкой

Описание

public WeakReference::get(): ?object

Получает объект со слабой ссылкой. Если объект уже был уничтожен, возвращается null.

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Возвращает ссылку object или null, если объект был уничтожен.


Содержание



Класс WeakMap

(PHP 8)

Введение

WeakMap - это коллекция (map) или словарь, который принимает объекты в качестве ключей. Однако, в отличие от аналогичного в остальном SplObjectStorage, объект в ключе WeakMap не влияет на счётчик ссылок объекта. То есть, если в какой-то момент единственной оставшейся ссылкой на объект является ключ WeakMap, объект будет собран сборщиком мусора и удалён из WeakMap. Его основной вариант использования - создание кешей данных, полученных из объекта, которым не нужно жить дольше, чем объект.

WeakMap реализует ArrayAccess, Iterator и Countable, поэтому в большинстве случаев его можно использовать так же, как ассоциативный массив.

Обзор классов

final class WeakMap implements ArrayAccess, Countable, IteratorAggregate {
/* Методы */
public count(): int
public offsetExists(object $object): bool
public offsetGet(object $object): mixed
public offsetSet(object $object, mixed $value): void
public offsetUnset(object $object): void
}

Примеры

Пример #1 Пример использования Weakmap

<?php
$wm
= new WeakMap();

$o = new stdClass;

class
A {
public function
__destruct() {
echo
"Уничтожено!\n";
}
}

$wm[$o] = new A;

var_dump(count($wm));
echo
"Сброс...\n";
unset(
$o);
echo
"Готово\n";
var_dump(count($wm));

Результат выполнения данного примера:

int(1)
Сброс...
Уничтожено!
Готово
int(0)


WeakMap::count

(PHP 8)

WeakMap::countПодсчитывает количество живых записей в коллекции (map)

Описание

public WeakMap::count(): int

Подсчитывает количество живых записей в коллекции (map).

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Возвращает количество живых записей в коллекции (map).



WeakMap::getIterator

(PHP 8)

WeakMap::getIteratorПолучает внешний итератор

Описание

public WeakMap::getIterator(): Iterator

Возвращает внешний итератор.

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Экземпляр объекта, реализующего Iterator или Traversable

Ошибки

Выбрасывает Exception в случае возникновения ошибки.



WeakMap::offsetExists

(PHP 8)

WeakMap::offsetExistsПроверяет, есть ли в коллекции (map) определённый объект

Описание

public WeakMap::offsetExists(object $object): bool

Проверяет, есть ли ссылка на переданный объект в коллекции (map).

Список параметров

object

Объект для проверки.

Возвращаемые значения

Возвращает true, если объект содержится в коллекции (map) или false в противном случае.



WeakMap::offsetGet

(PHP 8)

WeakMap::offsetGetВозвращает значение, на которое указывает определённый объект

Описание

public WeakMap::offsetGet(object $object): mixed

Возвращает значение, на которое указывает определённый объект.

Список параметров

object

Какой-то объект содержится в качестве ключа в коллекции (map).

Возвращаемые значения

Возвращает значение, связанное с объектом, переданным в качестве аргумента или null в противном случае.



WeakMap::offsetSet

(PHP 8)

WeakMap::offsetSetОбновляет коллекцию (map) новой парой ключ-значение

Описание

public WeakMap::offsetSet(object $object, mixed $value): void

Обновляет коллекцию (map) новой парой ключ-значение. Если ключ уже существует в коллекции, старое значение заменяется новым.

Список параметров

object

Объект, служащий ключом пары ключ-значение.

value

Произвольные данные, служащие значением пары ключ-значение.

Возвращаемые значения

Функция не возвращает значения после выполнения.



WeakMap::offsetUnset

(PHP 8)

WeakMap::offsetUnsetУдаляет запись из коллекции (map)

Описание

public WeakMap::offsetUnset(object $object): void

Удаляет запись из коллекции (map).

Список параметров

object

Объект, служащий ключом для записи, которую нужно удалить из коллекции.

Возвращаемые значения

Функция не возвращает значения после выполнения.


Содержание

  • WeakMap::count — Подсчитывает количество живых записей в коллекции (map)
  • WeakMap::getIterator — Получает внешний итератор
  • WeakMap::offsetExists — Проверяет, есть ли в коллекции (map) определённый объект
  • WeakMap::offsetGet — Возвращает значение, на которое указывает определённый объект
  • WeakMap::offsetSet — Обновляет коллекцию (map) новой парой ключ-значение
  • WeakMap::offsetUnset — Удаляет запись из коллекции (map)


Интерфейс Stringable

(PHP 8)

Введение

Интерфейс Stringable обозначает класс, реализующий метод __toString(). В отличие от большинства интерфейсов, Stringable неявно присутствует в любом классе, в котором определён магический метод __toString(), хотя он может и должен быть объявлен явно.

Его основное значение - разрешить функциям выполнять проверку типа на соответствие типу union string|Stringable, чтобы принимать либо строковый примитив, либо объект, который может быть преобразован в строку.

Обзор интерфейсов

interface Stringable {
/* Методы */
public __toString(): string
}

Примеры использования Stringable

Пример #1 Простой пример использования Stringable

<?php
class IPv4Address implements Stringable {
private
string $oct1;
private
string $oct2;
private
string $oct3;
private
string $oct4;

public function
__construct(string $oct1, string $oct2, string $oct3, string $oct4) {
$this->oct1 = $oct1;
$this->oct2 = $oct2;
$this->oct3 = $oct3;
$this->oct4 = $oct4;
}

public function
__toString(): string {
return
"$this->oct1.$this->oct2.$this->oct3.$this->oct4";
}
}

function
showStuff(string|Stringable $value) {
// Здесь Stringable будет преобразован в строку путем вызова
// __toString.
print $value;
}

$ip = new IPv4Address('123', '234', '42', '9');

showStuff($ip);
?>

Результатом выполнения данного примера будет что-то подобное:

123.234.42.9


Stringable::__toString

(PHP 8)

Stringable::__toStringПолучает строковое представление объекта

Описание

public Stringable::__toString(): string

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Возвращает строковое (string) представление объекта.

Смотрите также


Содержание



Интерфейс UnitEnum

(PHP 8 >= 8.1.0)

Введение

Интерфейс UnitEnum автоматически применяется движком ко всем перечислениям. Он не может быть реализован пользовательскими классами. Перечисления не могут переопределять его методы, поскольку реализации по умолчанию предоставляются движком. Доступен только для проверки типа.

Обзор интерфейсов

interface UnitEnum {
/* Методы */
public static cases(): array
}

UnitEnum::cases

(PHP 8 >= 8.1.0)

UnitEnum::casesВозвращает список вариантов перечисления

Описание

public static UnitEnum::cases(): array

Метод возвращает упакованный массив всех вариантов перечисления в порядке объявления.

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Массив всех определённых вариантов перечисления в порядке объявления.

Примеры

Пример #1 Простой пример использования

В следующем примере показано, как возвращаются варианты перечисления.

<?php
enum Suit
{
case
Hearts;
case
Diamonds;
case
Clubs;
case
Spades;
}

var_dump(Suit::cases());
?>

Результат выполнения данного примера:

array(4) {
    [0]=>
    enum(Suit::Hearts)
    [1]=>
    enum(Suit::Diamonds)
    [2]=>
    enum(Suit::Clubs)
    [3]=>
    enum(Suit::Spades)
}

Содержание

  • UnitEnum::cases — Возвращает список вариантов перечисления


Интерфейс BackedEnum

(PHP 8 >= 8.1.0)

Введение

Интерфейс BackedEnum автоматически применяется движком к типизированным перечислениям. Он не может быть реализован пользовательскими классами. Перечисления не могут переопределять его методы, поскольку реализации по умолчанию предоставляются движком. Доступен только для проверки типа.

Обзор интерфейсов

interface BackedEnum extends UnitEnum {
/* Методы */
public static from(int|string $value): static
public static tryFrom(int|string $value): ?static
/* Наследуемые методы */
public static UnitEnum::cases(): array
}

BackedEnum::from

(PHP 8 >= 8.1.0)

BackedEnum::fromСопоставляет скаляр с экземпляром перечисления

Описание

public static BackedEnum::from(int|string $value): static

Метод from() переводит строку (string) или число (int) в соответствующее значение перечисления, если такое имеется. Если соответствующее значение не определено, выбрасывается ValueError.

Список параметров

value

Скалярное значение для сопоставления с перечислением.

Возвращаемые значения

Случайный экземпляр этого перечисления.

Примеры

Пример #1 Простой пример использования

В следующем примере показано, как возвращаются варианты перечисления.

<?php
enum Suit
: string
{
case
Hearts = 'H';
case
Diamonds = 'D';
case
Clubs = 'C';
case
Spades = 'S';
}

$h = Suit::from('H');

var_dump($h);

$b = Suit::from('B');
?>

Результат выполнения данного примера:

enum(Suit::Hearts)

Fatal error: Uncaught ValueError: "B" is not a valid backing value for enum "Suit" in /file.php:15

Смотрите также

  • UnitEnum::cases() - Возвращает список вариантов перечисления
  • BackedEnum::tryFrom() - Сопоставляет скаляр с экземпляром перечисления или null



BackedEnum::tryFrom

(PHP 8 >= 8.1.0)

BackedEnum::tryFromСопоставляет скаляр с экземпляром перечисления или null

Описание

public static BackedEnum::tryFrom(int|string $value): ?static

Метод tryFrom() переводит строку (string) или число (int) в соответствующее значение перечисления, если такое имеется. Если соответствующее значение не определено, возвращается null.

Список параметров

value

Скалярное значение для сопоставления с перечислением.

Возвращаемые значения

Экземпляр перечисления или null, если экземпляр не найден.

Примеры

Пример #1 Простой пример использования

В следующем примере показано, как возвращаются варианты перечисления.

<?php
enum Suit
: string
{
case
Hearts = 'H';
case
Diamonds = 'D';
case
Clubs = 'C';
case
Spades = 'S';
}

$h = Suit::tryFrom('H');

var_dump($h);

$b = Suit::tryFrom('B') ?? Suit::Spades;

var_dump($b);
?>

Результат выполнения данного примера:

enum(Suit::Hearts)
enum(Suit::Spades)

Смотрите также

  • UnitEnum::cases() - Возвращает список вариантов перечисления
  • BackedEnum::from() - Сопоставляет скаляр с экземпляром перечисления


Содержание

  • BackedEnum::from — Сопоставляет скаляр с экземпляром перечисления
  • BackedEnum::tryFrom — Сопоставляет скаляр с экземпляром перечисления или null


Класс SensitiveParameterValue

(PHP 8 >= 8.2.0)

Введение

Класс SensitiveParameterValue позволяет обернуть чувствительные значения, чтобы защитить их от случайного раскрытия.

Значения параметров с атрибутом SensitiveParameter будут автоматически обёрнуты внутри объекта SensitiveParameterValue в трассировках стека.

Обзор классов

final class SensitiveParameterValue {
/* Свойства */
private readonly mixed $value;
/* Методы */
public __construct(mixed $value)
public __debugInfo(): array
public getValue(): mixed
}

Свойства

value

Чувствительное значение, которое необходимо защитить от случайного воздействия.


SensitiveParameterValue::__construct

(PHP 8 >= 8.2.0)

SensitiveParameterValue::__constructСоздаёт новый объект SensitiveParameterValue

Описание

public SensitiveParameterValue::__construct(mixed $value)

Внимание

К настоящему времени эта функция ещё не была документирована; для ознакомления доступен только список аргументов.

Список параметров

value

Произвольное значение, которое должно храниться внутри объекта SensitiveParameterValue.



SensitiveParameterValue::__debugInfo

(PHP 8 >= 8.2.0)

SensitiveParameterValue::__debugInfoЗащита чувствительных значений от случайного воздействия

Описание

public SensitiveParameterValue::__debugInfo(): array

Возвращает пустой массив (array) для защиты чувствительного значения от случайного раскрытия при использовании функции var_dump().

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Пустой массив (array).

Примеры

Пример #1 Передача объекта SensitiveParameterValue в функцию var_dump()

<?php
$s
= new \SensitiveParameterValue('secret');

var_dump($s);
?>

Результат выполнения данного примера:

object(SensitiveParameterValue)#1 (0) {
}



SensitiveParameterValue::getValue

(PHP 8 >= 8.2.0)

SensitiveParameterValue::getValueВозвращает чувствительное значение

Описание

public SensitiveParameterValue::getValue(): mixed

Внимание

К настоящему времени эта функция ещё не была документирована; для ознакомления доступен только список аргументов.

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Чувствительное значение.

Примеры

Пример #1 Пример использования SensitiveParameterValue::getValue()

<?php
$s
= new \SensitiveParameterValue('secret');

echo
"Защищённое значение: ", $s->getValue(), "\n";
?>

Результат выполнения данного примера:

Защищённое значение: secret


Содержание




Предопределённые атрибуты

Содержание

PHP предоставляет некоторые предопределённые атрибуты, которые можно использовать.


Класс Attribute

(PHP 8)

Введение

Атрибуты дают возможность добавлять структурированную, машиночитаемую информацию метаданных о декларациях в коде: целью атрибута могут быть классы, методы, функции, параметры, свойства и константы класса. Метаданные, определённые атрибутами, могут быть проверены во время выполнения с помощью Reflection API. Поэтому атрибуты можно рассматривать как язык конфигурации, встроенный непосредственно в код.

Обзор классов

final class Attribute {
/* Константы */
const int TARGET_CLASS;
const int TARGET_FUNCTION;
const int TARGET_METHOD;
const int TARGET_PROPERTY;
const int TARGET_PARAMETER;
const int TARGET_ALL;
const int IS_REPEATABLE;
/* Свойства */
public int $flags;
/* Методы */
public __construct(int $flags = Attribute::TARGET_ALL)
}

Предопределённые константы

Attribute::TARGET_CLASS

Attribute::TARGET_FUNCTION

Attribute::TARGET_METHOD

Attribute::TARGET_PROPERTY

Attribute::TARGET_CLASS_CONSTANT

Attribute::TARGET_PARAMETER

Attribute::TARGET_ALL

Attribute::IS_REPEATABLE

Свойства

flags

Смотрите также

Введение в атрибуты


Attribute::__construct

(PHP 8)

Attribute::__constructСоздаёт новый экземпляр Attribute

Описание

public Attribute::__construct(int $flags = Attribute::TARGET_ALL)

Создаёт новый экземпляр Attribute.

Список параметров

flags


Содержание



Класс AllowDynamicProperties

(PHP 8 >= 8.2.0)

Введение

Атрибут используется для маркировки классов, которые позволяют использовать динамические свойства.

Обзор классов

final class AllowDynamicProperties {
/* Методы */
public __construct()
}

Примеры

Динамические свойства устарели, начиная с PHP 8.2.0, поэтому их использование без маркировки класса этим атрибутом приведёт к появлению уведомления об устаревании.

<?php
class DefaultBehaviour { }

#[\AllowDynamicProperties]
class ClassAllowsDynamicProperties { }

$o1 = new DefaultBehaviour();
$o2 = new ClassAllowsDynamicProperties();

$o1->nonExistingProp = true;
$o2->nonExistingProp = true;
?>

Результат выполнения данного примера в PHP 8.2:

Deprecated: Creation of dynamic property DefaultBehaviour::$nonExistingProp is deprecated in file on line 10

Смотрите также

Введение в атрибуты


AllowDynamicProperties::__construct

(PHP 8 >= 8.2.0)

AllowDynamicProperties::__constructСоздаёт новый экземпляр атрибута AllowDynamicProperties

Описание

public AllowDynamicProperties::__construct()

Создаёт новый экземпляр AllowDynamicProperties.

Список параметров

У этой функции нет параметров.


Содержание



Класс ReturnTypeWillChange

(PHP 8 >= 8.1.0)

Введение

Большинство неокончательных внутренних методов теперь требуют, чтобы переопределяющие методы объявляли совместимый тип возвращаемого значения, иначе при проверке наследования будет выдано уведомление об устаревании. В случае если тип возвращаемого значения не может быть объявлен для переопределяемого метода из-за проблем совместимости с кросс-версиями PHP, может быть добавлен атрибут #[\ReturnTypeWillChange], чтобы заглушить уведомление об устаревании.

Обзор классов

final class ReturnTypeWillChange {
/* Методы */
public __construct()
}

Смотрите также

Введение в атрибуты


ReturnTypeWillChange::__construct

(PHP 8 >= 8.1.0)

ReturnTypeWillChange::__constructСоздаёт новый экземпляр атрибута ReturnTypeWillChange

Описание

public ReturnTypeWillChange::__construct()

Создаёт новый экземпляр ReturnTypeWillChange.

Список параметров

У этой функции нет параметров.


Содержание



Класс SensitiveParameter

(PHP 8 >= 8.2.0)

Введение

Атрибут используется для обозначения параметра, который является чувствительным и его значение должно быть отредактировано, если оно присутствует в трассировке стека.

Обзор классов

final class SensitiveParameter {
/* Методы */
public __construct()
}

Примеры

<?php

function defaultBehavior(
string $secret,
string $normal
) {
throw new
Exception('Error!');
}

function
sensitiveParametersWithAttribute(
#[\SensitiveParameter]
string $secret,
string $normal
) {
throw new
Exception('Error!');
}

try {
defaultBehavior('password', 'normal');
} catch (
Exception $e) {
echo
$e, PHP_EOL, PHP_EOL;
}

try {
sensitiveParametersWithAttribute('password', 'normal');
} catch (
Exception $e) {
echo
$e, PHP_EOL, PHP_EOL;
}

?>

Результат выполнения данного примера в PHP 8.2 аналогичен:

Exception: Error! in example.php:7
Stack trace:
#0 example.php(19): defaultBehavior('password', 'normal')
#1 {main}

Exception: Error! in example.php:15
Stack trace:
#0 example.php(25): sensitiveParametersWithAttribute(Object(SensitiveParameterValue), 'normal')
#1 {main}

SensitiveParameter::__construct

(PHP 8 >= 8.2.0)

SensitiveParameter::__constructСоздаёт новый экземпляр атрибута SensitiveParameter

Описание

public SensitiveParameter::__construct()

Создаёт новый экземпляр SensitiveParameter.

Список параметров

У этой функции нет параметров.


Содержание




Контекстные опции и параметры

PHP предлагает различные контекстные опции и параметры, которые могут быть использованы со всеми файловыми системами и обёртками потоков. Контекст создаётся с помощью функции stream_context_create(). Опции устанавливаются с помощью stream_context_set_option(), а параметры с помощью stream_context_set_params().


Контекстные опции сокета

Контекстные опции сокетаСписок контекстных опций сокета

Описание

Контекстные опции доступны для всех обёрток, которые работают через сокеты, такие как tcp, http и ftp.

Опции

bindto

Используется для указания IP-адреса (IPv4 или IPv6) и\или номера порта, которые PHP будет использовать для подключения к сети. Синтаксис выглядит следующим образом: ip:port для адреса IPv4, и [ip]:port для адреса IPv6. Установка IP и\или порта в 0 позволит системе самой выбрать нужный IP и\или порт.

Замечание:

Так как во время обычной работы FTP создаёт 2 соединения с сокетами, номер порта не может быть задан с помощью данной опции.

backlog

Используется для ограничения исходящих соединений в очереди соединений сокета.

Замечание:

Используется только для stream_socket_server().

ipv6_v6only

Переопределяет значение ОС по умолчанию для отображения IPv4 в IPv6.

Замечание:

Это важно в случае попытки отдельно слушать IPv4 адреса, в то время как задана привязка к [::].

Применимо только к stream_socket_server().

so_reuseport

Позволяет множественную привязку к одной и той же паре IP:порт, даже из разных процессов.

Замечание:

Применимо только к stream_socket_server().

so_broadcast

Разрешает посылать и принимать данные в/от широковещательных адресов.

Замечание:

Применимо только к stream_socket_server().

tcp_nodelay

Установка этой опции в true сделает SOL_TCP,NO_DELAY=1 соответственно, таким образом, отключение алгоритма TCP Nagle.

Список изменений

Версия Описание
7.1.0 Добавлено tcp_nodelay.
7.0.1 Добавлено ipv6_v6only.

Примеры

Пример #1 Пример использования bindto

<?php
// Соединение с сетью, используя IP '192.168.0.100'
$opts = array(
'socket' => array(
'bindto' => '192.168.0.100:0',
),
);


// Соединение с сетью, используя IP '192.168.0.100' и порт '7000'
$opts = array(
'socket' => array(
'bindto' => '192.168.0.100:7000',
),
);


// Соединение с сетью, используя IPv6 адрес '2001:db8::1'
// и порт '7000'
$opts = array(
'socket' => array(
'bindto' => '[2001:db8::1]:7000',
),
);


// Соединение с сетью через порт '7000'
$opts = array(
'socket' => array(
'bindto' => '0:7000',
),
);


// Создаём контекст...
$context = stream_context_create($opts);

// ...и используем его для получения данных
echo file_get_contents('http://www.example.com', false, $context);

?>



Опции контекста HTTP

Опции контекста HTTPСписок опций контекста HTTP

Описание

Опции контекста для транспортных протоколов http:// и https://.

Опции

method string

GET, POST или любой другой метод HTTP, поддерживаемый удалённым сервером.

По умолчанию GET.

header array или string

Дополнительные заголовки для отправки вместе с запросом. Значения в этой опции будут переопределять другие значения (такие как User-agent:, Host: и Authentication:), даже при следующих переадресациях Location:. Таким образом, не рекомендуется устанавливать заголовок Host:, если включён параметр follow_location.

user_agent string

Значение для отправки вместе с заголовком User-Agent:. Это значение будет использоваться, если заголовок user-agent не был указан в опции контекста header выше.

По умолчанию используется значение директивы user_agent из файла php.ini.

content string

Дополнительные данные для отправки после заголовков. Обычно используется с запросами POST и PUT.

proxy string

URI, указывающий адрес прокси-сервера. (Например, tcp://proxy.example.com:5100).

request_fulluri bool

Когда установлено в true, весь URI будет использован при формировании запроса. (Например, GET http://www.example.com/path/to/file.html HTTP/1.0). Хотя это нестандартный формат запроса, некоторые прокси-серверы требуют его.

По умолчанию false.

follow_location int

Следовать переадресациям заголовка Location. Для отключения установите в значение 0.

По умолчанию 1.

max_redirects int

Максимальное количество переадресаций, которым можно следовать. Значение 1 или меньше означает, что никаких переадресаций не будет произведено.

По умолчанию 20.

protocol_version float

Версия протокола HTTP.

По умолчанию 1.1, начиная с PHP 8.0.0; до этой версии значение по умолчанию было 1.0.

timeout float

Время ожидания на чтение в секундах, указанное в виде числа с плавающей точкой (float), например, 10.5.

По умолчанию используется значение директивы default_socket_timeout из файла php.ini.

ignore_errors bool

Извлечь содержимое даже при неуспешных статусах завершения.

По умолчанию false.

Примеры

Пример #1 Извлечь страницу и отправить данные методом POST

<?php

$postdata
= http_build_query(
array(
'var1' => 'некоторое содержимое',
'var2' => 'doh'
)
);

$opts = array('http' =>
array(
'method' => 'POST',
'header' => 'Content-type: application/x-www-form-urlencoded',
'content' => $postdata
)
);

$context = stream_context_create($opts);

$result = file_get_contents('http://example.com/submit.php', false, $context);

?>

Пример #2 Игнорировать переадресации, но извлечь заголовки и содержимое

<?php

$url
= "http://www.example.org/header.php";

$opts = array('http' =>
array(
'method' => 'GET',
'max_redirects' => '0',
'ignore_errors' => '1'
)
);

$context = stream_context_create($opts);
$stream = fopen($url, 'r', false, $context);

// информация о заголовках, а также
// метаданные о потоке
var_dump(stream_get_meta_data($stream));

// актуальная информация по ссылке $url
var_dump(stream_get_contents($stream));
fclose($stream);
?>

Примечания

Замечание: Опции контекста нижележащего потока в сокете
Дополнительные опции контекста могут поддерживаться нижележащим транспортным протоколом. Для потоков http://, это относится к опциям контекста для транспортного протокола tcp://. Для потоков https://, это относится к опциям контекста для транспортного протокола ssl://.

Замечание: Строка статуса HTTP
Когда эта обёртка потока следует по переадресации, wrapper_data, возвращаемый функцией stream_get_meta_data(), необязательно содержит строку статуса HTTP, которая на самом деле относится к содержанию данных по индексу 0.

array (
  'wrapper_data' =>
  array (
    0 => 'HTTP/1.0 301 Moved Permanently',
    1 => 'Cache-Control: no-cache',
    2 => 'Connection: close',
    3 => 'Location: http://example.com/foo.jpg',
    4 => 'HTTP/1.1 200 OK',
    ...
Первый запрос вернул код 301 (постоянное перенаправление), так что обёртка потока автоматически последовала этому перенаправлению, чтобы получить ответ 200 (индекс = 4).



Параметры контекста FTP

Параметры контекста FTPСписок параметров контекста FTP

Описание

Параметры контекста для транспортных протоколов ftp:// и ftps://

Опции

overwrite bool

Разрешает перезаписывать существующие файлы на удалённом сервере. Работает только в режиме записи (upload).

По умолчанию false.

resume_pos int

Смещение в файле, с которого начинается передача. Работает только в режиме чтения (download).

По умолчанию 0 (Начало файла).

proxy string

FTP-запрос через прокси-сервер HTTP. Применяется только при операции чтения файла. Пример: tcp://squid.example.com:8000.

Примечания

Замечание: Опции контекста нижележащего потока в сокете
Дополнительные опции контекста могут поддерживаться нижележащим транспортным протоколом. Для потоков ftp://, это относится к опциям контекста для транспортного протокола tcp://. Для потоков ftps://, это относится к опциям контекста для транспортного протокола ssl://.



Опции контекста SSL

Опции контекста SSLСписок опций контекста SSL

Описание

Опции контекста для протоколов ssl:// и tls://

Опции

peer_name string

Имя узла. Если его значение не задано, тогда имя подставляется основываясь на имени хоста, использованного при открытии потока.

verify_peer bool

Требовать проверки используемого SSL-сертификата.

По умолчанию true.

verify_peer_name bool

Требовать проверки имени узла.

По умолчанию true.

allow_self_signed bool

Разрешить самоподписанные сертификаты. Требует verify_peer.

По умолчанию false

cafile string

Расположение файла сертификата в локальной файловой системе, который следует использовать с опцией контекста verify_peer для проверки подлинности удалённого узла.

capath string

Если параметр cafile не определён или сертификат не найден, осуществляется поиск в директории, указанной в capath. Путь capath должен быть к корректной директории, содержащей сертификаты, имена которых являются хешем от поля subject, указанного в сертификате.

local_cert string

Путь к локальному сертификату в файловой системе. Это должен быть файл, закодированный в PEM, который содержит ваш сертификат и закрытый ключ. Он дополнительно может содержать открытый ключ эмитента. Закрытый ключ также может содержаться в отдельном файле, заданным local_pk.

local_pk string

Путь к локальному файлу с приватным ключом в случае отдельных файлов сертификата (local_cert) и приватного ключа.

passphrase string

Идентификационная фраза, с которой ваш файл local_cert был закодирован.

verify_depth int

Прервать, если цепочка сертификата слишком длинная.

По умолчанию проверка отсутствует.

ciphers string

Устанавливает список доступных алгоритмов шифрования. Формат этой строки описан в разделе » шифры(1).

По умолчанию принимает значение DEFAULT.

capture_peer_cert bool

Если установлено в true, то будет создана опция контекста peer_certificate, содержащая сертификат удалённого узла.

capture_peer_cert_chain bool

Если установлено в true, то будет создана опция контекста peer_certificate_chain, содержащая цепочку сертификатов.

SNI_enabled bool

Если установлено в true, то будет включено указание имени сервера. Включение SNI позволяет использовать разные сертификаты на одном и том же IP-адресе.

disable_compression bool

Отключает сжатие TLS, что помогает предотвратить атаки типа CRIME.

peer_fingerprint string | array

Прерваться, если дайджест сообщения не совпадает с указанным хешом.

Если указана строка (string), то её длина определяет какой алгоритм хеширования будет использован: "md5" (32) или "sha1" (40).

Если указан массив (array), то ключи определяют алгоритм хеширования, а каждое соответствующее значение является требуемым хешом.

security_level int

Устанавливает уровень безопасности. Если не указан, используется стандартный уровень безопасности, указанный в библиотеке. Уровни безопасности описаны в » SSL_CTX_get_security_level(3).

Доступна с PHP 7.2.0 и OpenSSL 1.1.0.

Список изменений

Версия Описание
7.2.0 Добавлен security_level. Требуется OpenSSL >= 1.1.0.

Примечания

Замечание: Так как ssl:// - это нижележащий транспортный протокол для обёрток https:// и ftps://, то любые опции контекста, которые применяются к ssl:// будут также применяться к https:// и ftps://.

Замечание: Чтобы была доступна возможность указания имени сервера (SNI, Server Name Indication), PHP должен быть скомпилирован с OpenSSL 0.9.8j или более поздней. Используйте константу OPENSSL_TLSEXT_SERVER_NAME чтобы определить, поддерживается ли SNI.



Контекстные опции Phar

Контекстные опции Phar Список контекстных опций Phar

Описание

Контекстные опции для обёртки phar://.

Опции

compress int

Одна из констант сжатия Phar.

metadata mixed

Метаданные Phar. Смотрите Phar::setMetadata().

Смотрите также



Параметры контекста

Параметры контекстаСписок параметров контекста

Описание

Данные параметры могут быть заданы для контекста с помощью функции stream_context_set_params().

Список параметров

notification callable

Функция типа callable, вызываемая при наступлении события в потоке.

За подробностями обращайтесь к документации функции stream_notification_callback.



Опции контекста Zip

Опции контекста ZipСписок опций контекста Zip

Описание

Опции контекста Zip доступны для обёрток zip.

Опции

password

Используется для указания пароля, используемого для зашифрованных архивов.

Список изменений

Версия Описание
PHP 7.2.0, PECL zip 1.14.0 Добавлен параметр password.

Примеры

Пример #1 Простой пример использования password

<?php
// Читаем зашифрованный архив
$opts = array(
'zip' => array(
'password' => 'secret',
),
);
// создаём контекст...
$context = stream_context_create($opts);

// ...и используем его для получения данных
echo file_get_contents('zip://test.zip#test.txt', false, $context);

?>



Zlib context options

Zlib context optionsПеречисление опций контекста Zlib

Описание

Опции контекста Zlib доступны для обёрток zlib.

Опции

level

Используется для указания уровня сжатия (0 - 9).

Список изменений

Версия Описание
7.3.0 Добавлен параметр level.


Содержание



Поддерживаемые протоколы и обёртки

PHP поставляется со множеством встроенных обёрток для различных URL-протоколов для использования с функциями файловой системы, таких как fopen(), copy(), file_exists() и filesize(). В дополнение к этим обёрткам, можно регистрировать собственные обёртки, используя функцию stream_wrapper_register().

Замечание: URL синтаксис, используемый для описания обёртки, может быть только вида scheme://.... Варианты синтаксиса scheme:/ и scheme: не поддерживаются.


file://

file://Доступ к локальной файловой системе

Описание

Файловая система - это стандартная обёртка для PHP, представляющая файловую систему на локальном компьютере. Когда задан относительный путь (путь, который не начинается с символов "/", "\", "\\" или с буквы жёсткого диска в Windows), он будет применён к текущей рабочей директории. В большинстве случаев это директория, в которой находится сценарий, если она не была изменена. При использовании CLI SAPI директорией по умолчанию будет та, из которой вызвано исполнение сценария.

В некоторых функциях, таких как fopen() и file_get_contents(), поиск файла может дополнительно производиться в include_path.

Использование

  • /path/to/file.ext
  • relative/path/to/file.ext
  • fileInCwd.ext
  • C:/path/to/winfile.ext
  • C:\path\to\winfile.ext
  • \\smbserver\share\path\to\winfile.ext
  • file:///path/to/file.ext

Опции

Основная информация
Атрибут Поддержка
Ограничение по allow_url_fopen Нет
Чтение Да
Запись Да
Добавление Да
Одновременное чтение и запись Да
Поддержка stat() Да
Поддержка unlink() Да
Поддержка rename() Да
Поддержка mkdir() Да
Поддержка rmdir() Да



http://

https://

http:// -- https://Доступ к URL-адресам по протоколу HTTP(s)

Описание

Предоставляет доступ только для чтения файлов/ресурсов через HTTP. По умолчанию используется HTTP 1.0 GET. Для поддержки виртуальных хостов на основе имён вместе с запросом посылается заголовок Host:. Если вы сконфигурировали строку user_agent, используя ваш файл php.ini или контекст потока, то она также будет включена в запрос.

Этот поток также позволяет получить доступ к содержимому ресурса; заголовки сохраняются в переменной $http_response_header.

Если важно знать URL, с которого был получен документ (после всех переадресаций, которые были произведены), то вам необходимо обработать серию заголовков ответов, возвращаемых потоком.

INI-директива from будет использоваться для заголовка From:, если установлена и не переопределена в контексте Контекстные опции и параметры.

Использование

  • http://example.com
  • http://example.com/file.php?var1=val1&var2=val2
  • http://user:password@example.com
  • https://example.com
  • https://example.com/file.php?var1=val1&var2=val2
  • https://user:password@example.com

Опции

Основная информация
Атрибут Поддержка
Ограничение по allow_url_fopen Да
Чтение Да
Запись Нет
Добавление Нет
Одновременное чтение и запись Недоступно
Поддержка stat() Нет
Поддержка unlink() Нет
Поддержка rename() Нет
Поддержка mkdir() Нет
Поддержка rmdir() Нет

Примеры

Пример #1 Определение URL, с которого был забран документ после переадресаций

<?php
$url
= 'http://www.example.com/redirecting_page.php';

$fp = fopen($url, 'r');

$meta_data = stream_get_meta_data($fp);
foreach (
$meta_data['wrapper_data'] as $response) {

/* Были ли мы переадресованы? */
if (strtolower(substr($response, 0, 10)) == 'location: ') {

/* Сохранить в $url адрес, куда нас переадресовали */
$url = substr($response, 10);
}

}

?>

Примечания

Замечание: Протокол HTTPS поддерживается только когда модуль openssl включён.

Соединения HTTP предназначены только для чтения; запись данных или копирование файлов в HTTP-ресурс не поддерживается.

Отправка запросов POST и PUT, например, может быть выполнена с помощью HTTP-контекста.

Смотрите также



ftp://

ftps://

ftp:// -- ftps://Доступ к URL-адресам по протоколу FTP(s)

Описание

Позволяет читать существующие файлы и создавать новые файлы через FTP. Если сервер FTP не поддерживает пассивный режим, соединение будет невозможно.

Вы можете открыть файл либо для чтения, либо для записи, но не одновременно для того и другого. Если файл на сервере FTP уже существует, и вы пытаетесь открыть его для записи, но не указали опцию контекста overwrite, соединение будет невозможно. Если вам необходимо перезаписать существующие файлы на FTP, укажите опцию overwrite в контексте и откройте файл для записи. Кроме того, вы можете использовать модуль FTP.

Если вы установили директиву from в файле php.ini, то это значение будет отправлено как пароль при анонимном подключении к FTP.

Использование

  • ftp://example.com/pub/file.txt
  • ftp://user:password@example.com/pub/file.txt
  • ftps://example.com/pub/file.txt
  • ftps://user:password@example.com/pub/file.txt

Опции

Основная информация
Атрибут Поддерживается
Ограничение по allow_url_fopen Да
Чтение Да
Запись Да (новые файлы / существующие файлы с опцией overwrite)
Добавление Да
Одновременное чтение и запись Нет
Поддержка stat() filesize(), filemtime(), filetype(), file_exists(), is_file() и is_dir().
Поддержка unlink() Да
Поддержка rename() Да
Поддержка mkdir() Да
Поддержка rmdir() Да

Примечания

Замечание:

FTPS поддерживается только тогда, когда включена поддержка модуля OpenSSL.

Если сервер не поддерживает SSL, то соединение переключается обратно на обычный нешифрованный протокол FTP.

Замечание: Дополнение
Файлы могут быть дописаны с помощью URL-обёртки ftp://.

Смотрите также



php://

php://Доступ к различным потокам ввода-вывода

Описание

PHP предоставляет несколько разнообразных потоков ввода-вывода, которые позволяют получить доступ к собственным потокам ввода-вывода PHP, к дескрипторам стандартного ввода, вывода и потока ошибок, к временным файловым потокам в памяти и на диске, и фильтрам, которые могут манипулировать другими файловыми ресурсами по мере их считывания или записи.

php://stdin, php://stdout и php://stderr

php://stdin, php://stdout и php://stderr позволяют получить прямой доступ к соответствующим потокам ввода или вывода процесса PHP. Поток указывает на копию файлового дескриптора, таким образом, если вы откроете php://stdin и потом закроете его, вы закроете только вашу копию дескриптора. Актуальный поток, на который ссылается STDIN, остаётся неизменным. Рекомендуется просто использовать константы STDIN, STDOUT и STDERR вместо ручного открытия потоков, используя эти обёртки.

Поток php://stdin предназначен только для чтения, тогда как php://stdout и php://stderr предназначены только для записи.

php://input

php://input является потоком только для чтения, который позволяет вам читать необработанные данные из тела запроса. php://input недоступен в POST-запросах с enctype="multipart/form-data", если опция enable_post_data_reading включена.

php://output

php://output является потоком только для записи, который позволяет вам записать данные в выходной буфер аналогично, как это делают функции print и echo.

php://fd

php://fd предоставляет прямой доступ к указанному файловому дескриптору. Например, php://fd/3 относится к файловому дескриптору 3.

php://memory и php://temp

php://memory и php://temp являются потоками для чтения/записи и позволяют сохранять временные данные в файлоподобной обёртке. Единственная разница между ними заключается в том, что php://memory будет всегда хранить данные в оперативной памяти, тогда как php://temp будет использовать временный файл в том случае, когда объем хранимой информации достигнет заданного лимита (по умолчанию 2 Мб). Расположение этого временного файла определяется аналогично функции sys_get_temp_dir().

Размер лимита для php://temp может устанавливаться путём добавления /maxmemory:NN, где NN - это максимальный размер данных в байтах для хранения в памяти перед использованием временного файла.

php://filter

php://filter - это вид мета-обёртки, предназначенный для разрешения применения фильтров к потоку во время открытия. Это полезно для функционально полных файловых функций, таких как readfile(), file() и file_get_contents(), где нет возможности применить фильтр к потоку до того, как содержимое будет прочитано.

Поток php://filter принимает следующие параметры как часть своего пути. В одном пути можно указать несколько цепочек фильтров. Пожалуйста, ознакомьтесь с примерами и особенностями при использовании этих параметров.

Параметры для php://filter
Название Описание
resource=<поток для фильтрации> Этот параметр является необходимым. Он указывает потоку, что его необходимо отфильтровать.
read=<список фильтров для применения к цепочке чтения> Этот параметр является необязательным. Одно или несколько имён фильтров может быть указано здесь, разделённых вертикальной чертой (|).
write=<список фильтров для применения к цепочке записи> Этот параметр является необязательным. Одно или несколько имён фильтров может быть указано здесь, разделённых вертикальной чертой (|).
<список фильтров для применения к обеим цепочкам чтения и записи> Любой список фильтров, которые используются без префиксов read= или write=, будет применён к обоим потокам на чтение и на запись при необходимости.

Опции

Основная информация (для php://filter смотрите информацию по обёртке, которая подвергается фильтрации)
Атрибут Поддержка
Ограничение по allow_url_fopen Нет
Ограничение по allow_url_include только php://input, php://stdin, php://memory и php://temp.
Чтение только php://stdin, php://input, php://fd, php://memory и php://temp.
Запись только php://stdout, php://stderr, php://output, php://fd, php://memory и php://temp.
Добавление только php://stdout, php://stderr, php://output, php://fd, php://memory и php://temp. (Эквивалентно записи)
Одновременное чтение и запись только php://fd, php://memory и php://temp.
Поддержка stat() нет. Тем не менее, php://memory и php://temp поддерживают fstat().
Поддержка unlink() Нет
Поддержка rename() Нет
Поддержка mkdir() Нет
Поддержка rmdir() Нет
Поддержка stream_select() только php://stdin, php://stdout, php://stderr, php://fd и php://temp.

Примеры

Пример #1 php://temp/maxmemory

Этот необязательный параметр позволяет установить лимит памяти до того, как php://temp начнёт использовать временный файл.

<?php
// Установка предела в 5 MB.
$fiveMBs = 5 * 1024 * 1024;
$fp = fopen("php://temp/maxmemory:$fiveMBs", 'r+');

fputs($fp, "hello\n");

// Читаем то, что мы записали.
rewind($fp);
echo
stream_get_contents($fp);
?>

Пример #2 php://filter/resource=<поток для фильтрации>

Этот параметр должен быть расположен в конце вашей спецификации php://filter и должен указывать на поток, который вы хотите фильтровать.

<?php
/* Это просто эквивалентно:
readfile("http://www.example.com");
так как на самом деле фильтры не указаны */

readfile("php://filter/resource=http://www.example.com");
?>

Пример #3 php://filter/read=<список фильтров для применения к цепочке чтения>

Этот параметр принимает один или более имён фильтров, разделённых вертикальной чертой |.

<?php
/* Этот скрипт выведет содержимое
www.example.com полностью в верхнем регистре */
readfile("php://filter/read=string.toupper/resource=http://www.example.com");

/* Этот скрипт делает тоже самое, что вверхний, но
будет также кодировать алгоритмом ROT13 */
readfile("php://filter/read=string.toupper|string.rot13/resource=http://www.example.com");
?>

Пример #4 php://filter/write=<список фильтров для применения к цепочке записи>

Этот параметр принимает один или более имён фильтров, разделённых вертикальной чертой |.

<?php
/* Этот скрипт будет фильтровать строку "Hello World"
через фильтр rot13, затем записывать результат в
файл example.txt в текущей директории */
file_put_contents("php://filter/write=string.rot13/resource=example.txt","Hello World");
?>

Пример #5 php://memory и php://temp нельзя переиспользовать

php://memory и php://temp нельзя переиспользовать, то есть после закрытия потоков невозможно сослаться на них снова.

file_put_contents('php://memory', 'PHP');
echo file_get_contents('php://memory'); // ничего не напечатает


zlib://

bzip2://

zip://

zlib:// -- bzip2:// -- zip://Сжатые потоки

Описание

compress.zlib:// и compress.bzip2://

zlib: работает как gzopen() за исключением того, что этот поток может использоваться функцией fread() и другими функциями, работающими с файловой системой. Устарела, ввиду неоднозначности при наличии файлов, содержащих ':'; используйте взамен compress.zlib://.

compress.zlib:// и compress.bzip2:// эквиваленты gzopen() и bzopen() соответственно и работают даже в системах, не поддерживающих fopencookie.

Модуль ZIP добавляет обёртку zip:. Начиная с PHP 7.2.0 и libzip 1.2.0+, была добавлена поддержка паролей для зашифрованных архивов, позволяя предоставлять пароли, используя контексты потоков. Пароли могут быть установлены с помощью контекстной опции 'password'.

Использование

  • compress.zlib://file.gz
  • compress.bzip2://file.bz2
  • zip://archive.zip#dir/file.txt

Опции

Основная информация
Атрибут Поддержка
Ограничение по allow_url_fopen Нет
Чтение Да
Запись Да (кроме zip://)
Добавление Да (кроме zip://)
Одновременное чтение и запись Нет
Поддержка stat() Нет, используйте стандартную обёртку file:// для получения информации по сжатым файлам.
Поддержка unlink() Нет, используйте стандартную обёртку file:// для удаления сжатых файлов.
Поддержка rename() Нет
Поддержка mkdir() Нет
Поддержка rmdir() Нет

Смотрите также



data://

data://Схема Data (RFC 2397)

Описание

data: (» RFC 2397) - это обёртка потоков.

Использование

  • data://text/plain;base64,

Опции

Основная информация
Атрибут Поддержка
Ограничение по allow_url_fopen Да
Ограничение по allow_url_include Да
Чтение Да
Запись Нет
Добавление Нет
Чтение и запись одновременно Нет
Поддержка stat() Нет
Поддержка unlink() Нет
Поддержка rename() Нет
Поддержка mkdir() Нет
Поддержка rmdir() Нет

Примеры

Пример #1 Вывод содержимого data://

<?php
// выводит "I love PHP"
echo file_get_contents('data://text/plain;base64,SSBsb3ZlIFBIUAo=');
?>

Пример #2 Получение типа потока

<?php
$fp
= fopen('data://text/plain;base64,', 'r');
$meta = stream_get_meta_data($fp);

// выводит "text/plain"
echo $meta['mediatype'];
?>


glob://

glob://Нахождение путей, соответствующих шаблону

Описание

Обёртка потока glob:.

Использование

  • glob://

Опции

Основная информация
Атрибут Поддержка
Ограничение по allow_url_fopen Нет
Ограничение по allow_url_include Нет
Чтение Нет
Запись Нет
Добавление Нет
Одновременное чтение и запись Нет
Поддержка stat() Нет
Поддержка unlink() Нет
Поддержка rename() Нет
Поддержка mkdir() Нет
Поддержка rmdir() Нет

Примеры

Пример #1 Основы использования

<?php
// Просмотреть все файлы *.php в директории ext/spl/examples/
// и напечатать имена файлов и их размеры
$it = new DirectoryIterator("glob://ext/spl/examples/*.php");
foreach(
$it as $f) {
printf("%s: %.1FK\n", $f->getFilename(), $f->getSize()/1024);
}
?>
tree.php: 1.0K
findregex.php: 0.6K
findfile.php: 0.7K
dba_dump.php: 0.9K
nocvsdir.php: 1.1K
phar_from_dir.php: 1.0K
ini_groups.php: 0.9K
directorytree.php: 0.9K
dba_array.php: 1.1K
class_tree.php: 1.8K


phar://

phar://PHP-архив

Описание

Обёртка потока phar://. Смотрите раздел Обёртка потока Phar для более детального описания.

Использование

  • phar://

Опции

Основная информация
Атрибут Поддержка
Ограничение по allow_url_fopen Нет
Ограничение по allow_url_include Нет
Чтение Да
Запись Да
Добавление Нет
Одновременное чтение и запись Да
Поддержка stat() Да
Поддержка unlink() Да
Поддержка rename() Да
Поддержка mkdir() Да
Поддержка rmdir() Да

Смотрите также



ssh2://

ssh2://Secure Shell 2

Описание

ssh2.shell:// ssh2.exec:// ssh2.tunnel:// ssh2.sftp:// ssh2.scp:// (PECL)

Замечание: Эта обёртка не включена по умолчанию
Для того, чтобы использовать обёртки ssh2.*:// вам необходимо установить модуль » SSH2, доступный в репозитории » PECL.

Кроме получения традиционных данных для входа к URI, обёртки ssh2 также будут повторно использовать открытые соединения, передавая ресурс соединения в хост-часть URL.

Использование

  • ssh2.shell://user:pass@example.com:22/xterm
  • ssh2.exec://user:pass@example.com:22/usr/local/bin/somecmd
  • ssh2.tunnel://user:pass@example.com:22/192.168.0.1:14
  • ssh2.sftp://user:pass@example.com:22/path/to/filename

Опции

Основная информация
Атрибут ssh2.shell ssh2.exec ssh2.tunnel ssh2.sftp ssh2.scp
Ограничение по allow_url_fopen Да Да Да Да Да
Чтение Да Да Да Да Да
Запись Да Да Да Да Нет
Добавление Нет Нет Нет Да (когда поддерживается сервером) Нет
Одновременная чтение и запись Да Да Да Да Нет
Поддержка stat() Нет Нет Нет Да Нет
Поддержка unlink() Нет Нет Нет Да Нет
Поддержка rename() Нет Нет Нет Да Нет
Поддержка mkdir() Нет Нет Нет Да Нет
Поддержка rmdir() Нет Нет Нет Да Нет

Опции контекста
Имя Использование По умолчанию
session Предварительно соединённый ресурс ssh2 для повторного использования  
sftp Предварительно выделенный ресурс sftp для повторного использования  
methods Обмен ключами, ключ хоста, шифр, компрессия и методы MAC для использования  
callbacks    
username Имя пользователя для соединения  
password Пароль для аутентификации  
pubkey_file Имя файла, в котором находится открытый ключ для аутентификации  
privkey_file Имя файла, в котором находится приватный ключ для аутентификации  
env Ассоциативный массив с переменными окружения, которые необходимо установить  
term Тип эмуляции терминала для запроса, когда выделяется pty  
term_width Ширина терминала, запрашивается когда выделяется pty  
term_height Высота терминала, запрашивается когда выделяется pty  
term_units Единицы, в которых измеряются term_width и term_height SSH2_TERM_UNIT_CHARS

Примеры

Пример #1 Открытие потока из активного соединения

<?php
$session
= ssh2_connect('example.com', 22);
ssh2_auth_pubkey_file($session, 'username', '/home/username/.ssh/id_rsa.pub',
'/home/username/.ssh/id_rsa', 'secret');
$stream = fopen("ssh2.tunnel://$session/remote.example.com:1234", 'r');
?>

Пример #2 Переменная $session должна быть доступна!

Если вы хотите использовать какую-либо из обёрток ssh2.*://$session, необходимо сохранить доступным ресурс, хранящийся в переменной $session. Следующий код не будет иметь желаемого эффекта:

<?php
$session
= ssh2_connect('example.com', 22);
ssh2_auth_pubkey_file($session, 'username', '/home/username/.ssh/id_rsa.pub',
'/home/username/.ssh/id_rsa', 'secret');
$connection_string = "ssh2.sftp://$session/";
unset(
$session);
$stream = fopen($connection_string . "path/to/file", 'r');
?>

unset() закрывает сессию, потому что $connection_string не является ссылкой на переменную $session, а только её текстовым представлением. Это также происходит и в случае неявного вызова unset() при выходе из области видимости (например, из функции).



rar://

rar://RAR

Описание

Эта обёртка принимает URL-кодированный путь к RAR-архиву (относительный или абсолютный), необязательный символ звёздочки (*), необязательный символ решётки (#) и необязательное URL-кодированное имя такое, как хранится в архиве. Для указания имени содержимого требуется символ решётки, начальный обратный слеш в названии содержимого необязателен.

Эта обёртка может открывать файлы и директории. Когда открываются директории, знак звёздочки требует, чтобы имена объектов директории были закодированы unencode. Если такой знак не указан, они будут возвращены в URL-кодировке. Смысл этого в том, чтобы позволить обёртке корректно использовать встроенную функциональность, такую как RecursiveDirectoryIterator когда присутствуют имена файлов, которые кажутся как url-закодированные данные.

Если символ решётки и часть имени записи не включена, будет отображён корень архива. Это отличается от обычных директорий тем, что результирующий поток не будет содержать такую информацию, как время модификации, так как корневая директория не сохраняется как отдельная запись в архиве. Использование обёртки с RecursiveDirectoryIterator требует, чтобы символ решётки был включён в URL, когда происходит доступ к корню, так чтобы URL потомков мог быть сконструирован правильно.

Замечание: Эта обёртка не включена по умолчанию
Для того, чтобы использовать обёртку rar://, вам необходимо установить модуль » rar, доступный из репозитория » PECL.

rar:// Доступно начиная с PECL rar 3.0.0

Использование

  • rar://<url encoded archive name>[*][#[<url encoded entry name>]]

Опции

Основная информация
Атрибут Поддержка
Ограничение по allow_url_fopen Нет
Ограничение по allow_url_include Нет
Чтение Да
Запись Нет
Добавление Нет
Одновременное чтение и запись Нет
Поддержка stat() Да
Поддержка unlink() Нет
Поддержка rename() Нет
Поддержка mkdir() Нет
Поддержка rmdir() Нет

Опции контекста
Название Использование По умолчанию
open_password Пароль используется для шифрования заголовков архива, если таковые есть. WinRAR будет шифровать все файлы с таким же паролем, как и пароль заголовков, когда последний присутствует. Поэтому для архивов с зашифрованными заголовками опция file_password будет проигнорирована.  
file_password Пароль, используемый для шифрования файла, если таковой имеется. Если заголовки также зашифрованы, эта опция будет игнорирована в пользу open_password. Причина этого в том, что нет смысла в использовании одновременно двух разных паролей для шифрования отдельно заголовков и отдельно файлов. Нет таких архивов, где бы это пригодилось. Заметим, что если у архива отсутствуют зашифрованные заголовки, то опция open_password будет игнорирована и эта опция должна быть использована вместо неё.  
volume_callback Обратный вызов для определения пути недостающих томов архива. Смотрите RarArchive::open() для более детальной информации.  

Примеры

Пример #1 Обход RAR-архива

<?php

class MyRecDirIt extends RecursiveDirectoryIterator {
function
current() {
return
rawurldecode($this->getSubPathName()) .
(
is_dir(parent::current())?" [DIR]":"");
}
}

$f = "rar://" . rawurlencode(dirname(__FILE__)) .
DIRECTORY_SEPARATOR . 'dirs_and_extra_headers.rar#';

$it = new RecursiveTreeIterator(new MyRecDirIt($f));

foreach (
$it as $s) {
echo
$s, "\n";
}
?>

Результатом выполнения данного примера будет что-то подобное:

|-allow_everyone_ni [DIR]
|-file1.txt
|-file2_אּ.txt
|-with_streams.txt
\-אּ [DIR]
  |-אּ\%2Fempty%2E [DIR]
  | \-אּ\%2Fempty%2E\file7.txt
  |-אּ\empty [DIR]
  |-אּ\file3.txt
  |-אּ\file4_אּ.txt
  \-אּ\אּ_2 [DIR]
    |-אּ\אּ_2\file5.txt
    \-אּ\אּ_2\file6_אּ.txt

Пример #2 Открытие зашифрованного файла (шифрование заголовка)

<?php
$stream
= fopen("rar://" .
rawurlencode(dirname(__FILE__)) . DIRECTORY_SEPARATOR .
'encrypted_headers.rar' . '#encfile1.txt', "r", false,
stream_context_create(
array(
'rar' =>
array(
'open_password' => 'samplepassword'
)
)
)
);
var_dump(stream_get_contents($stream));
/* дата создания и дата последнего доступа включается опционально в WinRAR, поэтому у
* большинства файлов их нет */
var_dump(fstat($stream));
?>

Результатом выполнения данного примера будет что-то подобное:

string(26) "Encrypted file 1 contents."
Array
(
    [0] => 0
    [1] => 0
    [2] => 33206
    [3] => 1
    [4] => 0
    [5] => 0
    [6] => 0
    [7] => 26
    [8] => 0
    [9] => 1259550052
    [10] => 0
    [11] => -1
    [12] => -1
    [dev] => 0
    [ino] => 0
    [mode] => 33206
    [nlink] => 1
    [uid] => 0
    [gid] => 0
    [rdev] => 0
    [size] => 26
    [atime] => 0
    [mtime] => 1259550052
    [ctime] => 0
    [blksize] => -1
    [blocks] => -1
)


ogg://

ogg://Аудиопотоки

Описание

Файлы, открываемые для чтения с использованием обёртки ogg://, рассматриваются как сжатый аудиопоток, кодируемый с использованием кодека OGG/Vorbis. Аналогично, файлы, открытые для записи или добавления через обёртку ogg://, записываются как сжатые звуковые данные. Функция stream_get_meta_data(), когда используется с файлами OGG/Vorbis открытыми для чтения, будет возвращать разнообразную информацию о потоке, включая тег производителя vendor, комментарии comments, число каналов channels, частоту дискретизации rate, и диапазон частоты кодирования, описываемый: bitrate_lower, bitrate_upper, bitrate_nominal и bitrate_window.

ogg:// (PECL)

Замечание: Данная обёртка не доступна по умолчанию
Для того чтобы использовать обёртку ogg:// вы должны установить модуль » OGG/Vorbis доступный в » PECL.

Использование

  • ogg://soundfile.ogg
  • ogg:///path/to/soundfile.ogg
  • ogg://http://www.example.com/path/to/soundstream.ogg

Опции

Основная информация
Атрибут Поддержка
Ограничение по allow_url_fopen Нет
Чтение Да
Запись Да
Добавление Да
Одновременное чтение и запись Нет
Поддержка stat() Нет
Поддержка unlink() Нет
Поддержка rename() Нет
Поддержка mkdir() Нет
Поддержка rmdir() Нет

Установки для контекста
Название Использование Значение по умолчанию Режим
pcm_mode Опция PCM кодирования, применяемая во время чтения, одна из констант: OGGVORBIS_PCM_U8, OGGVORBIS_PCM_S8, OGGVORBIS_PCM_U16_BE, OGGVORBIS_PCM_S16_BE, OGGVORBIS_PCM_U16_LE и OGGVORBIS_PCM_S16_LE. (8- или 16-битное, со знаком или без него, прямой или обратный порядок байтов) OGGVORBIS_PCM_S16_LE Чтение
rate Частота дискретизации входных данных, выраженная в Гц 44100 Запись/Добавление
bitrate Когда дано целое число, постоянный битрейт при котором кодировать. (от 16000 до 131072) Когда дано вещественное число, качество переменного битрейта для использования. (от -1.0 до 1.0) 128000 Запись/Добавление
channels Количество аудиоканалов для кодирования, обычно 1 (Моно), или 2 (Стерео). Может варьироваться вплоть до 16. 2 Запись/Добавление
comments Массив строк для запись в заголовок трека.   Запись/Добавление

Примеры



expect://

expect://Потоки для взаимодействия с процессами

Описание

Потоки, открытые с помощью обёртки expect://, предоставляют доступ к процессам stdio, stdout и stderr через PTY.

Замечание: Эта обёртка отключена по умолчанию
Для того, чтобы использовать обёртку expect://, необходимо установить модуль » Expect, доступный в » PECL.

expect:// (PECL)

Использование

  • expect://command

Опции

Основная информация
Атрибут Поддержка
Ограничение по allow_url_fopen Нет
Чтение Да
Запись Да
Добавление Да
Одновременное чтение и запись Нет
Поддержка stat() Нет
Поддержка unlink() Нет
Поддержка rename() Нет
Поддержка mkdir() Нет
Поддержка rmdir() Нет

Примеры


Содержание

  • file:// — Доступ к локальной файловой системе
  • http:// — Доступ к URL-адресам по протоколу HTTP(s)
  • ftp:// — Доступ к URL-адресам по протоколу FTP(s)
  • php:// — Доступ к различным потокам ввода-вывода
  • zlib:// — Сжатые потоки
  • data:// — Схема Data (RFC 2397)
  • glob:// — Нахождение путей, соответствующих шаблону
  • phar:// — PHP-архив
  • ssh2:// — Secure Shell 2
  • rar:// — RAR
  • ogg:// — Аудиопотоки
  • expect:// — Потоки для взаимодействия с процессами



Безопасность


Вступление

PHP является мощным языком программирования и интерпретатором, взаимодействующим с веб-сервером как модуль либо как независимое бинарное CGI приложение. PHP способен обращаться к файлам, выполнять различные команды на сервере и открывать сетевые соединения. Именно поэтому все скрипты, исполняемые на сервере, являются потенциально опасными. PHP изначально разрабатывался как более защищённый (относительно Perl, C) язык для написания CGI-приложений. При помощи ряда настроек во время компиляции, а также динамических настроек приложения, вы всегда сможете найти подходящее сочетание свободы действий и безопасности.

Поскольку существует много различных способов использования PHP, имеется и множество опций, управляющих его поведением. Широкий выбор опций гарантирует вам возможность использовать PHP в разных целях, но также означает, что некоторые комбинации опций делают сервер незащищённым.

Гибкость конфигурирования PHP можно сравнить с гибкостью самого языка. PHP можно использовать для создания полноценных серверных приложений, использующих доступные для указанного пользователя возможности операционной системы, либо в качестве простых подключаемых файлов, хранящихся на сервере с минимальным риском в жёстко контролируемой среде. То, как настроено данное окружение, а также качество его безопасности, в большей части зависит от PHP-разработчика.

Эта глава начинается с рассмотрения некоторых общих вопросов безопасности, различных конфигурационных опций и их комбинаций, а также ситуаций, когда их использование является безопасным. Кроме того, приводятся некоторые рассуждения касательно безопасного кодирования.



Общие рассуждения

Так как абсолютно безопасные системы являются не более, чем мифом, на практике приходится балансировать между комфортом и безопасностью. Если каждая переменная, вводимая пользователем, будет требовать две биометрические проверки (например, сканирование сетчатки глаза и отпечатки пальцев), то вы получите предельно высокую достоверность данных. Но поскольку заполнение сложной формы будет занимать около получаса, у пользователей такой системы непременно возникнет желание обойти навязчивую защиту.

Правильно поставленная защита должна соответствовать основным требованиям безопасности, не ухудшая при этом работу пользователя и не усложняя самому программисту разработку продукта. Вместе с тем, некоторые атаки могут основываться именно на таком подходе к защите, что приводит к её постепенному ослаблению.

Следует помнить хорошую поговорку: надёжность системы определяется её самым слабым звеном. Например, если все транзакции логируются по времени, месторасположению, типу транзакции и ряду других параметров, но авторизация пользователя происходит всего лишь по куке (cookie), то связь конкретной записи в логе с пользователем системы весьма сомнительна.

При тестировании следует помнить, что вы не можете проверить все возможные варианты даже для простейшей страницы. Данные, которые вы ожидаете, могут совершенно не соответствовать тому, что введёт раздражённый служащий, хакер со стажем или домашний кот, разгуливающий по клавиатуре. Поэтому лучше логически подумать над вопросом: в каком месте могут быть введены неожиданные данные, как их можно модифицировать, усечь, либо, наоборот, дополнить.

Интернет наполнен людьми, которые хотят сделать себе имя на том, что взломают ваш код, разрушат сайт, опубликуют на нем неуместный контент или просто сделают ваш день интереснее. И не важно, маленький у вас сайт или большой, если у вас есть онлайн-сервер - вы уже потенциальная жертва. Многие программы-взломщики не смотрят на размер, они просто перебирают массивы IP-адресов, выискивая очередную жертву. Постарайтесь не стать одной из них.



Если PHP установлен как CGI

Содержание


Возможные атаки

Использование PHP как бинарного CGI-приложения является одним из вариантов, когда по каким-либо причинам нежелательно интегрировать PHP в веб-сервер (например, Apache) в качестве модуля, либо предполагается использование различных CGI-обёрток и таких утилит, как chroot и setuid для организации безопасного окружения работы скриптов. Такая установка обычно сопровождается копированием исполняемого файла PHP в директорию cgi-bin веб-сервера. CERT (организация, следящая за угрозами безопасности) » CA-96.11 рекомендует не помещать какие-либо интерпретаторы в каталог cgi-bin. Даже если PHP используется как самостоятельный интерпретатор, он спроектирован так, чтобы предотвратить возможность следующих атак:

  • Доступ к системным файлам: http://my.host/cgi-bin/php?/etc/passwd Данные, введённые в строке запроса (URL) после вопросительного знака, передаются интерпретатору как аргументы командной строки с помощью интерфейса CGI. Обычно интерпретаторы открывают и исполняют файл, указанный в качестве первого аргумента. В случае использования PHP в качестве CGI-приложения он не станет интерпретировать аргументы командной строки.
  • Доступ к произвольному документу на сервере: http://my.host/cgi-bin/php/secret/doc.html Согласно общепринятому соглашению, часть пути в запрошенной странице, которая расположена после имени выполняемого модуля PHP, /secret/doc.html, используется для указания файла, который будет интерпретирован CGI-программой. Обычно, некоторые конфигурационные опции веб-сервера (например, Action для сервера Apache) используются для перенаправления документа, к примеру, для перенаправления запросов вида http://my.host/secret/script.php интерпретатору PHP. В таком случае веб-сервер сначала проверяет права доступа к директории /secret, и после этого создаёт перенаправленный запрос http://my.host/cgi-bin/php/secret/script.php. К сожалению, если запрос изначально задан в полном виде, проверка на наличие прав для файла /secret/script.php не выполняется, она происходит только для файла /cgi-bin/php. Таким образом, пользователь имеет возможность обратиться к /cgi-bin/php, и, как следствие, к любому защищённому документу на сервере. Если в PHP указать во время исполнения скрипта опции cgi.force_redirect, doc_root и user_dir, то можно предотвратить подобные атаки для директорий с ограниченным доступом. Более детально приведённые опции, а также их комбинации будут рассмотрены ниже.


Вариант 1: обслуживаются только общедоступные файлы

В случае, если на вашем сервере отсутствуют файлы, доступ к которым ограничен паролем либо фильтром по IP-адресам, нет никакой необходимости использовать данные опции. Если ваш веб-сервер не разрешает выполнять перенаправления, либо не имеет возможности взаимодействовать с исполняемым PHP-модулем на необходимом уровне безопасности, вы можете включить ini-директиву cgi.force_redirect. Но при этом вы всё ещё должны убедиться, что альтернативные способы вызова скрипта, такие как непосредственный вызов http://my.host/cgi-bin/php/dir/script.php либо с переадресацией http://my.host/dir/script.php, недоступны.

В веб-сервере Apache перенаправление может быть сконфигурировано при помощи директив AddHandler и Action (описано ниже).



Вариант 2: использование cgi.force_redirect

Конфигурационная директива cgi.force_redirect предотвращает попытки непосредственного вызова PHP по адресу вида http://my.host/cgi-bin/php/secretdir/script.php. Вместо этого PHP будет обрабатывать пришедший запрос только в том случае, если он был перенаправлен веб-сервером.

Обычно перенаправление в конфигурации Apache настраивается при помощи следующих опций:

Action php-script /cgi-bin/php
AddHandler php-script .php

Эта опция проверена только с веб-сервером Apache, её работа основывается на установке в случае перенаправления нестандартной переменной REDIRECT_STATUS, находящейся в CGI-окружении. В случае, если ваш веб-сервер не предоставляет возможности однозначно идентифицировать, является ли данный запрос перенаправленным, вы не можете использовать описываемую в данном разделе опцию и должны воспользоваться любым другим методом работы с CGI-приложениями.



Вариант 3: использование опций doc_root или user_dir

Размещение динамического контента, такого как скрипты или любых других исполняемых файлов, в директории веб-сервера делает его потенциально опасным. В случае, если в конфигурации сервера допущена ошибка, возможна ситуация, когда скрипты не выполняются, а отображаются в браузере, как обычные HTML-документы, что может привести к утечке конфиденциальной информации (например, паролей), либо информации, являющейся интеллектуальной собственностью. Исходя из таких соображений, многие системные администраторы предпочитают использовать для хранения скриптов отдельную директорию, работая со всеми размещёнными в ней файлами по CGI-интерфейсу.

В случае, если невозможно гарантировать, что запросы не перенаправляются, как было показано в предыдущем разделе, необходимо указывать переменную doc_root, которая отличается от корневой директории веб-документов.

Вы можете установить корневую директорию для PHP-скриптов, настроив параметр doc_root в конфигурационном файле, либо установив переменную окружения PHP_DOCUMENT_ROOT. В случае, если PHP используется посредством CGI, полный путь к открываемому файлу будет построен на основании значения переменной doc_root и указанного в запросе пути. Таким образом, вы можете быть уверены, что скрипты будут выполняться только внутри указанной вами директории (кроме директории user_dir, которая описана ниже).

Ещё одна используемая при настройке безопасности опция - user_dir. В случае, если переменная user_dir не установлена, путь к открываемому файлу строится относительно doc_root. Запрос вида http://my.host/~user/doc.php приводит к выполнению скрипта, находящегося не в домашнем каталоге соответствующего пользователя, а находящегося в подкаталоге doc_root скрипта ~user/doc.php (да, имя директории начинается с символа ~).

Но если user_dir установлена, например, в значение public_php, то запрос вида http://my.host/~user/doc.php откроет файл doc.php, находящийся в домашнем каталоге пользователя, в директории public_php. Например, если домашний каталог пользователя /home/user, будет выполнен файл /home/user/public_php/doc.php.

Установка опции user_dir происходит независимо от установки doc_root, таким образом вы можете контролировать корневую директорию веб-сервера и пользовательские директории независимо друг от друга.



Вариант 4: PHP вне дерева веб-документов

Один из способов существенно повысить уровень безопасности - поместить исполняемый модуль PHP вне дерева веб-документов, например в /usr/local/bin. Единственным недостатком такого подхода является то, что первая строка каждого скрипта должна иметь вид:

#!/usr/local/bin/php
Также необходимо сделать все файлы скриптов исполняемыми. Таким образом, скрипт будет рассматриваться так же, как и любое другое CGI-приложение, написанное на Perl, sh или любом другом скриптовом языке, который использует #! в начале файла для запуска самого себя.

Для корректной обработки PHP переменных PATH_INFO и PATH_TRANSLATED директива ini cgi.discard_path должна быть включена.




Если PHP установлен как модуль Apache

Если PHP используется как модуль Apache, он наследует права пользователя, с которыми был запущен веб-сервер (обычно это пользователь "nobody"). Это влияет на обеспечение безопасности и реализацию авторизации. Например, если вы используете PHP для доступа к базе данных, которая не имеет встроенного механизма разграничения доступа, вам придётся обеспечить доступ к БД для пользователя 'nobody'. В таком случае вредоносный скрипт может получить доступ к базе данных и модифицировать её, даже не зная логина и пароля. Вполне возможна ситуация, при которой веб-паук неверными запросами на страницу администратора базы данных может уничтожить все ваши базы данных. Вы можете избежать такой ситуации при помощи авторизации Apache или разработав собственную модель доступа, используя LDAP, файлы .htaccess или любые другие технологии, внедряя соответствующий код в ваши PHP-скрипты.

Достаточно часто используются такие настройки безопасности, при которых PHP (имеется в виду пользователь, с правами которого выполняется Apache) имеет минимальные привилегии, например, отсутствует возможность записи в пользовательские директории с помощью PHP. Или, например, отсутствует возможность работать с базой данных. При этом система безопасности не позволяет записывать как "хорошие", так и "плохие" файлы, или провести "хорошие" или "плохие" транзакции.

Распространённой ошибкой является запуск Apache с правами суперпользователя или любое другое расширение полномочий веб-сервера.

Расширение привилегий веб-сервера до полномочий суперпользователя угрожает работоспособности всей системы, поэтому такие команды, как sudo, chroot и другие способы запуска с правами суперпользователя должны выполняться исключительно теми, кто профессионально разбирается в вопросах безопасности.

Существует несколько простых решений. Используя open_basedir, вы можете ограничить дерево доступных директорий для PHP. Вы так же можете определить область доступа Apache, ограничив все действия, совершаемые из веба не пользовательскими или несистемными файлами.



Безопасность сессий

Крайне важно обеспечивать безопасность HTTP-сессий. Подробное описание, какими средствами этого можно достичь, читайте в секции Безопасность сессий руководства Сессии.



Безопасность файловой системы

Содержание

PHP является одним из важных моментов в вопросе безопасности сервера, поскольку PHP-скрипты могут манипулировать файлами и каталогами на диске. В связи с этим существуют конфигурационные настройки, указывающие, какие файлы могут быть доступны и какие операции с ними можно выполнять. Необходимо проявлять осторожность, поскольку любой из файлов, с полными правами чтения ("world readable") может быть прочитан каждым, кто имеет доступ к файловой системе.

Поскольку в PHP изначально предполагался полноправный пользовательский доступ к файловой системе, можно написать PHP-скрипт, который позволит читать системные файлы, такие как /etc/passwd, управлять сетевыми соединениями, отправлять задания принтеру, и так далее. Как следствие, вы всегда должны быть уверены в том, что файлы, которые вы читаете или модифицируете, являются именно теми, которые вы подразумевали.

Рассмотрим следующий пример, в котором пользователь создал скрипт, удаляющий файл из его домашней директории. Предполагается ситуация, когда веб-интерфейс, написанный на PHP, регулярно используется для работы с файлами, и настройки безопасности позволяют удалять файлы в домашнем каталоге.

Пример #1 Недостаточная проверка внешних данных ведёт к...

<?php
// Удаление файла из домашней директории пользователя
$username = $_POST['user_submitted_name'];
$userfile = $_POST['user_submitted_filename'];
$homedir = "/home/$username";

unlink("$homedir/$userfile");

echo
"Файл был удалён!";
?>
Поскольку переменные вводятся в пользовательской форме, существует возможность удалить файлы, принадлежащие кому-либо другому, введя соответствующие значения. В этом случае может понадобиться авторизация. Посмотрим, что произойдёт, если будут отправлены значения "../etc/" и "passwd". Скрипт выполнит следующие действия:

Пример #2 ... атаке на файловую систему

<?php
// Удаление любого файла, доступного из PHP-скрипта.
// В случае, если PHP работает с правами пользователя root:
$username = $_POST['user_submitted_name']; // "../etc"
$userfile = $_POST['user_submitted_filename']; // "passwd"
$homedir = "/home/$username"; // "/home/../etc"

unlink("$homedir/$userfile"); // "/home/../etc/passwd"

echo "Файл был удалён!";
?>
Существуют две важные меры, которые можно предпринять для предотвращения описанной проблемы.
  • Ограничить доступ пользователя, с правами которого работает веб-сервер с PHP.
  • Проверять все данные, вводимые пользователем.
Вот улучшенный вариант кода:

Пример #3 Более безопасная проверка имени файла

<?php
// Удаление любого файла, к которому имеет доступ пользователь,
// под которым запущен PHP.
$username = $_SERVER['REMOTE_USER']; // использование авторизации
$userfile = basename($_POST['user_submitted_filename']);
$homedir = "/home/$username";

$filepath = "$homedir/$userfile";

if (
file_exists($filepath) && unlink($filepath)) {
$logstring = "$filepath удалён\n";
} else {
$logstring = "Не удалось удалить $filepath\n";
}
$fp = fopen("/home/logging/filedelete.log", "a");
fwrite($fp, $logstring);
fclose($fp);

echo
htmlentities($logstring, ENT_QUOTES);

?>
Однако и такая проверка не учитывает все возможные ситуации. Если система авторизации позволяет пользователям выбирать произвольные логины, взломщик может создать учётную запись вида "../etc/" и система опять окажется уязвимой. Исходя из этого, вам может понадобиться более строгая проверка:

Пример #4 Более строгая проверка имени файла

<?php
$username
= $_SERVER['REMOTE_USER']; // использование авторизации
$userfile = $_POST['user_submitted_filename'];
$homedir = "/home/$username";

$filepath = "$homedir/$userfile";

if (!
ctype_alnum($username) || !preg_match('/^(?:[a-z0-9_-]|\.(?!\.))+$/iD', $userfile)) {
die(
"Неправильное имя пользователя или файл");
}

//etc...
?>

В зависимости от используемой вами операционной системы необходимо предусматривать возможность атаки на разнообразные файлы, включая системные файлы устройств (/dev/ или COM1), конфигурационные файлы (например /etc/ или файлы с расширением .ini), хорошо известные области хранения данных (/home/, My Documents), и так далее. Исходя из этого, как правило, легче реализовать такую политику безопасности, в которой запрещено все, исключая то, что явно разрешено.


Проблемы безопасности, связанные с нулевым байтом

Так как для работы с файловой системой PHP использует нижележащие C-функции, то в этом случае возможна крайне неожиданная обработка нулевого байта. Так как нулевой байт означает конец строки в C, то строки, содержащие такой байт, не будут трактоваться полностью, а только до той позиции, в которой находится этот байт. Следующий пример содержит уязвимый код, демонстрирующий эту проблему:

Пример #1 Скрипт, уязвимый к нулевому байту

<?php
$file
= $_GET['file']; // "../../etc/passwd\0"
if (file_exists('/home/wwwrun/'.$file.'.php')) {
// file_exists возвратит true, т.к. /home/wwwrun/../../etc/passwd существует
include '/home/wwwrun/'.$file.'.php';
// будет подключён файл /etc/passwd
}
?>

Таким образом, любая испорченная строка, используемая в операциях с файловой системой должна быть соответствующим образом проверена. Вот улучшенная версия предыдущего примера:

Пример #2 Корректная проверка входных данных

<?php
$file
= $_GET['file'];

// Белый список возможных значений
switch ($file) {
case
'main':
case
'foo':
case
'bar':
include
'/home/wwwrun/include/'.$file.'.php';
break;
default:
include
'/home/wwwrun/include/main.php';
}
?>



Безопасность баз данных

Содержание

На сегодняшний день базы данных являются ключевыми компонентами большинства веб-приложений, позволяя предоставлять на сайтах динамический контент. Поскольку в таких БД может храниться очень деликатная или конфиденциальная информация, необходимо очень серьёзно относиться к защите базы данных.

Для извлечения или сохранения любых данных вам необходимо открыть соединение с базой данных, отправить корректный запрос, извлечь результат и закрыть соединение. В настоящее время наиболее распространённым стандартом общения является язык структурированных запросов (SQL). Всегда следует помнить о возможности атаки посредством SQL-запроса.

Очевидно, что сам по себе PHP не может защитить вашу базу данных. В этом разделе документации описаны самые основы безопасного доступа и управления данными баз данных в PHP-скриптах.

Запомните простое правило: максимальная защита. Чем больше потенциально опасных участков системы вы проработаете, тем сложнее будет потенциальному взломщику получить доступ к базе данных или повредить её. Хорошее проектирование базы данных и программных приложений поможет вам справиться с вашими страхами.


Проектирование базы данных

Первый шаг - это всегда создание БД, исключая тот случай, когда вы хотите использовать готовую базу, предоставляемую третьими лицами. После того, как база данных создана, она назначается пользователю, который выполнил создавший БД запрос. Как правило, только владелец (или суперпользователь) может выполнять различные действия с объектами, хранимыми в базе данных. Для того, чтобы и другие пользователи имели к ней доступ, их необходимо наделить соответствующими привилегиями.

Приложения никогда не должны соединяться с базой данных, используя учётную запись владельца или суперпользователя, потому что они смогут выполнить любой запрос, например, модифицировать структуру таблиц (например, удалить некоторые таблицы) или даже удалить все содержимое БД целиком.

Вы можете создать различные учётные записи пользователей БД для каждой индивидуальной потребности приложения с сильно ограниченными функциональными ограничениями. Рекомендуется назначать только самые необходимые привилегии, также вы должны избегать ситуаций, когда один и тот же пользователь может взаимодействовать с базой данных несколькими способами. Вы должны понимать, что если злоумышленник сможет воспользоваться какой-либо учётной записью вашей БД, он сможет вносить в базу все те изменения, что и программа, которая использует текущую учётную запись.



Соединение с базой данных

Вы можете использовать безопасные SSL или ssh соединения, для шифрования данных, которыми обмениваются клиент и сервер. При реализации чего-либо из вышеперечисленного мониторинг трафика и сбор данных о вашей базе данных существенно усложнится для потенциального взломщика .



Шифрование хранилища базы данных

Вы можете установить соединения через SSL для шифрования связи клиент/сервер для повышения безопасности, или вы можете использовать ssh для шифрования сетевого соединения между клиентами и сервером базы данных. Если любой из них используется, то мониторинг вашего трафика и получение информации о вашей базы данных будет трудным для потенциального злоумышленника.

В случае, если взломщик получил непосредственный доступ к БД (в обход веб-сервера), он может извлечь интересующие данные или нарушить их целостность, если информация не защищена на уровне самой БД. Шифрование данных - хороший способ предотвратить такую ситуацию, но лишь незначительное количество БД предоставляют такую возможность.

Наиболее простое решение этой проблемы - установить вначале обыкновенный программный пакет для шифрования данных, а затем использовать его в ваших PHP-скриптах. PHP может вам помочь с этой задачей с помощью таких модулей как OpenSSL и Sodium, реализующих довольно большое число алгоритмов шифрования. При таком подходе скрипт вначале шифрует сохраняемые данные, а затем дешифрует их при запросе. Ниже приведены примеры того, как работает шифрование данных в PHP-скриптах.

Хеширование

В случае работы со скрытыми служебными данными, если не требуется их нешифрованное представление (т.е. его не нужно показывать), то, как следствие, можно использовать хеширование. Хорошо известный пример хеширования - хранение криптографического хеша от пароля в БД, вместо хранения оригинального значения.

Функция password позволяет удобно хешировать конфиденциальные данные и работать с этими хешами.

password_hash() позволяет хешировать заданную строку самым сильным из доступных алгоритмом и password_verify() проверяет, что заданный пароль совпадает с сохранённым в БД хешем.

Пример #1 Хеширование полей с паролями

<?php

// Сохраняем хеш пароля
$query = sprintf("INSERT INTO users(name,pwd) VALUES('%s','%s');",
pg_escape_string($username),
password_hash($password, PASSWORD_DEFAULT));
$result = pg_query($connection, $query);

// проверка введённого пользователем пароля на корректность
$query = sprintf("SELECT pwd FROM users WHERE name='%s';",
pg_escape_string($username));
$row = pg_fetch_assoc(pg_query($connection, $query));

if (
$row && password_verify($password, $row['pwd'])) {
echo
'Добро пожаловать, ' . htmlspecialchars($username) . '!';
} else {
echo
'Ошибка авторизации, ' . htmlspecialchars($username) . '.';
}

?>


SQL-инъекции

SQL-инъекция - это техника, при которой злоумышленник использует недостатки в коде приложения, отвечающего за построение динамических SQL-запросов. Злоумышленник может получить доступ к привилегированным разделам приложения, получить всю информацию из базы данных, подменить существующие данные или даже выполнить опасные команды системного уровня на узле базы данных. Уязвимость возникает, когда разработчики конкатенируют или интерполируют произвольный ввод в SQL-запросах.

Пример #1 Постраничный вывод результата и создание суперпользователя в PostgreSQL

В следующем примере пользовательский ввод напрямую интерполируется в SQL-запрос, что позволяет злоумышленнику получить учётную запись суперпользователя в базе данных.

<?php

$offset
= $_GET['offset']; // осторожно, нет валидации ввода!
$query = "SELECT id, name FROM products ORDER BY name LIMIT 20 OFFSET $offset;";
$result = pg_query($conn, $query);
?>
Обычно пользователи нажимают по ссылкам 'вперёд' и 'назад', вследствие чего значение переменной $offset заносится в URL. Скрипт ожидает, что $offset - десятичное число. Однако, взломщик может попытаться взломать систему, присоединив к URL следующее значение:
0;
insert into pg_shadow(usename,usesysid,usesuper,usecatupd,passwd)
  select 'crack', usesysid, 't','t','crack'
  from pg_shadow where usename='postgres';
--
Если это произойдёт, скрипт предоставит злоумышленнику доступ суперпользователя. Обратите внимание, что значение 0; использовано для того, чтобы задать правильное смещение для первого запроса и корректно его завершить.

Замечание:

Это распространённый приём, чтобы заставить синтаксический анализатор SQL игнорировать остальную часть запроса, написанного разработчиком с помощью --, который является знаком комментария в SQL.

Ещё один вероятный способ получить пароли учётных записей в БД - атака страниц, предоставляющих поиск по базе. Злоумышленнику нужно лишь проверить, используется ли в запросе передаваемая на сервер и необрабатываемая надлежащим образом переменная. Это может быть один из устанавливаемых на предыдущей странице фильтров, таких как WHERE, ORDER BY, LIMIT и OFFSET, используемых при построении запросов SELECT. В случае, если используемая вами база данных поддерживает конструкцию UNION, злоумышленник может присоединить к оригинальному запросу ещё один дополнительный, для извлечения пользовательских паролей. Настоятельно рекомендуем использовать только зашифрованные пароли.

Пример #2 Листинг статей... и некоторых паролей (для любой базы данных)

<?php

$query
= "SELECT id, name, inserted, size FROM products
WHERE size = '
$size'";
$result = odbc_exec($conn, $query);
?>
Статическая часть запроса может комбинироваться с другим SELECT-запросом, который выведет все пароли:
'
union select '1', concat(uname||'-'||passwd) as name, '1971-01-01', '0' from usertable;
--

Выражения UPDATE и INSERT также подвержены таким атакам.

Пример #3 От сброса пароля до получения дополнительных привилегий (любой сервер баз данных)

<?php
$query
= "UPDATE usertable SET pwd='$pwd' WHERE uid='$uid';";
?>
Но злоумышленник может ввести значение ' or uid like'%admin%' для переменной $uid для изменения пароля администратора или просто присвоить переменной $pwd значение hehehe', trusted=100, admin='yes для получения дополнительных привилегий. При выполнении запросы переплетаются:
<?php

// $uid: ' or uid like '%admin%
$query = "UPDATE usertable SET pwd='...' WHERE uid='' or uid like '%admin%';";

// $pwd: hehehe', trusted=100, admin='yes
$query = "UPDATE usertable SET pwd='hehehe', trusted=100, admin='yes' WHERE
...;"
;
?>

Хотя остаётся очевидным, что для проведения успешной атаки злоумышленник должен обладать хотя бы некоторыми знаниями об архитектуре базы данных, получить эту информацию зачастую очень просто. Например, код может быть частью программного обеспечения с открытым исходным кодом и находиться в открытом доступе. Эта информация также может быть раскрыта закрытым кодом - даже если он закодирован, обфусцирован или скомпилирован, и даже вашим собственным кодом через отображение сообщений об ошибках. Другие методы включают использование типичных имён таблиц и столбцов. Например, форма входа в систему, использующая таблицу 'users' с именами столбцов 'id', 'username' и 'password'.

Пример #4 Атака на операционную систему сервера базы данных (MSSQL Server)

Пугающий пример того, как команды уровня операционной системы могут быть доступны на некоторых узлах баз данных.

<?php

$query
= "SELECT * FROM products WHERE id LIKE '%$prod%'";
$result = mssql_query($query);
?>
Если злоумышленник передаст значение a%' exec master..xp_cmdshell 'net user test testpass /ADD' -- в $prod, то $query будет:
<?php

$query
= "SELECT * FROM products
WHERE id LIKE '%a%'
exec master..xp_cmdshell 'net user test testpass /ADD' --%'"
;
$result = mssql_query($query);
?>
MSSQL Server выполняет SQL запросы в пакете, включая команду добавления нового пользователя в локальную базу данных учётных записей. Если бы это приложение было запущено от имени sa и служба MSSQLSERVER была запущена с достаточными привилегиями, у злоумышленника появилась бы учётная запись, с помощью которой он мог бы получить доступ к этой машине.

Замечание:

Некоторые примеры, приведённые выше, привязаны к конкретному серверу баз данных, но это не означает, что подобная атака невозможна на другие продукты. Ваш сервер баз данных может быть аналогично уязвим и другим способом.

Забавный пример проблем, связанных с SQL-инъекциями
Изображение любезно предоставлено » xkcd

Способы защиты

Рекомендуемый способ избежать SQL-инъекций - связывание всех данных с помощью подготовленных запросов. Использование подготовленных запросов недостаточно для полного предотвращения SQL-инъекций, но это самый простой и безопасный способ обеспечить ввод данных в SQL-запросы. Все динамические литералы данных в выражениях WHERE, SET и VALUES должны быть заменены заполнителями. Фактические данные будут связаны во время выполнения и отправлены отдельно от команды SQL.

Привязка параметров может использоваться только для данных. Другие динамические части SQL-запроса должны быть отфильтрованы по известному списку допустимых значений.

Пример #5 Избегание SQL-инъекций с помощью подготовленных операторов PDO

<?php

// Динамическая часть SQL проверяется на соответствие ожидаемым значениям
$sortingOrder = $_GET['sortingOrder'] === 'DESC' ? 'DESC' : 'ASC';
$productId = $_GET['productId'];

// SQL подготавливается с заполнителем
$stmt = $pdo->prepare("SELECT * FROM products WHERE id LIKE ? ORDER BY price {$sortingOrder}");

// Значение предоставляется с подстановочными знаками LIKE
$stmt->execute(["%{$productId}%"]);
?>

Подготовленные операторы предоставляются PDO, MySQLi, а также другими библиотеками баз данных.

Атаки SQL-инъекций в основном основаны на использовании кода, написанного без учёта требований безопасности. Никогда не доверяйте любому вводу, особенно со стороны клиента, даже если он поступает из поля выбора, скрытого поля ввода или cookie. Первый пример показывает, что такой простой запрос может привести к катастрофе.

Стратегия "защита в глубину" включает в себя несколько эффективных методов написания кода:

  • Никогда не подключайтесь к базе данных как суперпользователь или владелец базы данных. Всегда используйте настроенных пользователей с минимальными привилегиями.
  • Всегда проверяйте введённые данные на соответствие ожидаемому типу. В PHP есть множество функций для проверки данных: начиная от простейших функций для работы с переменными и функций определения типа символов (таких как is_numeric() и ctype_digit() соответственно) и заканчивая Perl-совместимыми регулярными выражениями.
  • В случае, если приложение ожидает цифровой ввод, примените функцию ctype_digit() для проверки введённых данных, или принудительно укажите их тип при помощи settype(), или просто используйте числовое представление при помощи функции sprintf().
  • Если на уровне базы данных не поддерживаются привязанные переменные, то всегда экранируйте любые нечисловые данные, используемый в запросах к БД при помощи специальных экранирующих функций, специфичных для используемой вами базы данных (например, mysql_real_escape_string(), sqlite_escape_string() и т.д.). Общие функции такие как addslashes() полезны только в определённых случаях (например MySQL в однобайтной кодировке с отключённым NO_BACKSLASH_ESCAPES), поэтому лучше избегать их использование.
  • Ни в коем случае не выводите никакой информации о БД, особенно о её структуре. Также ознакомьтесь с соответствующими разделами документации: "Сообщения об ошибках" и "Функции обработки и логирования ошибок".

Помимо всего вышесказанного, вы можете логировать запросы в вашем скрипте либо на уровне базы данных, если она это поддерживает. Очевидно, что логирование не может предотвратить нанесение ущерба, но может помочь при трассировке взломанного приложения. Лог-файл полезен не сам по себе, а информацией, которая в нем содержится. Причём, в большинстве случаев полезно логировать все возможные детали.




Сообщения об ошибках

С точки зрения безопасности вывод сообщений об ошибках несёт в себе как плюсы, так и минусы.

Одна из стандартных методик, применяемых в атаках - ввод некорректных данных с последующим анализом содержания и характера сообщений об ошибках. Это даёт взломщику возможность проверить скрипты и данные сервера на наличие потенциальных дыр. Например, если взломщик получил некоторую информацию о странице на основании отправки формы, он попробует предопределить некоторые передаваемые значения или модифицировать их:

Пример #1 Атака на переменные в HTML-странице

<form method="post" action="attacktarget?username=badfoo&amp;password=badfoo">
<input type="hidden" name="username" value="badfoo" />
<input type="hidden" name="password" value="badfoo" />
</form>

Возникающие во время работы скриптов ошибки являются достаточно ценной информацией для разработчика, содержащей такие данные, как функция или файл, а также номер строки, в которой возникла ошибка. Вся эта информация может быть использована для взлома. Для PHP-разработчика достаточно привычно пользоваться такими функциями, как show_source(), highlight_string() или highlight_file() в целях отладки, но на работающих сайтах это может открыть информацию о скрытых переменных, непроверенном синтаксисе и других потенциально опасных моментах. Особенно опасно наличие кода со встроенным механизмом отладки в публичных частях сайта. Взломщик может попытаться запустить отладочный механизм, подбирая основные признаки отладки:

Пример #2 Использование стандартных отладочных переменных

<form method="post" action="attacktarget?errors=Y&amp;showerrors=1&amp;debug=1">
<input type="hidden" name="errors" value="Y" />
<input type="hidden" name="showerrors" value="1" />
<input type="hidden" name="debug" value="1" />
</form>

Независимо от метода обработки ошибок возможность проверки системы на наличие ошибок снабжает взломщика дополнительной информацией.

Например, стандартный вывод об ошибке указывает операционную систему, в которой выполняются PHP-скрипты. Если взломщик анализирует обычную страницу сайта с расширением .html и пытается узнать систему, с помощью которой работает сайт (для дальнейшего поиска уязвимых мест), то подавая на ввод неверные данные он может обнаружить, что система использует PHP.

Также уведомление об ошибке может дать информацию об используемой базе данных, или, к примеру, как построена логика работы скриптов. Это, в свою очередь, может позволить взломщику подключиться к открытому порту базы данных, либо найти определённые ошибки в коде. Пробуя поочерёдно различные неверные блоки данных, злоумышленник может определить порядок аутентификации в скрипте (например, по номерам строк с ошибками) или проверять на наличие дыр различные участки кода.

Вывод стандартных ошибок или ошибок, связанных с файловой системой, может указать, с какими привилегиями запущен веб-сервер, и как организованы каталоги сайта. Обработка подобных ошибок, написанная разработчиками приложения, может только усугубить проблему, если взломщиком будет найден способ обнаружить "скрытую" отладочную информацию.

Существует три основных способа решения этой проблемы. Первый заключается в том, чтобы структурировать все функции и попытаться компенсировать объем выдаваемых ошибок. Второй способ - полностью отключить в работающем коде вывод сообщений об ошибках. И, наконец, третий способ - использовать специальные средства PHP для создания собственного обработчика ошибок. В зависимости от используемой вами политики безопасности вы можете применить в вашей конкретной ситуации все три способа.

Один из возможных способов обезопасить ваш код перед его публикацией в общий доступ - это использование функции PHP error_reporting(), которая может помочь выявить потенциально опасные переменные. Тестируя код перед выпуском релиза при помощи значения E_ALL, вы достаточно легко можете обнаружить участки кода, в которых переменные могут быть подменены либо модифицированы. После окончания тестирования, вы можете либо полностью отключить все сообщения об ошибках установив error_reporting() в 0, либо отключить их вывод с помощью директивы php.ini display_errors, изолировав таким образом ваш код от прощупывания. Если вы решили использовать последний способ, то необходимо также указать путь к лог-файлу с помощью директивы error_log и включить директиву log_errors.

Пример #3 Поиск потенциально опасных переменных при помощи E_ALL

<?php
if ($username) { // Переменная не инициализируется или не проверяется перед использованием
$good_login = 1;
}
if (
$good_login == 1) { // Если предыдущая проверка потерпела неудачу, переменная оказывается неинициализированной
readfile ("/highly/sensitive/data/index.html");
}
?>



Данные, введённые пользователем

Наиболее опасные уязвимости во многих PHP-скриптах возникают не столько из-за самого языка, сколько из-за кода, написанного без учёта соответствующих требований безопасности. Как следствие, вы всегда должны выделять время на исследование разрабатываемого участка кода, чтобы оценить потенциальную угрозу от ввода переменной с нестандартным значением.

Пример #1 Потенциально опасное использование переменных

<?php
// удалить файлы из домашней директории пользователя...
// а может, из ещё какой-нибудь?
unlink ($evil_var);

// записать в лог-файл выполняемое действие...
// а может быть в /etc/passwd?
fwrite ($fp, $evil_var);

// выполнение тривиальных действий... или rm -rf *?
system ($evil_var);
exec ($evil_var);

?>

Вы должны тщательно проверять ваш код и быть абсолютно уверены в том, что все данные, передаваемые веб-браузером, проверяются надлежащим образом. Попробуйте ответить для себя на следующие вопросы:

  • Будет ли данный скрипт воздействовать исключительно на предполагаемые данные?
  • Могут ли быть обработаны некорректные или нестандартные данные?
  • Возможно ли использование скрипта непредусмотренным способом?
  • Возможно ли его использование в сочетании с другими скриптами в негативных целях?
  • Будет ли каждая транзакция корректно логирована?

Ответив на эти вопросы во время написания скрипта, а не после, вы, возможно, предотвратите последующую доработку скрипта в целях повышения его безопасности. Начиная разработку с этих вопросов, вы не гарантируете полную безопасность вашей системы, но сможете значительно повысить её.

Вы также можете рассмотреть отключение таких конфигурационных опций, как register_globals, magic_quotes и некоторых других, которые могут приводить к сомнениям относительно происхождения или значения получаемых переменных. Использование при написании PHP-кода режима error_reporting(E_ALL) может помочь предупредить вас об использовании переменных до инициализации или проверки (что предотвратит работу с данными, отличными от ожидаемых).



Сокрытие PHP

В общем случае внесение неясности ненамного улучшает защищённость системы. Но бывают случаи, когда следует использовать малейшую возможность.

Несколько несложных методик могут помочь вам скрыть PHP, что усложняет работу потенциального взломщика, который пытается найти брешь в вашей системе. Установив опцию expose_php в off в конфигурационном файле php.ini, вы уменьшите количество доступной хакеру информации.

Ещё одна методика заключается в настройке веб-сервера таким образом, чтобы он обрабатывал файлы с различными расширениями как PHP-скрипты. Это можно указать как в .htaccess файлах, так и конфигурационном файле Apache. В таком случае вы сможете использовать при написании кода нестандартные расширения:

Пример #1 Маскировка PHP под другие языки программирования

# Теперь PHP-скрипты могут иметь те же расширения, что и другие языки программирования
AddType application/x-httpd-php .asp .py .pl
Или скрыть его совсем:

Пример #2 Использование неизвестных расширений для PHP-скриптов

# Теперь PHP-скрипты могут иметь неизвестные типы файлов
AddType application/x-httpd-php .bop .foo .133t
Также можно спрятать его под видом HTML-кода, что приведёт к потере производительности, так как все HTML-файлы будут обрабатываться PHP:

Пример #3 Маскировка PHP-файлов под HTML

# Теперь PHP-скрипты выглядят как обыкновенный HTML
AddType application/x-httpd-php .htm .html
Чтобы достичь желаемого эффекта, вы должны переименовать все ваши PHP-скрипты в соответствии с выбранным вами расширением. Описанное в этом разделе документации повышение безопасности через сокрытие является небольшой превентивной мерой при малых затратах.



Необходимость обновлений

PHP, как и любая другая большая система, постоянно проверяется и улучшается. Каждая новая версия содержит множество как существенных, так и мелких изменений, которые, в том числе, касаются повышения безопасности, расширения конфигурационных возможностей, а также стабильности вашей системы.

Как и в других программах и языках программирования, рекомендуется регулярно обновлять PHP и быть в курсе изменений, сделанных в последних версиях.




Отличительные особенности


HTTP-аутентификация в PHP

Возможно использовать функцию header() для отправки сообщения "Authentication Required" браузеру, заставив его показать окошко для ввода логина и пароля. Как только пользователь заполнит логин и пароль, ссылка, содержащая PHP-скрипт будет вызвана ещё раз с предопределёнными переменными PHP_AUTH_USER, PHP_AUTH_PW и AUTH_TYPE, установленными в логин, пароль и тип аутентификации соответственно. Эти предопределённые переменные хранятся в массиве $_SERVER. Поддерживаются только: "Basic" и "Digest". Подробнее смотрите функцию header().

Пример фрагмента скрипта, который вынуждает клиента авторизоваться для просмотра страницы:

Пример #1 Пример Basic HTTP-аутентификации

<?php
if (!isset($_SERVER['PHP_AUTH_USER'])) {
header('WWW-Authenticate: Basic realm="My Realm"');
header('HTTP/1.0 401 Unauthorized');
echo
'Текст, отправляемый в том случае,
если пользователь нажал кнопку Cancel'
;
exit;
} else {
echo
"<p>Hello {$_SERVER['PHP_AUTH_USER']}.</p>";
echo
"<p>Вы ввели пароль {$_SERVER['PHP_AUTH_PW']}.</p>";
}
?>

Пример #2 Пример Digest HTTP-аутентификации

Это пример реализации простого скрипта Digest HTTP-аутентификации. За подробностями обращайтесь к » RFC 2617.

<?php
$realm
= 'Запретная зона';

//user => password
$users = array('admin' => 'mypass', 'guest' => 'guest');


if (empty(
$_SERVER['PHP_AUTH_DIGEST'])) {
header('HTTP/1.1 401 Unauthorized');
header('WWW-Authenticate: Digest realm="'.$realm.
'",qop="auth",nonce="'.uniqid().'",opaque="'.md5($realm).'"');

die(
'Текст, отправляемый в том случае, если пользователь нажал кнопку Cancel');
}


// анализируем переменную PHP_AUTH_DIGEST
if (!($data = http_digest_parse($_SERVER['PHP_AUTH_DIGEST'])) ||
!isset(
$users[$data['username']]))
die(
'Неправильные данные!');


// генерируем корректный ответ
$A1 = md5($data['username'] . ':' . $realm . ':' . $users[$data['username']]);
$A2 = md5($_SERVER['REQUEST_METHOD'].':'.$data['uri']);
$valid_response = md5($A1.':'.$data['nonce'].':'.$data['nc'].':'.$data['cnonce'].':'.$data['qop'].':'.$A2);

if (
$data['response'] != $valid_response)
die(
'Неправильные данные!');

// все хорошо, логин и пароль верны
echo 'Вы вошли как: ' . $data['username'];


// функция разбора заголовка http auth
function http_digest_parse($txt)
{
// защита от отсутствующих данных
$needed_parts = array('nonce'=>1, 'nc'=>1, 'cnonce'=>1, 'qop'=>1, 'username'=>1, 'uri'=>1, 'response'=>1);
$data = array();
$keys = implode('|', array_keys($needed_parts));

preg_match_all('@(' . $keys . ')=(?:([\'"])([^\2]+?)\2|([^\s,]+))@', $txt, $matches, PREG_SET_ORDER);

foreach (
$matches as $m) {
$data[$m[1]] = $m[3] ? $m[3] : $m[4];
unset(
$needed_parts[$m[1]]);
}

return
$needed_parts ? false : $data;
}
?>

Замечание: Замечание касательно совместимости

Будьте особенно внимательны при указании HTTP-заголовков. Для того, чтобы гарантировать максимальную совместимость с наибольшим количеством различных клиентов, слово "Basic" должно быть написано с большой буквы "B", регион (realm) должен быть взят в двойные (не одинарные!) кавычки, и ровно один пробел должен предшествовать коду 401 в заголовке HTTP/1.0 401. Параметры аутентификации должны разделяться запятыми, как это было показано в примере Digest аутентификации выше.

Вместо простого отображения на экране переменных PHP_AUTH_USER и PHP_AUTH_PW, вам, возможно, понадобится проверить их корректность. Используйте для этого запрос к базе данных или поиск пользователя в dbm-файле.

Вы можете пронаблюдать особенности работы браузера Internet Explorer. Он очень требователен к параметру передаваемых заголовков. Трюк с указанием заголовка WWW-Authenticate перед отправкой статуса HTTP/1.0 401 пока что работает для него.

Замечание: Замечание касательно конфигурации

PHP использует указание директивы AuthType для указания того, используется внешняя аутентификация или нет.

Следует заметить, что все вышесказанное не предотвращает похищения паролей к страницам, требующим авторизацию, кем-либо, кто контролирует страницы без авторизации, расположенные на том же сервере.

И Netscape Navigator и Internet Explorer очищают кеш аутентификации текущего окна для заданного региона (realm) при получении от сервера статуса 401. Это может использоваться для реализации принудительного выхода пользователя и повторного отображения диалогового окна для ввода имени пользователя и пароля. Некоторые разработчики используют это для ограничения авторизации по времени или для предоставления кнопки "Выход".

Пример #3 Пример HTTP-аутентификации с принудительным вводом новой пары логин/пароль

<?php
function authenticate() {
header('WWW-Authenticate: Basic realm="Test Authentication System"');
header('HTTP/1.0 401 Unauthorized');
echo
"Вы должны ввести корректный логин и пароль для получения доступа к ресурсу \n";
exit;
}

if (!isset(
$_SERVER['PHP_AUTH_USER']) ||
(
$_POST['SeenBefore'] == 1 && $_POST['OldAuth'] == $_SERVER['PHP_AUTH_USER'])) {
authenticate();
} else {
echo
"<p>Добро пожаловать: " . htmlspecialchars($_SERVER['PHP_AUTH_USER']) . "<br />";
echo
"Предыдущий логин: " . htmlspecialchars($_REQUEST['OldAuth']);
echo
"<form action='' method='post'>\n";
echo
"<input type='hidden' name='SeenBefore' value='1' />\n";
echo
"<input type='hidden' name='OldAuth' value=\"" . htmlspecialchars($_SERVER['PHP_AUTH_USER']) . "\" />\n";
echo
"<input type='submit' value='Авторизоваться повторно' />\n";
echo
"</form></p>\n";
}
?>

Это поведение не регламентируется стандартами HTTP Basic-аутентификации, следовательно, вы не должны зависеть от этого. Тестирование браузера Lynx показало, что Lynx не очищает кеш авторизации при получении от сервера статуса 401, и, нажав последовательно "Back", а затем "Forward" возможно открыть такую страницу, при условии, что требуемые атрибуты авторизации не изменились. Однако, пользователь может нажать клавишу '_' для очистки кеша аутентификации.

Для того, чтобы добиться корректной работы HTTP-аутентификации в IIS сервере с CGI версией PHP, вы должны отредактировать конфигурационную настройку IIS под названием "Directory Security". Щёлкните на надписи "Edit" и установите опцию "Anonymous Access", все остальные поля должны остаться неотмеченными.

Замечание: Замечание касательно IIS:
Для того, чтобы HTTP-аутентификация корректно работала в IIS, в конфигурации PHP-опция cgi.rfc2616_headers должна быть установлена значением 0 (значение по умолчанию).



Cookies

PHP прозрачно поддерживает HTTP cookies. Cookies - это механизм хранения данных браузером удалённой машины для отслеживания или идентификации возвращающихся посетителей. Вы можете установить cookies при помощи функций setcookie() или setrawcookie(). Cookies являются частью HTTP-заголовка, поэтому setcookie() должна вызываться до любого вывода данных в браузер. Это то же самое ограничение, которое имеет функция header(). Вы можете использовать функции буферизации вывода, чтобы задержать вывод результатов работы скрипта до того момента, когда будет известно, понадобится ли установка cookies или других заголовков.

Любые cookies, отправленные серверу браузером клиента, будут автоматически включены в суперглобальный массив $_COOKIE, если директива variables_order содержит букву "C". Для назначения нескольких значений одной cookie, просто добавьте [] к её имени.

Дополнительная информация, в том числе и особенности реализации браузеров, приведена в описании функций setcookie() и setrawcookie().



Сессии

Сессии PHP представляют собой различные способы сохранения данных для дальнейшего доступа к ним. Они позволяют создавать более гибкие приложения и улучшают привлекательность вашего сайта. Подробная информация находится в справочнике сессий.



Работа с XForms

» XForms являются альтернативой традиционным веб-формам, и позволяют использовать их на множестве платформ и браузеров, а также реализовывать нестандартные представления форм, например, в виде PDF-документа.

Первое существенное отличие XForms заключается в том, как форма отсылается клиенту. Руководство » XForms for HTML Authors содержит детальное описание создания XForms. Для того, чтобы очертить основную идею руководства, приведём несколько простых примеров.

Пример #1 Простая поисковая форма XForms

<h:html xmlns:h="http://www.w3.org/1999/xhtml"
        xmlns="http://www.w3.org/2002/xforms">
<h:head>
 <h:title>Поиск</h:title>
 <model>
  <submission action="http://example.com/search"
              method="post" id="s"/>
 </model>
</h:head>
<h:body>
 <h:p>
  <input ref="q"><label>Что искать?</label></input>
  <submit submission="s"><label>Найти</label></submit>
 </h:p>
</h:body>
</h:html>

Приведённая выше форма отображает текстовое поле для ввода (названное q) и кнопку для отправки формы, при нажатии на которую все введённые данные будут отправлены скрипту, указанному в поле action.

Тут мы подошли к ещё одному существенному различию с точки зрения вашего веб-приложения. Стандартная HTML-форма отправляет данные как application/x-www-form-urlencoded, а XForms для передачи данных использует разметку XML.

Если вы решили работать с XForms, скорее всего вы захотите получить отправленные пользователем данные в формате XML. В таком случае обратите внимание на переменную $HTTP_RAW_POST_DATA, в ней содержится XML-документ, сгенерированный браузером, который в дальнейшем можно обработать предпочитаемым вами движком XSLT или парсером документа.

Если разметка вас не интересует, и вы хотите, чтобы передаваемые данные были помещены в стандартный массив $_POST, вы можете указать клиентскому браузеру на необходимость отправлять данные в формате application/x-www-form-urlencoded. Для этого установите атрибут method значением urlencoded-post.

Пример #2 Использование XForm совместно с массивом $_POST

<h:html xmlns:h="http://www.w3.org/1999/xhtml"
        xmlns="http://www.w3.org/2002/xforms">
<h:head>
 <h:title>Поиск</h:title>
 <model>
  <submission action="http://example.com/search"
              method="urlencoded-post" id="s"/>
 </model>
</h:head>
<h:body>
 <h:p>
  <input ref="q"><label>Что искать?</label></input>
  <submit submission="s"><label>Найти</label></submit>
 </h:p>
</h:body>
</h:html>

Замечание: В дополнение к вышесказанному следует заметить, что большое количество браузеров не поддерживают XForms. Если приведённые примеры потерпели неудачу, проверьте версию используемого вами браузера.



Загрузка файлов на сервер

Содержание


Загрузка файлов методом POST

Данная возможность позволяет загружать как текстовые, так и бинарные файлы. С помощью PHP-функций аутентификации и работы с файлами вы имеете полный контроль над тем, кому разрешено загружать файлы и что делать с файлом после его загрузки.

PHP способен получать загруженные файлы из любого браузера, совместимого со стандартом RFC-1867.

Замечание: Смежные замечания по конфигурации

Также ознакомьтесь с описанием директив file_uploads, upload_max_filesize, upload_tmp_dir, post_max_size и max_input_time конфигурационного файла php.ini

Также следует заметить, что PHP поддерживает загрузку файлов методом PUT, который используется в клиентах Netscape Composer и W3C Amaya. Для получения более детальной документации обратитесь к разделу поддержка метода PUT.

Пример #1 Форма для загрузки файлов

Страница для загрузки файлов может быть реализована при помощи специальной формы, которая выглядит примерно так:

<!-- Тип кодирования данных, enctype, ДОЛЖЕН БЫТЬ указан ИМЕННО так -->
<form enctype="multipart/form-data" action="__URL__" method="POST">
    <!-- Поле MAX_FILE_SIZE должно быть указано до поля загрузки файла -->
    <input type="hidden" name="MAX_FILE_SIZE" value="30000" />
    <!-- Название элемента input определяет имя в массиве $_FILES -->
    Отправить этот файл: <input name="userfile" type="file" />
    <input type="submit" value="Отправить файл" />
</form>

В приведённом выше примере __URL__ необходимо заменить ссылкой на PHP-скрипт.

Скрытое поле MAX_FILE_SIZE (значение необходимо указывать в байтах) должно предшествовать полю для выбора файла, и его значение является максимально допустимым размером принимаемого файла в PHP. Рекомендуется всегда использовать эту переменную, так как она предотвращает тревожное ожидание пользователей при передаче огромных файлов, только для того, чтобы узнать, что файл слишком большой и передача фактически не состоялась. Имейте в виду, что обойти это ограничение на стороне браузера достаточно просто, следовательно, вы не должны полагаться на то, что все файлы большего размера будут блокированы при помощи этой возможности. Это по большей части удобная возможность для пользователей клиентской части вашего приложения. Однако настройки PHP (на сервере) касательно максимального размера обойти невозможно.

Замечание:

Также следует убедиться, что форма загрузки имеет атрибут enctype="multipart/form-data", в противном случае загрузка файлов на сервер не произойдёт.

Глобальный массив $_FILES содержит всю информацию о загруженных файлах. Его содержимое для нашего примера приводится ниже. Обратите внимание, что здесь предполагается использование имени userfile для поля выбора файла, как и в приведённом выше примере. На самом деле имя поля может быть любым.

$_FILES['userfile']['name']

Оригинальное имя файла на компьютере клиента.

$_FILES['userfile']['type']

Mime-тип файла, в случае, если браузер предоставил такую информацию. В качестве примера можно привести "image/gif". Этот mime-тип не проверяется на стороне PHP, так что не полагайтесь на его значение без проверки.

$_FILES['userfile']['size']

Размер в байтах принятого файла.

$_FILES['userfile']['tmp_name']

Временное имя, с которым принятый файл был сохранён на сервере.

$_FILES['userfile']['error']

Код ошибки, которая может возникнуть при загрузке файла.

$_FILES['userfile']['full_path']

Полный путь, представленный браузером. Это значение не всегда содержит реальную структуру каталогов и ему нельзя доверять. Доступно, начиная с PHP 8.1.0.

По умолчанию принятые файлы сохраняются на сервере в стандартной временной папке до тех пор, пока не будет задана другая директория при помощи директивы upload_tmp_dir конфигурационного файла php.ini. Директорию сервера по умолчанию можно сменить, установив переменную TMPDIR для окружения, в котором выполняется PHP. Установка этой переменной при помощи функции putenv() внутри PHP-скрипта работать не будет. Эта переменная окружения также может использоваться для того, чтобы удостовериться, что другие операции также работают с принятыми файлами.

Пример #2 Проверка загружаемых на сервер файлов

Для получения более детальной информации вы можете ознакомиться с описанием функций is_uploaded_file() и move_uploaded_file(). Следующий пример принимает и обрабатывает загруженный при помощи формы файл.

<?php
$uploaddir
= '/var/www/uploads/';
$uploadfile = $uploaddir . basename($_FILES['userfile']['name']);

echo
'<pre>';
if (
move_uploaded_file($_FILES['userfile']['tmp_name'], $uploadfile)) {
echo
"Файл корректен и был успешно загружен.\n";
} else {
echo
"Возможная атака с помощью файловой загрузки!\n";
}

echo
'Некоторая отладочная информация:';
print_r($_FILES);

print
"</pre>";

?>

PHP-скрипт, принимающий загруженный файл, должен реализовывать логику, необходимую для определения дальнейших действий над принятым файлом. Например, вы можете проверить переменную $_FILES['userfile']['size'], чтобы отсечь слишком большие или слишком маленькие файлы. Также вы можете использовать переменную $_FILES['userfile']['type'] для исключения файлов, которые не удовлетворяют критерию касательно типа файла, однако, принимайте во внимание, что это поле полностью контролируется клиентом, используйте его только в качестве первой из серии проверок. Также вы можете использовать $_FILES['userfile']['error'] и коды ошибок при реализации вашей логики. Независимо от того, какую модель поведения вы выбрали, вы должны удалить файл из временной папки или переместить его в другую директорию.

В случае, если при отправке формы файл выбран не был, PHP установит переменную $_FILES['userfile']['size'] значением 0, а переменную $_FILES['userfile']['tmp_name'] - none.

По окончанию работы скрипта, если загруженный файл не был переименован или перемещён, он будет автоматически удалён из временной папки.

Пример #3 Загрузка массива файлов

PHP поддерживает возможность передачи массива из HTML в том числе и с файлами.

<form action="" method="post" enctype="multipart/form-data">
<p>Изображения:
<input type="file" name="pictures[]" />
<input type="file" name="pictures[]" />
<input type="file" name="pictures[]" />
<input type="submit" value="Отправить" />
</p>
</form>
<?php
foreach ($_FILES["pictures"]["error"] as $key => $error) {
if (
$error == UPLOAD_ERR_OK) {
$tmp_name = $_FILES["pictures"]["tmp_name"][$key];
// basename() может спасти от атак на файловую систему;
// может понадобиться дополнительная проверка/очистка имени файла
$name = basename($_FILES["pictures"]["name"][$key]);
move_uploaded_file($tmp_name, "data/$name");
}
}
?>

Полоса прогресса загрузки файлов может быть реализована с помощью "отслеживания прогресса загрузки файлов с помощью сессий".



Объяснение сообщений об ошибках

PHP возвращает код ошибки наряду с другими атрибутами принятого файла. Он расположен в массиве, создаваемом PHP при загрузке файла, и может быть получен при обращении по ключу error. Другими словами, код ошибки можно найти в $_FILES['userfile']['error'].

UPLOAD_ERR_OK

Значение: 0; Ошибок не возникло, файл был успешно загружен на сервер.

UPLOAD_ERR_INI_SIZE

Значение: 1; Размер принятого файла превысил максимально допустимый размер, который задан директивой upload_max_filesize конфигурационного файла php.ini.

UPLOAD_ERR_FORM_SIZE

Значение: 2; Размер загружаемого файла превысил значение MAX_FILE_SIZE, указанное в HTML-форме.

UPLOAD_ERR_PARTIAL

Значение: 3; Загружаемый файл был получен только частично.

UPLOAD_ERR_NO_FILE

Значение: 4; Файл не был загружен.

UPLOAD_ERR_NO_TMP_DIR

Значение: 6; Отсутствует временная папка.

UPLOAD_ERR_CANT_WRITE

Значение: 7; Не удалось записать файл на диск.

UPLOAD_ERR_EXTENSION

Значение: 8; Модуль PHP остановил загрузку файла. PHP не предоставляет способа определить, какой модуль остановил загрузку файла; в этом может помочь просмотр списка загруженных модулей с помощью phpinfo().



Наиболее распространённые ошибки

Опция MAX_FILE_SIZE не должна позволять передачу файлов, размер которых превышает лимит, установленный конфигурационной директивой upload_max_filesize в php.ini. Ограничение по умолчанию составляет 2 мегабайта.

В случае, если установлены ограничения памяти, вам может понадобиться увеличить значение опции memory_limit. Убедитесь в том, что значение memory_limit достаточно велико.

В случае, если опция max_execution_time установлена слишком маленьким значением, необходимое время работы скрипта может превышать это значение. Убедитесь в том, что значение max_execution_time достаточно велико.

Замечание: Директива max_execution_time касается исключительно времени, используемого непосредственно самим скриптом. Время, потраченное на внешние действия, такие как системные вызовы при помощи функции system() или sleep(), обращения к базе данных, а также время, потраченное на загрузку файла и другие действия, происходящие вне скрипта, не учитываются при определении максимально допустимого промежутка времени, отведённого для выполнения скрипта.

Внимание

Директива max_input_time указывает максимально допустимое время в секундах для получения входящих данных, в том числе и загружаемых файлов. В случае, если вы имеете дело с несколькими или большими файлами, либо удалённые пользователи используют медленный канал, ограничение по умолчанию в 60 секунд может быть превышено.

Если директива post_max_size слишком мала, большие файлы не смогут быть загружены на сервер. Убедитесь, что значение директивы post_max_size достаточно велико.

Опция max_file_uploads контролирует максимальное количество загружаемых файлов в течение одного запроса. Если загружается большее количество файлов, чем указано в этом ограничении, то массив $_FILES прекратит дальнейшую обработку файлов по достижении этого ограничения. Например, если max_file_uploads установлено в 10, то $_FILES никогда не будет содержать больше 10 элементов.

Если не проверять, с какими файлами вы работаете, пользователи могут получить доступ к конфиденциальной информации, расположенной в других директориях.

Поскольку разные системы по-разному работают с файловой структурой, нет никаких гарантий того, что файлы с экзотическими именами (например, которые содержат пробельные символы) будут обработаны корректно.

Разработчики не должны использовать одинаковые имена для обычных полей ввода (тег input) и полей выбора файла в пределах одной и той же формы (например, используя имя для тега input наподобие foo[]).



Загрузка нескольких файлов

Загрузку нескольких файлов можно реализовать используя, например, различные значения name для тега input.

Также можно одновременно загружать несколько файлов и автоматически получить их в виде массива. Для реализации такой возможности используйте тот же синтаксис массива в HTML-форме, что и для множественных полей select и checkbox:

Пример #1 Загрузка нескольких файлов

<form action="file-upload.php" method="post" enctype="multipart/form-data">
  Файлы:<br />
  <input name="userfile[]" type="file" /><br />
  <input name="userfile[]" type="file" /><br />
  <input type="submit" value="Отправить" />
</form>

В случае, если такая форма была отправлена, массивы $_FILES['userfile'], $_FILES['userfile']['name'], и $_FILES['userfile']['size'] будут инициализированы.

Например, предположим, что были загружены файлы /home/test/review.html и /home/test/xwp.out. В таком случае переменная $_FILES['userfile']['name'][0] будет установлена значением review.html, а переменная $_FILES['userfile']['name'][1] - значением xwp.out. Аналогично, переменная $_FILES['userfile']['size'][0] будет содержать размер файла review.html и так далее.

Переменные $_FILES['userfile']['name'][0], $_FILES['userfile']['tmp_name'][0], $_FILES['userfile']['size'][0] и $_FILES['userfile']['type'][0] также будут инициализированы.

Внимание

Конфигурационная директива max_file_uploads регулирует лимит одновременно загружаемых файлов в течение одного запроса. Вам необходимо будет убедиться, что ваша форма не пытается загрузить файлов больше этого лимита за один запрос.

Пример #2 Загрузка всего каталога

В полях загрузки HTML-файла можно загрузить весь каталог с помощью атрибута webkitdirectory. Он поддерживается большинством современных браузеров.

С помощью информации full_path можно сохранить относительные пути или восстановить тот же каталог на сервере.

<form action="file-upload.php" method="post" enctype="multipart/form-data">
  Загрузка каталога:<br />
  <input name="userfile[]" type="file" webkitdirectory multiple />
  <input type="submit" value="Загрузить файлы" />
</form>
Внимание

Атрибут webkitdirectory нестандартен и не входит в стандартную поставку. Не используйте его на рабочих сайтах: он работает не у всех пользователей. Между реализациями также может быть большая несовместимость, также поведение может измениться в будущем.

PHP анализирует только информацию об относительном пути, отправленную браузером/пользовательским агентом и передаёт эту информацию в массив $_FILES. Нет никакой гарантии, что значения в массиве full_path содержат реальную структуру каталогов и приложение PHP не должно доверять этой информации.



Поддержка метода PUT

PHP поддерживает загрузку файлов методом HTTP PUT, который используется в некоторых клиентах для загрузки файлов на сервер. Запросы PUT намного проще, чем загрузка файла с использованием POST-запросами и выглядят примерно так:

PUT /path/filename.html HTTP/1.1

Такой вызов означает, что удалённый клиент хотел бы сохранить файл под именем /path/filename.html в дереве каталогов вашего веб-сервера. Очевидно, что возможность клиента автоматически перезаписывать файлы веб-сервера при помощи Apache или PHP не является хорошим решением. Поэтому для того, чтобы обрабатывать такие запросы, вам необходимо указать веб-серверу PHP-скрипт, которому вы доверяете их обработку. В веб-сервере Apache вы можете сделать это, используя директиву Script. Как правило, эта директива расположена внутри блока <Directory> или же внутри блока <VirtualHost>. Сама запись выглядит следующим образом:

Script PUT /put.php

Это указывает веб-серверу Apache на необходимость перенаправлять все PUT-запросы, контекст которых совпадает с контекстом, в которым вы разместили эту строку, в файл put.php. Предполагается, что файлы с расширением .php обрабатываются, как PHP-скрипты, и что сам PHP установлен и работает. Ресурсом назначения для всех PUT-запросов на этот скрипт должен быть сам скрипт, а не имя файла, которое должен иметь загружаемый файл.

Внутри вашего файла put.php вы можете поместить что-нибудь похожее на следующий пример. Он скопирует содержимое загруженного файла в файл myputfile.ext на сервер. Возможно, вам понадобится осуществить несколько проверок и/или аутентифицировать пользователя перед выполнением копирования этого файла.

Пример #1 Сохранение файлов, отправленных через HTTP PUT

<?php
/* PUT данные приходят в потоке ввода stdin */
$putdata = fopen("php://input", "r");

/* Открываем файл на запись */
$fp = fopen("myputfile.ext", "w");

/* Читаем 1 KB данных за один раз
и пишем в файл */
while ($data = fread($putdata, 1024))
fwrite($fp, $data);

/* Закрываем потоки */
fclose($fp);
fclose($putdata);
?>





Работа с удалёнными файлами

В случае, если опция allow_url_fopen включена в конфигурационном файле php.ini, вы можете использовать URL-адреса HTTP и FTP в большинстве функций, принимающих в качестве параметра имя файла. Также вы можете использовать ссылки в операторах include, include_once, require и require_once (для корректной работы этих функций должна быть включена опция allow_url_include). Дополнительную информацию о поддерживаемых в PHP протоколах вы можете найти в Поддерживаемые протоколы и обёртки.

Например, вы можете использовать это для того, чтобы открыть файл на удалённом сервере, извлечь необходимые вам данные и использовать их в запросе к базе данных или же просто отобразить их в дизайне вашего сайта.

Пример #1 Получение заголовка удалённой страницы

<?php
$file
= fopen ("http://www.example.com/", "r");
if (!
$file) {
echo
"<p>Невозможно открыть удалённый файл.\n";
exit;
}
while (!
feof ($file)) {
$line = fgets ($file, 1024);
/* Сработает, только если заголовок и сопутствующие теги расположены в одной строке */
if (preg_match ("@\<title\>(.*)\</title\>@i", $line, $out)) {
$title = $out[1];
break;
}
}
fclose($file);
?>

Вы также можете работать с удалёнными файлами, расположенными на FTP-сервере (подразумевается, что вы авторизовались с необходимыми для этого привилегиями). Таким образом вы можете только создавать новые файлы, но попытка перезаписать существующий файл при помощи функции fopen() приведёт к ошибке.

Для того, чтобы авторизоваться под пользователем, отличным от 'anonymous', вам необходимо указать логин (и, возможно, пароль) в адресной строке, например так: 'ftp://user:password@ftp.example.com/path/to/file'. (Вы можете использовать этот же синтаксис для доступа к удалённым файлам по HTTP-протоколу, если необходима Basic-аутентификация.)

Пример #2 Сохранение данных на удалённом сервере

<?php
$file
= fopen ("ftp://ftp.example.com/incoming/outputfile", "w");
if (!
$file) {
echo
"<p>Невозможно перезаписать удалённый файл.\n";
exit;
}
/* Запись данных. */
fwrite ($file, $_SERVER['HTTP_USER_AGENT'] . "\n");
fclose ($file);
?>

Замечание:

Глядя на приведённый выше пример, у вас может возникнуть идея использовать эту технику для ведения удалённого лог-файла. К сожалению, это нереализуемо, поскольку попытка записи в уже существующий удалённый файл при помощи функции fopen() приведёт к ошибке. В реализации распределённого логирования, возможно, вам поможет функция syslog().



Работа с соединениями

Статус соединения сохраняется внутренними механизмами PHP. Ниже перечислены четыре возможные состояния:

  • 0 - NORMAL
  • 1 - ABORTED
  • 2 - TIMEOUT
  • 3 - ABORTED и TIMEOUT

Во время штатного выполнения PHP-скрипта установлен статус NORMAL. В случае, если удалённый клиент разорвал соединение, статус изменяется на ABORTED. Чаще всего отсоединение удалённого клиента происходит при нажатии кнопки "Stop" в браузере. В случае, если достигается установленный временной лимит (ознакомьтесь с функцией set_time_limit()), будет установлен статус TIMEOUT.

Вы можете решать, приводит ли отключение клиента к завершению вашего скрипта. Иногда бывает необходимо, чтобы скрипт выполнился до конца, даже если отсутствует удалённый браузер, которому адресован весь вывод. По умолчанию скрипт завершает свою работу при отключении клиента. Это поведение может быть изменено при помощи опции ignore_user_abort в конфигурационном файле php.ini. Такого же результата можно добиться, указав php_value ignore_user_abort в конфигурационном файле Apache httpd.conf или воспользовавшись функцией ignore_user_abort(). Если вы явно не указали на необходимость игнорировать разрыв соединения с клиентом, выполнение скрипта будет прервано. Исключением является тот случай, если используя register_shutdown_function(), вы указали специальную функцию, вызываемую при завершении скрипта. В таком случае после того, как пользователь нажал кнопку "Stop" в своём браузере, при первой же попытке что-либо вывести PHP обнаруживает, что соединение с клиентом было утеряно, и вызывает завершающую функцию. Эта функция также вызывается при нормальном завершении работы вашего скрипта, поэтому для того, чтобы выполнить некоторые специфические действия при отсоединении клиента, вам понадобится функция connection_aborted(), которая возвращает true, если соединение было разорвано.

Выполнение вашего скрипта также может быть прервано встроенным таймером. Стандартное ограничение по времени составляет 30 секунд, изменить его можно при помощи директивы max_execution_time в конфигурационном файле php.ini. Такого же результата можно достичь, добавив php_value max_execution_time в конфигурационный файл Apache httpd.conf или воспользовавшись функцией set_time_limit(). При достижении скриптом временного лимита выполнение скрипта прерывается и вызывается завершающая функция, если она была указана. Уточнить причину завершения скрипта вы можете при помощи функции connection_status(), которая возвращает 2, если скрипт был прерван по достижению временного ограничения.

Единственное, что следует заметить - что оба статуса: ABORTED и TIMEOUT, - могут быть установлены одновременно. Это может произойти в том случае, если вы явно указали необходимость игнорировать отсоединение удалённого клиента. В таком случае после разрыва соединения, отметив этот факт, PHP продолжит выполнение скрипта, и при достижении временного лимита будет вызвана завершающая функция, если таковая была указана. В этой точке вы можете обнаружить, что connection_status() вернёт значение 3.



Постоянные соединения с базами данных

Постоянные соединения представляют собой связи с базами данных, которые не закрываются при завершении скрипта. При получении запроса на постоянное соединение PHP вначале проверяет, имеется ли идентичное постоянное соединение (которое было открыто при предыдущих обращениях) и, если таковое было найдено, использует его. В случае, если идентичного соединения нет, PHP создаёт новое. Под "идентичным" подразумевается соединение, открытое на том же хосте с таким же именем пользователя и паролем (если они указаны).

Та часть разработчиков, которая не имеет чёткого представления о том, как работает веб-сервер и как распределяется нагрузка, могут получить ошибочное представление о том, чем на самом деле являются постоянные соединения. В частности, постоянные соединения не предоставляют возможность открывать 'пользовательские сессии' в том же самом соединении, они не предоставляют возможность организовывать более эффективные транзакции, также они не предоставляют множества других полезных возможностей. Фактически, постоянные соединения не предоставляют никакой функциональности, которая была бы невозможна в непостоянных аналогичных соединениях.

Почему?

Это зависит от того, как происходит взаимодействие с веб-сервером. Существует три основных способа использования PHP сервером для генерации веб-страниц.

Первый способ заключается в том, чтобы использовать PHP как CGI-обёртку. При этом PHP-интерпретатор создаётся и уничтожается при каждом обращении к странице (PHP-скрипту). Поскольку интерпретатор уничтожается после каждого запроса к серверу, все используемые им ресурсы (в том числе и соединение с базой данных) закрываются. Следовательно, в этом случае вы не получите ничего от использования постоянных соединений - их просто нет.

Второй, и наиболее популярный способ - использовать PHP как модуль в сервере, который использует несколько процессов. В число таких серверов сейчас входит только Apache. В таком случае, можно выделить один процесс (родительский), который координирует работу всех остальных процессов (дочерних), которые фактически и выполняют работу по обслуживанию веб-страниц. При каждом обращении клиента к серверу запрос перенаправляется одному из дочерних процессов, который в данный момент не занят обслуживанием другого клиента. Это означает, что когда тот же самый клиент выполняет повторный запрос к серверу, он может быть обработан другим дочерним процессом, отличным от того, который был при первом обращении. После открытия постоянного соединения каждая последующая страница, требующая соединения с базой данных, может использовать уже установленное ранее соединение с SQL-сервером.

Третий способ - использовать PHP в качестве плагина в многопоточном веб-сервере. В настоящее время в PHP реализована поддержка ISAPI, WSAPI, и NSAPI (для Windows-платформ), которые позволяют подключать PHP к таким многопоточным серверам, как Netscape FastTrack (iPlanet), Microsoft's Internet Information Server (IIS) и O'Reilly WebSite Pro. В этом случае поведение PHP полностью аналогично рассмотренной ранее модели с использованием нескольких процессов.

Если постоянные соединения не предоставляют никакой дополнительной функциональности, чем же они тогда так хороши?

Ответ содержится в повышении эффективности. Постоянные соединения полезны в том случае, если при открытии большого количества SQL-соединений возникает ощутимая нагрузка на сервер. То, насколько велика эта нагрузка, зависит от многих факторов. Например, от того, какая именно база данных используется, находится ли она на том же компьютере что и ваш веб-сервер, насколько загружена машина, на которой установлен SQL-сервер, и так далее. В случае, если затраты на установку соединения велики, постоянные соединения могут вам существенно помочь. Они позволяют дочернему процессу на протяжении всего жизненного цикла использовать одно и то же соединение вместо того, чтобы создавать его при обработке каждой страницы, которая взаимодействует с SQL-сервером. Это означает, что каждый дочерний процесс, открывший постоянное соединение, будет иметь своё собственное соединение с сервером. Например, если у вас запущено 20 дочерних процессов, которые выполнили скрипт, использовавший постоянное соединение с SQL-сервером, вы получите 20 различных соединений с SQL-сервером, по одному на каждый дочерний процесс.

Следует заметить, что этот подход имеет некоторые недостатки: если вы используете базу данных с ограниченным количеством возможных подключений, оно может быть превышено количеством запрашиваемых дочерними процессами постоянных соединений. Например, если ваша база данных позволяет 16 одновременных соединений, и во время нагрузки на сервер 17 дочерних процессов попробуют открыть соединение, одна из попыток потерпит неудачу. Если в вашем коде содержатся ошибки, не позволяющие закрывать соединение (например, бесконечные циклы), база данных с 32 одновременными подключениями вскоре может оказаться заблокированной. Информацию о том, как обрабатывать открытые и неиспользуемые соединения, вы можете найти в документации к вашей базе данных.

Внимание

Есть ещё два дополнительных предостережения, которые следует помнить при работе с постоянными соединениями. В случае, если скрипт блокирует таблицу и по каким-либо причинам не может её освободить, при использовании постоянного соединения все последующие скрипты, которые используют это соединение будут блокированы бесконечно долго и могут потребовать рестарта веб-сервера или сервера баз данных. Второе предостережение заключается в том, что открытые транзакции, если они не были закрыты до завершения работы скрипта, будут продолжены в следующем скрипте, использующем это же постоянное соединение. Исходя из этого, вы можете использовать функцию register_shutdown_function() для указания простой функции, которая снимает блокировку таблиц или отката ваших транзакций. Ещё лучше избежать этих проблем полностью, не используя постоянные соединения в скриптах, которые используют блокировку таблиц или транзакции (при этом вы всё ещё можете использовать их где-то в другом месте).

Важное резюме. Постоянные соединения были созданы для точного отображения обыкновенных соединений. Это означает, что у вас всегда есть возможность заменить все постоянные соединения непостоянными, и это никак не отразится на поведении скрипта. Такая замена может повлиять (и, наверное, повлияет) на эффективность работы скрипта, но никак не на его поведение.

Смотрите также ibase_pconnect(), ociplogon(), odbc_pconnect(), oci_pconnect(), pfsockopen() и pg_pconnect().



Использование PHP в командной строке

Содержание


Введение

Основная цель этого CLI SAPI - разработка консольных приложений на PHP. Имеется довольно много различий между CLI SAPI и другими видами SAPI, которые будут рассмотрены в этой главе. Стоит отметить, что CLI SAPI и CGI - различные SAPI-интерфейсы, хотя в их поведении много общего.

CLI SAPI включается по умолчанию с помощью опции --enable-cli, но может быть выключен опцией --disable-cli при запуске ./configure.

Имя, расположение и существование бинарных модулей CLI/CGI зависит от того, как именно установлен PHP в вашей системе. По умолчанию при выполнении make создаётся как CGI-, так и CLI-модуль, размещённые в директориях sapi/cgi/php-cgi и sapi/cli/php соответственно, внутри директории с исходниками PHP. Следует заметить, что оба файла имеют одинаковое название: php. Что произойдёт при выполнении make install, зависит от того, какие опции вы указали на стадии конфигурирования. Если выбран модуль SAPI во время выполнения, например, apxs, или используется опция опция --disable-cgi, модуль CLI будет скопирован в {PREFIX}/bin/php при выполнении make install, в противном случае будет скопирован CGI-модуль. Например, если задана опция --with-apxs, то при выполнении make install CLI-версия будет скопирована в {PREFIX}/bin/php. Если вы хотите переопределить установку CGI-модуль, используйте make install-cli после выполнения make install. В качестве альтернативы вы могли бы указать опцию --disable-cgi в строке конфигурации.

Замечание:

Поскольку обе опции, --enable-cli и --enable-cgi, включены по умолчанию, просто наличие --enable-cli в команде конфигурации необязательно означает, что CLI будет скопирован в {PREFIX}/bin/php при выполнении make install.

Бинарный файл CLI входит в дистрибутив для Windows в основной папке в качестве файлаphp.exe. CGI-версия находится в файле php-cgi.exe. Кроме того, в дистрибутив входит файл php-win.exe, если PHP был сконфигурирован с помощью --enable-cli-win32. Он полностью эквивалентен CLI-версии, за исключением того, что абсолютно ничего не выводит, и, таким образом, не предоставляет консоль (окно терминала не появляется на экране).

Замечание: Какой из вариантов SAPI установлен?

Выполните из командной строки php -v для получения информации о том, является ли php CGI или CLI. Также вы можете использовать функцию php_sapi_name() или константу PHP_SAPI.

Замечание:

Соответствующую страницу руководства (man) Unix можно просмотреть с помощью команды man php в консоли.



Основные отличия от остальных реализаций SAPI

Основные отличия CLI SAPI от остальных реализаций SAPI:

  • В отличие от CGI SAPI, заголовки не пишутся в поток вывода.

    Несмотря на то, что в CGI SAPI есть способ подавления HTTP-заголовков, в CLI SAPI нет возможности их включить.

    CLI по умолчанию запускается в тихом режиме, тем не менее, ключи -q и --no-header сохранены для обратной совместимости, что позволяет использовать старые CGI-скрипты.

    Текущая директория не изменяется на рабочую директорию скрипта. (Ключи -C и --no-chdir сохранены для обратной совместимости)

    Сообщения об ошибках выдаются в текстовом режиме (без HTML-форматирования).

  • Некоторые настройки php.ini переопределяются CLI SAPI, поскольку они не имеют смысла при работе в командной строке:

    Переопределяемые директивы php.ini
    Директива Значение по умолчанию в CLI SAPI Комментарий
    html_errors false По умолчанию false, т.к. бывает достаточно сложно читать в консоли сообщения об ошибке, когда они наполнены бессмысленными HTML-тегами.
    implicit_flush true Обычно в консоли желательно отображать вывод, например, из print, echo и других, сразу же минуя буфер. Тем не менее, по-прежнему можно использовать буферизацию вывода для отложенного вывода или манипуляций с ним.
    max_execution_time 0 (без ограничений) PHP, выполняемый в консоли, как правило, используется для более широкого диапазона задач, чем обычные веб-скрипты. И так как они могут выполняться очень долго, то максимальное время выполнения неограниченно.
    register_argc_argv true

    Установка этой опции в значение true означает, что скрипты запускаемые через CLI SAPI всегда имеют доступ к argc (количество аргументов, переданных приложению) и argv (массив текущих аргументов).

    При использовании CLI SAPI переменные $argc и $argv автоматически заполняются соответствующими значениями. Эти значения можно также найти в массиве $_SERVER, например: $_SERVER['argv'].

    output_buffering false

    Несмотря на то, что эта опция php.ini жёстко установлена в false, функции буферизации вывода всё ещё доступны.

    max_input_time false

    PHP CLI не поддерживает GET, POST или загрузку файлов.

    Замечание:

    Эти директивы не могут быть инициализированы другими значениями из конфигурационного файла php.ini или любого другого (в случае, если он указан). Это ограничение связано с тем, что значения применяются после обработки конфигурационных файлов. Тем не менее, эти значения могут быть изменены во время работы скрипта (хотя это не имеет особого смысла для всех них, например register_argc_argv).

    Замечание:

    Рекомендуется установить опцию ignore_user_abort для скриптов, используемых из командной строки. За подробностями обращайтесь к функции ignore_user_abort().

  • Для облегчения работы в окружении оболочки было определено некоторое количество констант для потоков ввода/вывода.

  • CLI SAPI не изменяет текущую директорию на директорию исполняемого скрипта.

    Пример #1 Пример, демонстрирующий разницу с CGI SAPI:

    <?php
    // Простейший тестовый скрипт под названием test.php
    echo getcwd(), "\n";
    ?>

    В случае, если используется CGI-версия, результат работы будет следующим:

    $ pwd
    /tmp
    
    $ php -q another_directory/test.php
    /tmp/another_directory
    

    Это наглядно демонстрирует, что PHP изменяет текущую директорию на директорию исполняемого скрипта.

    Использование CLI SAPI даёт другой результат:

    $ pwd
    /tmp
    
    $ php -f another_directory/test.php
    /tmp
    

    Это обеспечивает большую гибкость при написании консольных скриптов на PHP.

    Замечание:

    CGI SAPI позволяет получить аналогичное CLI SAPI поведение в случае использования ключа -C при запуске из командной строки.



Список опций командной строки

Список опций командной строки, предоставляемых PHP, могут быть получены в любой момент, запустив PHP с ключом -h:

Usage: php [options] [-f] <file> [--] [args...]
   php [options] -r <code> [--] [args...]
   php [options] [-B <begin_code>] -R <code> [-E <end_code>] [--] [args...]
   php [options] [-B <begin_code>] -F <file> [-E <end_code>] [--] [args...]
   php [options] -- [args...]
   php [options] -a

  -a               Run interactively
  -c <path>|<file> Look for php.ini file in this directory
  -n               No php.ini file will be used
  -d foo[=bar]     Define INI entry foo with value 'bar'
  -e               Generate extended information for debugger/profiler
  -f <file>        Parse and execute <file>.
  -h               This help
  -i               PHP information
  -l               Syntax check only (lint)
  -m               Show compiled in modules
  -r <code>        Run PHP <code> without using script tags <?..?>
  -B <begin_code>  Run PHP <begin_code> before processing input lines
  -R <code>        Run PHP <code> for every input line
  -F <file>        Parse and execute <file> for every input line
  -E <end_code>    Run PHP <end_code> after processing all input lines
  -H               Hide any passed arguments from external tools.
  -S <addr>:<port> Run with built-in web server.
  -t <docroot>     Specify document root <docroot> for built-in web server.
  -s               Output HTML syntax highlighted source.
  -v               Version number
  -w               Output source with stripped comments and whitespace.
  -z <file>        Load Zend extension <file>.

  args...          Arguments passed to script. Use -- args when first argument
                   starts with - or script is read from stdin

  --ini            Show configuration file names

  --rf <name>      Show information about function <name>.
  --rc <name>      Show information about class <name>.
  --re <name>      Show information about extension <name>.
  --rz <name>      Show information about Zend extension <name>.
  --ri <name>      Show configuration for extension <name>.

Опции, доступные из командной строки
Опция Полное название Описание
-a --interactive

Запустить PHP в интерактивном режиме. Для получения дополнительной информации смотрите раздел Интерактивная консоль.

-b --bindpath

Путь связывания библиотек (Bind Path) для внешнего режима FASTCGI Server (только для CGI).

-C --no-chdir

Не менять текущую директорию на директорию скрипта (только для CGI).

-q --no-header

Тихий режим. Подавляет вывод заголовков HTTP (только для CGI).

-T --timing

Измерить время выполнения скрипта, повторенного count раз (только для CGI).

-c --php-ini

Указывает, либо директорию, в которой нужно искать конфигурационный файл php.ini, либо пользовательский INI-файл (название которого может отличаться от стандартного php.ini), например:

$ php -c /custom/directory/ my_script.php

$ php -c /custom/directory/custom-file.ini my_script.php

Если эта опция не указана, поиск php.ini будет осуществлён в местах по умолчанию.

-n --no-php-ini

Полностью игнорировать php.ini.

-d --define

Устанавливает пользовательское значение для каждой из конфигурационных опций, доступных в php.ini. Синтаксис выглядит следующим образом:

 -d configuration_directive[=value]

# Если значение опущено, то соответствующей опции будет присвоено значение "1"
$ php -d max_execution_time
        -r '$foo = ini_get("max_execution_time"); var_dump($foo);'
string(1) "1"

# Указание пустого значения установит соответствующую опцию значением ""
php -d max_execution_time=
        -r '$foo = ini_get("max_execution_time"); var_dump($foo);'
string(0) ""

# Конфигурационная переменная будет установлена любым значением, указанным после символа '='
$  php -d max_execution_time=20
        -r '$foo = ini_get("max_execution_time"); var_dump($foo);'
string(2) "20"
$  php
        -d max_execution_time=doesntmakesense
        -r '$foo = ini_get("max_execution_time"); var_dump($foo);'
string(15) "doesntmakesense"

-e --profile-info

Включить режим расширенной информации, используемый отладчиком/профайлером.

-f --file

Парсит и исполняет файл, указанный в опции -f. Этот параметр необязателен и может быть опущен - достаточно просто указать имя запускаемого файла.

-h и -? --help и --usage Выводит список опций командной строки с однострочным описанием того, что они делают.
-i --info Вызывает phpinfo() и выводить её результат. В случае, если PHP работает некорректно, рекомендуется выполнить php -i и посмотреть, выводятся ли сообщения об ошибках до или вместо информационных таблиц. Учитывайте, что в случае использования CGI-модуля весь вывод будет в формате HTML и, как следствие, очень большим.
-l --syntax-check

Предоставляет удобный способ для проверки заданного PHP-кода на наличие синтаксических ошибок. В случае успешной проверки будет напечатана следующая фраза: "No syntax errors detected in <filename>", а код возврата будет равен 0. При неудачной проверке будет выведено "Errors parsing <filename>" вместе с внутренними сообщениями парсера, а код возврата будет равен -1.

Данная опция не будет обнаруживать фатальные ошибки (например, вызов неопределённых функций). Используйте опцию -f, если вы хотите проверить код на наличие фатальных ошибок.

Замечание:

Эта опция не работает с опцией -r.

-m --modules

Пример #1 Вывод встроенных (и загруженных) модулей PHP и Zend

$ php -m
[PHP Modules]
xml
tokenizer
standard
session
posix
pcre
overload
mysql
mbstring
ctype

[Zend Modules]

-r --run

Позволяет выполнять PHP-код, указанный непосредственно в командной строке. Открывающие и закрывающие PHP-теги (<?php и ?>) не нужны и будут приводит к синтаксической ошибке, если они присутствуют.

Замечание:

При использовании этого ключа следует быть очень осторожным и избегать недоразумений, связанных с автоматической подстановкой переменных окружения.

Пример #2 Ошибка синтаксиса при использовании двойных кавычек

$ php -r "$foo = get_defined_constants();"
PHP Parse error:  syntax error, unexpected '=' in Command line code on line 1

Parse error: syntax error, unexpected '=' in Command line code on line 1

Проблема здесь заключается в том, что sh/bash выполняет автоматическую подстановку переменных в случае, если используются двойные кавычки ("). Поскольку переменная $foo вряд ли определена, она заменяется пустой строкой, что приводит к тому, что передаваемый PHP-код для выполнения выглядит следующим образом:

$ php -r " = get_defined_constants();"

Правильным решением в данном случае будет использование одинарных кавычек ', поскольку автоматическая подстановка переменных, заключённых в одинарные кавычки, в sh/bash не происходит.

Пример #3 Использование одинарных кавычек для предотвращения подстановки переменных в консоли

$ php -r '$foo = get_defined_constants(); var_dump($foo);'
array(370) {
  ["E_ERROR"]=>
  int(1)
  ["E_WARNING"]=>
  int(2)
  ["E_PARSE"]=>
  int(4)
  ["E_NOTICE"]=>
  int(8)
  ["E_CORE_ERROR"]=>
  [...]

При использовании оболочки, отличной от sh/bash, могут возникнуть другие проблемы. В таком случае необходимо создать отчёт о возникшей ошибке на сайте » https://github.com/php/php-src/issues. Можно столкнуться с проблемами при попытке получить доступ к переменным оболочки или при работе с экранирующими обратными слешами. Теперь вы предупреждены!

Замечание:

Ключ -r доступен в CLI SAPI, но недоступен в CGI SAPI.

Замечание:

Эта опция предназначена только для самого простого кода. Поэтому некоторые конфигурационные директивы (например, auto_prepend_file и auto_append_file) в этом режиме будут проигнорированы.

-B --process-begin

Выполняемый код PHP перед обработкой потока ввода (stdin).

-R --process-code

PHP-код, выполняемый для каждой строки ввода.

В этом режиме есть две специальные переменные: $argn и $argi. $argn содержит строку, которую PHP обрабатывает в данный момент, а $argi содержит номер этой строки.

-F --process-file

PHP-файл, выполняемый для каждой строки ввода.

-E --process-end

PHP-код, выполняемый после обработки ввода.

Пример #4 Использование опций -B, -R и -E для подсчёта количества строк в проекте.

$ find my_proj | php -B '$l=0;' -R '$l += count(@file($argn));' -E 'echo "Всего строк: $l\n";'
Всего строк: 37328

-S --server

Запускает встроенный веб-сервер.

-t --docroot Указывает корень документа для встроенного веб-сервера.
-s --syntax-highlight и --syntax-highlighting

Показать исходный код с подсветкой синтаксиса.

Эта опция использует внутренний механизм для разбора файла и записи в стандартный поток вывода подсвеченной версии этого файла. Учтите, что все что она делает, это генерирует блок <code> [...] </code> HTML-тегов, без HTML-заголовков.

Замечание:

Эта опция несовместима с опцией -r.

-v --version

Пример #5 Использование -v для получения типа SAPI и версии PHP и Zend

$ php -v
PHP 5.3.1 (cli) (built: Dec 11 2009 19:55:07)
Copyright (c) 1997-2009 The PHP Group
Zend Engine v2.3.0, Copyright (c) 1998-2009 Zend Technologies

-w --strip

Показать исходный код без комментариев и пробелов.

Замечание:

Эта опция несовместима с опцией -r.

-z --zend-extension

Загружает модуль Zend. Если передано только имя файла, PHP попытается загрузить этот модуль из пути библиотек по умолчанию (обычно указывается в /etc/ld.so.conf в системах Linux). Передача файла с абсолютным путём не будет использовать системный путь поиска библиотеки. Относительное имя файла, содержащее директорию, укажет PHP подгрузить модуль относительно текущей директории.

  --ini

Показывает имена конфигурационных файлов и отсканированные директории.

Пример #6 Пример --ini

$ php --ini
Configuration File (php.ini) Path: /usr/dev/php/5.2/lib
Loaded Configuration File:         /usr/dev/php/5.2/lib/php.ini
Scan for additional .ini files in: (none)
Additional .ini files parsed:      (none)

--rf --rfunction

Показывает информацию об указанной функции или методе класса (например, количество и названия параметров).

Эта опция доступна только в том случае, если PHP был скомпилирован с поддержкой Reflection.

Пример #7 Базовое использование --rf

$ php --rf var_dump
Function [ <internal> public function var_dump ] {

  - Parameters [2] {
    Parameter #0 [ <required> $var ]
    Parameter #1 [ <optional> $... ]
  }
}

--rc --rclass

Показывает информацию об указанном классе (список констант, свойств и методов).

Эта опция доступна только в том случае, если PHP был скомпилирован с поддержкой Reflection.

Пример #8 Пример --rc

$ php --rc Directory
Class [ <internal:standard> class Directory ] {

  - Constants [0] {
  }

  - Static properties [0] {
  }

  - Static methods [0] {
  }

  - Properties [0] {
  }

  - Methods [3] {
    Method [ <internal> public method close ] {
    }

    Method [ <internal> public method rewind ] {
    }

    Method [ <internal> public method read ] {
    }
  }
}

--re --rextension

Показывает информацию об указанном модуле (список опций php.ini, определённых функций, констант и классов).

Эта опция доступна только в том случае, если PHP был скомпилирован с поддержкой Reflection.

Пример #9 Пример --re

$ php --re json
Extension [ <persistent> extension #19 json version 1.2.1 ] {

  - Functions {
    Function [ <internal> function json_encode ] {
    }
    Function [ <internal> function json_decode ] {
    }
  }
}

--rz --rzendextension

Показывает информацию о конфигурации указанного Zend-модуля (та же информация, которая возвращается phpinfo()).

--ri --rextinfo

Показывает информацию о конфигурации указанного модуля (та же информация, которая возвращается phpinfo()). Конфигурацию ядра можно узнать, указав в качестве имени модуля значение "main".

Пример #10 Пример --ri

$ php --ri date

date

date/time support => enabled
"Olson" Timezone Database Version => 2009.20
Timezone Database => internal
Default timezone => Europe/Oslo

Directive => Local Value => Master Value
date.timezone => Europe/Oslo => Europe/Oslo
date.default_latitude => 59.930972 => 59.930972
date.default_longitude => 10.776699 => 10.776699
date.sunset_zenith => 90.583333 => 90.583333
date.sunrise_zenith => 90.583333 => 90.583333

Замечание:

Опции -rBRFEH, --ini и --r[fcezi] доступны только в CLI.



Выполнение PHP-файлов

В CLI SAPI есть три различных способа запуска PHP-кода:

  1. Указание конкретного файла для запуска.

    $ php my_script.php
    
    $ php -f my_script.php
    

    Оба способа (с указанием опции -f или без) запустят файл my_script.php. Нет ограничений, какой файл запускать; в частности, файлы не обязаны иметь расширение .php.

  2. Передать PHP-код напрямую в командной строке.

    $ php -r 'print_r(get_defined_constants());'
    

    Необходимо быть особо осторожным при использовании этого способа, т.к. может произойти подстановка переменных оболочки при использовании двойных кавычек.

    Замечание:

    Внимательно прочтите пример: в нем нет открывающих и закрывающих тегов! Опция -r просто в них не нуждается, и их использование приведёт к ошибке разбора.

  3. Передать запускаемый PHP-код через стандартный поток ввода (stdin).

    Это даёт мощную возможность создавать PHP-код и передавать его запускаемому файлу, как показано в этом (вымышленном) примере:

    $ some_application | some_filter | php | sort -u > final_output.txt
    
Вы не можете комбинировать любой из этих трёх способов запуска кода.

Как и любое другое консольное приложение, бинарный файл PHP принимает аргументы, но PHP-скрипт также может получать аргументы. PHP не ограничивает количество аргументов, передаваемых в скрипт (оболочка консоли устанавливает некоторый порог количества символов, которые могут быть переданы; обычно этого лимита хватает). Переданные аргументы доступны в глобальном массиве $argv. Первый индекс (ноль) всегда содержит имя вызываемого скрипта из командной строки. Учтите, что если код вызывается на лету из командной строки с помощью опции -r, значением $argv[0] будет "Стандартный поток" ("Standard input code"); до PHP 7.2.0 это был дефис ("-"). То же самое верно и для кода, переданного через конвейер из STDIN.

Вторая зарегистрированная глобальная переменная - это $argc, содержащая количество элементов в массиве $argvне количество аргументов, переданных скрипту).

Если передаваемые аргументы не начинаются с символа -, то особых проблем быть не должно. Передаваемый в скрипт аргумент, который начинается с - создаст проблемы, т.к. PHP решит, что он сам должен его обработать. Для предотвращения подобного поведения используйте разделитель списка аргументов --. После того, как этот разделитель будет проанализирован PHP, все последующие аргументы будут переданы в скрипт нетронутыми.

# Эта команда не запустит данный код, но покажет информацию об использовании PHP
$ php -r 'var_dump($argv);' -h
Usage: php [options] [-f] <file> [args...]
[...]

# Эта команда передаст аргумент '-h' в скрипт, предотвратив показ справки PHP
$ php -r 'var_dump($argv);' -- -h
array(2) {
  [0]=>
  string(1) "-"
  [1]=>
  string(2) "-h"
}

Однако, в Unix-системах есть ещё один способ использования PHP для консольных скриптов. Можно написать скрипт, первая строка которого будет начинаться с #!/usr/bin/php (или же другой корректный путь к бинарному файлу PHP CLI). После этой строки можно поместить обычный PHP-код, заключённый в открывающие и закрывающие теги PHP. Как только будут установлены корректные атрибуты запуска на файл (например, chmod +x test), скрипт может быть запущен как обычный консольный или perl-скрипт:

Пример #1 Запуск PHP-скрипта как консольного

#!/usr/bin/php
<?php
var_dump
($argv);
?>

Предполагая, что этот файл назван test и находится в текущей директории, можно сделать следующее:

$ chmod +x test
$ ./test -h -- foo
array(4) {
  [0]=>
  string(6) "./test"
  [1]=>
  string(2) "-h"
  [2]=>
  string(2) "--"
  [3]=>
  string(3) "foo"
}

Как можно увидеть, в этом случае не нужно заботиться о передаче параметров, которые начинаются с -.

Исполняемый PHP-файл может использоваться для запуска PHP-скриптов независимо от веб-сервера. В случае работы в Unix-подобной системе, необходимо добавить в первую строку файла #! (называемый также "shebang") чтобы указать, какая из программ должна запускать скрипт. На Windows-платформах можно назначить обработчик php.exe для файлов с расширениями .php или создать пакетный (.bat) файл для запуска скриптов посредством PHP. Строка, добавляемая в начале скрипта для Unix-систем, не влияет на их работу в ОС Windows, таким образом можно создавать кроссплатформенные скрипты. Ниже приведён простой пример скрипта, выполняемого из командной строки:

Пример #2 Скрипт, предназначенный для запуска из командной строки (script.php)

#!/usr/bin/php
<?php

if ($argc != 2 || in_array($argv[1], array('--help', '-help', '-h', '-?'))) {
?>

Это консольный PHP-скрипт, принимающий один аргумент.

Использование:
<?php echo $argv[0]; ?> <option>

<option> Любое слово, которое вы хотели бы
напечатать. Опции --help, -help, -h,
или -? покажут текущую справочную информацию.

<?php
} else {
echo
$argv[1];
}
?>

В приведённом выше скрипте в первой строке содержится shebang, указывающий что этот файл должен запускаться PHP. Работа ведётся с CLI-версией, поэтому не будет выведено ни одного HTTP-заголовка.

Скрипт сначала проверяет наличие обязательного одного аргумента (в дополнение к имени скрипта, который также подсчитывается). Если их нет, или если переданный аргумент был --help, -help, -h или -?, выводится справочное сообщение с использованием $argv[0], которое содержит имя выполняемого скрипта. В противном случае просто выводится полученный аргумент.

Для запуска приведённого примера в Unix-системе, нужно сделать его исполняемым и просто выполнить в консоли script.php echothis или script.php -h. В Windows-системе можно создать пакетный файл:

Пример #3 Пакетный файл для запуска PHP-скрипта из командной строки (script.bat)

@echo OFF
"C:\php\php.exe" script.php %*

Предполагая, что вышеприведённый скрипт называется script.php, а полный путь к CLI php.exe находится в C:\php\php.exe, этот пакетный файл запустит его с переданными параметрами: script.bat echothis или script.bat -h.

Также можно ознакомиться с модулем Readline для получения дополнительных функций, которые можно использовать для улучшения консольного PHP-скрипта.

В Windows запуск PHP можно настроить без необходимости указывать C:\php\php.exe или расширение .php. Подробнее эта тема описана в разделе Запуск PHP из командной строки в Microsoft Windows.

Замечание:

В Windows рекомендуется запускать PHP под актуальной учётной записью пользователя. При работе в сетевой службе некоторые операции не будут выполнены, поскольку "сопоставление имён учётных записей и идентификаторов безопасности не выполнено".



Потоки ввода/вывода

Модуль CLI SAPI определяет несколько констант для потоков ввода/вывода, чтобы упростить работу с командной строкой.

Константы, специфичные для модуля CLI
Константа Описание
STDIN

Уже открытый поток ввода (stdin). Это предотвращает необходимость его открывать следующим способом:

<?php
$stdin
= fopen('php://stdin', 'r');
?>
Если вы хотите прочесть одну строку из stdin, можно использовать следующий код:
<?php
$line
= trim(fgets(STDIN)); // читает одну строку из STDIN
fscanf(STDIN, "%d\n", $number); // читает число из STDIN
?>

STDOUT

Уже открытый поток вывода (stdout). Это предотвращает необходимость его открывать следующим способом:

<?php
$stdout
= fopen('php://stdout', 'w');
?>

STDERR

Уже открытый поток ошибок (stderr). Это предотвращает необходимость его открывать следующим способом:

<?php
$stderr
= fopen('php://stderr', 'w');
?>

Учитывая вышесказанное, нет необходимости самому открывать поток, например, stderr, а можно просто использовать уже определённую константу ресурса потока:

php -r 'fwrite(STDERR, "stderr\n");'
Вам не нужно явно закрывать эти потоки, они будут закрыты PHP автоматически при окончании вашего скрипта.

Замечание:

Эти константы недоступны, если считывается PHP-скрипт из stdin.



Интерактивная консоль

Модуль CLI SAPI предоставляет интерактивную консоль, используя опцию -a, если PHP был скомпилирован с опцией --with-readline. Начиная с PHP PHP 7.1.0, интерактивная консоль также доступна на Windows, если модуль readline включён.

Используя интерактивную консоль, можно ввести и выполнить непосредственно PHP-код.

Пример #1 Запуск кода в интерактивной консоли

$ php -a
Interactive shell

php > echo 5+8;
13
php > function addTwo($n)
php > {
php { return $n + 2;
php { }
php > var_dump(addtwo(2));
int(4)
php >

Интерактивная консоль также автодополняет (с помощью клавиши Tab) имена функций, констант, классов, переменных, вызовы статических методов и константы классов.

Пример #2 Автодополнение по Tab

Двойное нажатие клавиши Tab при наличии нескольких вариантов дополнения покажет список этих вариантов:

php > strp[TAB][TAB]
strpbrk   strpos    strptime
php > strp

Когда есть только одно дополнение, одиночное нажатие Tab дополнит оставшийся текст на той же самой строке:

php > strpt[TAB]ime(

Дополнение также работает для имён, которые были объявлены в течение данной интерактивной сессии:

php > $fooThisIsAReallyLongVariableName = 42;
php > $foo[TAB]ThisIsAReallyLongVariableName

Интерактивная консоль хранит историю команд, для доступа к которой можно использовать стрелки вверх и вниз. История хранится в файле ~/.php_history.

Модуль CLI SAPI предоставляет две новые настройки в php.ini: cli.pager и cli.prompt. Настройка cli.pager позволяет использовать внешнюю программу (такую как less) для постраничного просмотра данных вместо их прямого вывода на экран. Настройка cli.prompt позволяет задавать приглашение php > на ввод команды.

Также можно устанавливать настройки php.ini в интерактивной консоли, используя специальное сокращение.

Пример #3 Установка настройки php.ini в интерактивной консоли

Настройка cli.prompt:

php > #cli.prompt=hello world :>
hello world :>

Используя обратные апострофы можно задать PHP-код, который выполнится в приглашении на ввод команды:

php > #cli.prompt=`echo date('H:i:s');` php >
15:49:35 php > echo 'hi';
hi
15:49:43 php > sleep(2);
15:49:45 php >

Установка less для постраничного вывода данных:

php > #cli.pager=less
php > phpinfo();
(output displayed in less)
php >

Настройка cli.prompt поддерживает несколько управляющих последовательностей:

Управляющие последовательности cli.prompt
Управляющая последовательность Описание
\e Используется для добавления цветов в приглашение на ввод команды. Пример: \e[032m\v \e[031m\b \e[34m\> \e[0m
\v Версия PHP.
\b Отображает в какой части PHP мы находимся. Для примера /* показывает, что мы находимся в многострочном комментарии. Внешняя область видимости обозначается как php.
\> Указывает символ приглашения. По умолчанию это символ >, но можно изменить, когда оболочка находится внутри незакрытого блока или строки. Возможные символы: ' " { ( >

Замечание:

Файлы, подключённые с помощью опций auto_prepend_file и auto_append_file обрабатываются в этом режиме с некоторыми ограничениями, например, функции должны быть объявлены до их использования.

Интерактивный режим

Если модуль readline недоступен, то до PHP 8.1.0 вызов файла CLI SAPI с параметром -a обеспечивал интерактивный режим. В этом режиме предполагается, что полный скрипт PHP передаётся через STDIN, а после завершения скрипт оценивается с помощью CRTL+d (POSIX) или CTRL+z с последующим ENTER (Windows). По сути это то же самое, что и вызов CLI SAPI без параметра -a. option.

Начиная с PHP 8.1.0, вызов CLI SAPI с параметром -a завершается ошибкой, если модуль readline недоступен.



Встроенный веб-сервер

Внимание

Веб-сервер предназначен для помощи в разработке приложений. Он также может быть полезным в тестовых целях или для демонстрации приложения, запускаемого в полностью контролируемом окружении. Он не выполняет функции полноценного веб-сервера и не должен использоваться в общедоступных сетях.

Модуль CLI SAPI содержит встроенный веб-сервер.

Веб-сервер выполняет только один однопоточный процесс, поэтому приложения PHP будут останавливаться, если запрос заблокирован.

URI запросы обслуживаются из текущей директории, в которой был запущен PHP, если не используется опция -t для явного указания корневого документа. Если URI запроса не указывает на определённый файл, то будет возвращён index.php или index.html в указанной директории. Если ни один из файлов не существует, то поиск этих файлов будет продолжен в родительской директории и так далее до тех пор, пока они не будут найдены или был достигнут корень документа. Если найден index.php или index.html, он возвращается, а в $_SERVER['PATH_INFO'] будет находится последняя часть URL. В противном случае возвращается 404 код ответа.

Если PHP-файл указывается в командной строке, когда запускается веб-сервер, то он рассматривается как скрипт "маршрутизации" (router). Скрипт выполняется в самом начале каждого HTTP-запроса. Если этот скрипт возвращает false, то запрашиваемый ресурс возвращается как есть. В противном случае браузеру будет возвращён вывод этого скрипта.

Стандартные MIME-типы возвращаются для файлов со следующими расширениями: .3gp, .apk, .avi, .bmp, .css, .csv, .doc, .docx, .flac, .gif, .gz, .gzip, .htm, .html, .ics, .jpe, .jpeg, .jpg, .js, .kml, .kmz, .m4a, .mov, .mp3, .mp4, .mpeg, .mpg, .odp, .ods, .odt, .oga, .ogg, .ogv, .pdf, .pdf, .png, .pps, .pptx, .qt, .svg, .swf, .tar, .text, .tif, .txt, .wav, .webm, .wmv, .xls, .xlsx, .xml, .xsl, .xsd и .zip.

История правок: Поддерживаемые MIME-типы (расширения файлов)
Версия Описание
5.5.12 .xml, .xsl, и .xsd
5.5.7 .3gp, .apk, .avi, .bmp, .csv, .doc, .docx, .flac, .gz, .gzip, .ics, .kml, .kmz, .m4a, .mp3, .mp4, .mpg, .mpeg, .mov, .odp, .ods, .odt, .oga, .pdf, .pptx, .pps, .qt, .swf, .tar, .text, .tif, .wav, .wmv, .xls, .xlsx и .zip
5.5.5 .pdf
5.4.11 .ogg, .ogv, и .webm
5.4.4 .htm и .svg
История изменений
Версия Описание
7.4.0 Вы можете настроить встроенный веб-сервер так, чтобы он выполнял разветвление нескольких воркеров для проверки кода, который требует нескольких одновременных запросов к встроенному веб-серверу. Задайте в переменной окружения PHP_CLI_SERVER_WORKERS количество требуемых воркеров перед запуском сервера. Не поддерживается в Windows.
Внимание

Эта экспериментальная функция не предназначена для продакшен использования. Обычно встроенный веб-сервер не предназначен для продакшен использования.

Пример #1 Запуск веб-сервера

$ cd ~/public_html
$ php -S localhost:8000

В консоли выведется:

PHP 5.4.0 Development Server started at Thu Jul 21 10:43:28 2011
Listening on localhost:8000
Document root is /home/me/public_html
Press Ctrl-C to quit

После URI-запросов http://localhost:8000/ и http://localhost:8000/myscript.html в консоли выведется примерно следующее:

PHP 5.4.0 Development Server started at Thu Jul 21 10:43:28 2011
Listening on localhost:8000
Document root is /home/me/public_html
Press Ctrl-C to quit.
[Thu Jul 21 10:48:48 2011] ::1:39144 GET /favicon.ico - Request read
[Thu Jul 21 10:48:50 2011] ::1:39146 GET / - Request read
[Thu Jul 21 10:48:50 2011] ::1:39147 GET /favicon.ico - Request read
[Thu Jul 21 10:48:52 2011] ::1:39148 GET /myscript.html - Request read
[Thu Jul 21 10:48:52 2011] ::1:39149 GET /favicon.ico - Request read

Обратите внимание, что до PHP 7.4.0 статические ресурсы с символическими ссылками не были доступны в Windows, если только скрипт маршрутизатора не обработал бы их.

Пример #2 Запуск с указанием корневой директории

$ cd ~/public_html
$ php -S localhost:8000 -t foo/

В консоли выведется:

PHP 5.4.0 Development Server started at Thu Jul 21 10:50:26 2011
Listening on localhost:8000
Document root is /home/me/public_html/foo
Press Ctrl-C to quit

Пример #3 Использование скрипта маршрутизации

В этом примере, запросы изображений будут отображать их, но запросы HTML-файлов будут возвращать "Добро пожаловать в PHP".

<?php
// router.php
if (preg_match('/\.(?:png|jpg|jpeg|gif)$/', $_SERVER["REQUEST_URI"])) {
return
false; // сервер возвращает файлы напрямую.
} else {
echo
"<p>Добро пожаловать в PHP</p>";
}
?>
$ php -S localhost:8000 router.php
Внимание

Встроенный веб-сервер не должен использоваться в общедоступной сети.

Пример #4 Проверка использования веб-сервера CLI

Для совместного использования скрипта маршрутизации при разработке с веб-сервером CLI и в дальнейшем с рабочим (production) веб-сервером:

<?php
// router.php
if (php_sapi_name() == 'cli-server') {
/* Маршрутизация с заданными правилами и возврат false */
}
/* продолжение с обычными операциями index.php */
?>
$ php -S localhost:8000 router.php

Пример #5 Поддержка неподдерживаемых типов файлов

Если вам нужно обслуживать статические ресурсы с MIME-типами, неподдерживаемыми веб-сервером CLI, используйте это:

<?php
// router.php
$path = pathinfo($_SERVER["SCRIPT_FILENAME"]);
if (
$path["extension"] == "el") {
header("Content-Type: text/x-script.elisp");
readfile($_SERVER["SCRIPT_FILENAME"]);
}
else {
return
FALSE;
}
?>
$ php -S localhost:8000 router.php

Пример #6 Доступ к веб-серверу CLI с удалённых машин

Вы можете сделать веб-сервер доступным на 8000 порту для всех сетевых интерфейсов:

$ php -S 0.0.0.0:8000


Опции конфигурации

Опции конфигурации CLI SAPI
Имя По умолчанию Место изменения Список изменений
cli_server.color "0" PHP_INI_ALL  

Краткое разъяснение конфигурационных директив.

cli_server.color bool

Включает поддержку цветовых кодов ANSI в выводе терминала встроенного веб-сервера.




Сборка мусора

Содержание

В этом разделе описываются достоинства нового механизма сборки мусора (также называемого Garbage Collection или GC), являющегося частью PHP 5.3.


Основы подсчёта ссылок

Переменная PHP хранится в контейнере, называемом "zval". Контейнер zval, помимо типа и значения переменной, также содержит два дополнительных элемента. Первый называется "is_ref" и представляет булево значение, указывающее, является переменная частью "набора ссылок" или нет. Благодаря этому элементу PHP знает как отличать обычные переменные от ссылок. Так как PHP содержит пользовательские ссылки, которые можно создать оператором &, контейнер zval также содержит внутренний механизм подсчёта ссылок для оптимизации использования памяти. Эта вторая часть дополнительной информации, называемая "refcount" (счётчик ссылок), содержит количество имён переменных (также называемых символами), которые указывают на данный контейнер zval. Все имена переменных хранятся в таблице имён, отдельной для каждой области видимости переменных. Такая область видимости существует для главного скрипта, а также для каждой функции и метода.

Контейнер zval создаётся при создании новой переменной, которой присваивается константа, например:

Пример #1 Создание нового контейнера zval

<?php
$a
= "new string";
?>

В данном примере создаётся новый символ a в текущей области видимости и новый контейнер переменной с типом string и значением new string. Бит "is_ref" по умолчанию задаётся равным false, т.к. не создано ни одной пользовательской ссылки. Значение же "refcount" задаётся равным 1, т.к. только одно имя переменной указывает на данный контейнер. Обратите внимание, что ссылки (т.е. "is_ref" равно true) с "refcount" равным 1 обрабатываются так, как если бы они не были ссылками (то есть как "is_ref" было бы false). Если у вас установлен » Xdebug, то вы можете вывести эту информацию, вызвав функцию xdebug_debug_zval().

Пример #2 Вывод информации о zval

<?php
$a
= "new string";
xdebug_debug_zval('a');
?>

Результат выполнения данного примера:

a: (refcount=1, is_ref=0)='new string'

Присвоение этой переменной другой увеличивает счётчик ссылок.

Пример #3 Увеличение счётчика ссылок zval

<?php
$a
= "new string";
$b = $a;
xdebug_debug_zval( 'a' );
?>

Результат выполнения данного примера:

a: (refcount=2, is_ref=0)='new string'

Счётчик ссылок здесь равен 2, т.к. a и b ссылаются на один и тот же контейнер переменной. PHP достаточно умён, чтобы не копировать контейнер, пока в этом нет необходимости. Как только "refcount" станет равным нулю, контейнер уничтожается. "refcount" уменьшается на единицу при уходе переменной из области видимости (например, в конце функции) или при удалении этой переменной (например при вызове unset()).

Пример #4 Уменьшение счётчика ссылок zval

<?php
$a
= "new string";
$c = $b = $a;
xdebug_debug_zval( 'a' );
$b = 42;
xdebug_debug_zval( 'a' );
unset(
$c );
xdebug_debug_zval( 'a' );
?>

Результат выполнения данного примера:

a: (refcount=3, is_ref=0)='new string'
a: (refcount=2, is_ref=0)='new string'
a: (refcount=1, is_ref=0)='new string'

Если мы сейчас вызовем unset($a);, то контейнер, включая тип и значение, будет удалён из памяти.

Составные типы данных

Все несколько усложняется с составными типами данных, такими как массивы (array) и объекты (object). В отличие от скалярных (scalar) значений, массивы и объекты хранят свои свойства в собственных таблицах имён. Это значит, что следующий пример создаст сразу три zval контейнера:

Пример #5 Создание array zval

<?php
$a
= array( 'meaning' => 'life', 'number' => 42 );
xdebug_debug_zval( 'a' );
?>

Результатом выполнения данного примера будет что-то подобное:

a: (refcount=1, is_ref=0)=array (
   'meaning' => (refcount=1, is_ref=0)='life',
   'number' => (refcount=1, is_ref=0)=42
)

Графически:

Контейнеры для простого массива

Результат - три контейнера: a, meaning и number. Похожие правила применяются и для увеличения и уменьшения "refcounts". Ниже мы добавляем ещё один элемент массива и устанавливаем ему значение уже существующего элемента:

Пример #6 Добавление уже существующего элемента в массив

<?php
$a
= array( 'meaning' => 'life', 'number' => 42 );
$a['life'] = $a['meaning'];
xdebug_debug_zval( 'a' );
?>

Результатом выполнения данного примера будет что-то подобное:

a: (refcount=1, is_ref=0)=array (
   'meaning' => (refcount=2, is_ref=0)='life',
   'number' => (refcount=1, is_ref=0)=42,
   'life' => (refcount=2, is_ref=0)='life'
)

Графически:

Контейнеры для простого массива со ссылками

Вышеприведённый вывод Xdebug показывает, что и старый и новый элементы массива сейчас указывают на контейнер, чей "refcount" равен 2. Хотя показано два контейнера со значением 'life', на самом деле это один контейнер. Функция xdebug_debug_zval() не выводит информации об этом, но вы можете проверить это также отобразив указатели памяти.

Удаление элемента из массива происходит точно так же, как и удаление имени переменной из области видимости: уменьшается "refcount" контейнера, на который ссылается элемент массива. Опять же, при достижении "refcount" нуля, контейнер удаляется из памяти. Пример:

Пример #7 Удаление элемента из массива

<?php
$a
= array( 'meaning' => 'life', 'number' => 42 );
$a['life'] = $a['meaning'];
unset(
$a['meaning'], $a['number'] );
xdebug_debug_zval( 'a' );
?>

Результатом выполнения данного примера будет что-то подобное:

a: (refcount=1, is_ref=0)=array (
   'life' => (refcount=1, is_ref=0)='life'
)

Ситуация станет интереснее, если добавить массив новым элементом в самого себя. В следующем примере мы также используем оператор присваивания по ссылке, чтобы PHP не создал копию массива.

Пример #8 Добавление массива новым элементом в самого себя

<?php
$a
= array( 'one' );
$a[] =& $a;
xdebug_debug_zval( 'a' );
?>

Результатом выполнения данного примера будет что-то подобное:

a: (refcount=2, is_ref=1)=array (
   0 => (refcount=1, is_ref=0)='one',
   1 => (refcount=2, is_ref=1)=...
)

Графически:

Контейнеры массива с циклическими ссылками

Можно увидеть, что переменная с массивом (a), так же как и второй элемент (1) сейчас указывают на контейнер с "refcount" равным 2. Символы "..." в выводе означают рекурсию и, в нашем случае, указывают на оригинальный массив.

Как и ранее, удаление переменной уменьшает счётчик ссылок контейнера на единицу. Если мы применим unset к переменной $a после вышеприведённого примера, то счётчик ссылок контейнера, на который указывают $a и элемент "1", изменится с "2" на "1":

Пример #9 Удаление $a

(refcount=1, is_ref=1)=array (
   0 => (refcount=1, is_ref=0)='one',
   1 => (refcount=1, is_ref=1)=...
)

Графически:

Контейнеры после удаления массива с циклическими ссылками, демонстрирующие утечку памяти

Суть проблемы

Хотя во всех областях видимости больше нет имени переменной, ссылающейся на данную структуру, она не может быть очищена, т.к. элемент массива "1" по-прежнему ссылается на этот массив. Т.к. теперь нет никакой возможности пользователю удалить эти данные, то мы получили утечку памяти. К счастью, PHP удалит эти данные при завершении запроса, но до этого момента данные будут занимать ценное место в памяти. Такая ситуация часто бывает, когда реализуются алгоритмы парсинга или другие, где есть дочерние элементы, ссылающиеся на родительские. Ещё чаще такая ситуация случается с объектами, потому что они всегда неявно используются по ссылке.

Эта не проблема, если такое случается раз или два, но если существуют тысячи или даже миллионы таких утечек памяти, то они уже становятся проблемой. Особенно в долгоработающих скриптах, таких как демоны, где запрос не заканчивается никогда, или в больших наборах модульных тестов. Последний случай вызвал проблемы при запуске модульных тестов для компонента Template из библиотеки ez Components. В некоторых случаях может потребоваться свыше 2 Гб памяти, которая не всегда есть на тестовом сервере.



Сбор циклических ссылок

Обычно механизмы подсчёта ссылок в памяти, например, используемый в PHP ранее, не решают проблему утечки памяти из-за циклических ссылок. Начиная с версии 5.3.0, в PHP реализован синхронный механизм из исследования "» Concurrent Cycle Collection in Reference Counted Systems", в котором рассматривается этот вопрос.

Полное описание работы алгоритма выходит за рамки данного раздела, поэтому приведены только основы. Прежде всего мы должны задать несколько основных правил. Если счётчик ссылок увеличивается, то контейнер всё ещё используется и не является мусором. Если счётчик уменьшается до нуля, то zval может быть удалён. Исходя из этих правил утечки памяти с циклическими ссылками могут получиться только при уменьшении счётчика ссылок до ненулевого значения. Затем, в выделенных контейнерах можно найти мусор проверив возможность уменьшения всех счётчиков ссылок на единицу и определив те контейнеры, у которых счётчик станет равным нулю.

Алгоритм сборки мусора

Для избежания постоянной проверки на мусор с циклическими ссылками при каждом уменьшении счётчика ссылок, алгоритм добавляет все возможные корни (zval контейнеры) в "корневой буфер" (помечая их как "фиолетовые"). Это также гарантирует попадание любого корня в буфер только один раз. Механизм сборки мусора стартует только тогда, когда наполняется буфер (смотрите шаг A на рисунке выше).

На шаге B алгоритм производит поиск в глубину по всем возможным корням для однократного уменьшения счётчика ссылок на единицу у всех контейнеров (помечая их как "серые"). На шаге C алгоритм снова производит поиск в глубину для проверки счётчиков ссылок. Если он находит счётчик с нулевым значением, то контейнер помечается как "белый" (на рисунке отображено синим). Если же счётчик больше нуля, то происходит поиск в глубину от этого контейнера с обратным увеличением счётчиков на единицу и повторной пометкой как "чёрный" на их контейнерах. На последнем шаге D алгоритм проходит по корневому буферу и удаляет из него корни контейнеров, заодно проверяя какие контейнеры помечены как "белые". Эти контейнеры будут освобождены из памяти.

Теперь, когда вы имеете представление о работе алгоритма, рассмотрим его интеграцию в PHP. По умолчанию сборщик мусора всегда включён. Для изменения этой опции используется параметр zend.enable_gc в php.ini.

Если сборщик мусора включён, алгоритм поиска циклических ссылок выполняется каждый раз, когда корневой буфер наполняется 10,000 корнями (вы можете поменять это значение, изменив константу GC_THRESHOLD_DEFAULT в файле Zend/zend_gc.c в исходном коде PHP и пересобрав PHP). Если сборщик мусора выключен, алгоритм никогда не будет запущен. Тем не менее, буфер всегда заполняется корнями.

Если буфер заполнился при выключенном механизме сборки мусора, то другие корни не будут в него записаны. Таким образом, если они окажутся мусором с циклическими ссылками, то никогда не будут очищены и создадут утечку памяти.

Причиной постоянной записи корней в буфер даже при выключенном механизме сборки мусора является то, что это намного быстрее, чем постоянно проверять включён ли механизм сборки мусора или нет. Однако, сама сборка мусора и алгоритм её анализа могут занимать значительное время.

Помимо изменения параметра zend.enable_gc, механизм сборки мусора также можно запустить и остановить вызвав функции gc_enable() и gc_disable() соответственно. Вызов этих функций имеет тот же эффект, что и включение/выключение механизма с помощью настроек конфигурации. Кроме того, можно запустить сборку мусора, даже если корневой буфер ещё не заполнен. Для этого вы можете вызвать функцию gc_collect_cycles(), которая также возвращает количество циклических ссылок собранных алгоритмом.

Причиной включения и выключения механизма сборки, а также его ручного запуска, может стать то, что некоторые части вашего приложения могут быть требовательными ко времени. В этих случаях вы, возможно, не захотите постороннего вмешательства сборщика мусора. Разумеется, выключая сборщик мусора в определённых местах вашего приложения вы рискуете получить утечку памяти, т.к. потенциально некоторые корни могут не поместиться в ограниченный корневой буфер. Более целесообразно будет вызвать gc_collect_cycles() непосредственно перед вызовом gc_disable() для освобождения памяти и уже записанных корней в буфере. Это очистит буфер и позволит использовать больше места для хранения корней, пока механизм будет выключен.



Вопросы производительности

В предыдущем разделе нами уже говорилось, что простой сбор корней меньше влияет на производительность. Хотя запись корней в буфер по сравнению с полным отсутствием таковой в PHP 5.2 работает медленней, другие изменения в работе PHP 5.3 сделали эту потерю производительности незаметной.

Есть две основные области влияющие на производительность: уменьшение размера используемой памяти и замедление работы при сборке мусора. Рассмотрим их.

Уменьшение размера используемой памяти

Прежде всего, основной причиной реализации механизма сборки мусора является уменьшение размера используемой памяти с помощью чистки циклических ссылок, которая происходит при достижении соответствующих условий. В реализации PHP это происходит как только заполнится корневой буфер или при вызове функции gc_collect_cycles(). На графике ниже приведено использование памяти скрипта, запущенного в PHP 5.2 и PHP 5.3, без учёта памяти, используемой самим PHP при запуске.

Пример #1 Пример использования памяти

<?php
class Foo
{
public
$var = '3.14159265359';
}

$baseMemory = memory_get_usage();

for (
$i = 0; $i <= 100000; $i++ )
{
$a = new Foo;
$a->self = $a;
if (
$i % 500 === 0 )
{
echo
sprintf( '%8d: ', $i ), memory_get_usage() - $baseMemory, "\n";
}
}
?>
Сравнение использования памяти в PHP 5.2 и PHP 5.3

В этом очень академическом примере мы создаём объект, свойство a которого задаётся ссылкой на сам объект. Когда в скрипте в следующей итерации цикла переопределяется переменная $a, то происходит типичная утечка памяти. В данном случае пропадают два контейнера zval (контейнер объекта и контейнер свойства объекта), но определяется только один корень - удалённая переменная. Как только пройдут 10 000 итераций (максимально в корневом буфере будет 10 000 корней), то запустится механизм сборки мусора и память, занимаемая этими корнями, будет освобождена. Этот процесс хорошо виден на графике использования памяти для PHP 5.3: после каждых 10 000 итераций график проседает. Сам по себе механизм в данном примере совершает не так много работы, потому что структура утечек слишком проста. Из графика видно, что максимальное использование памяти в PHP 5.3 составило около 9 Мб, тогда как в PHP 5.2 оно продолжает возрастать.

Замедление работы

Второй областью, где сборка мусора влияет на производительность, является потеря времени, когда сборщик мусора освобождает память. Чтобы понять степень этого влияния, мы немного изменим предыдущий скрипт, добавив большее число итераций и промежуточных переменных. Изменённый скрипт:

Пример #2 Влияние на производительность

<?php
class Foo
{
public
$var = '3.1415962654';
}

for (
$i = 0; $i <= 1000000; $i++ )
{
$a = new Foo;
$a->self = $a;
}

echo
memory_get_peak_usage(), "\n";
?>

Мы запустим скрипт два раза: с включённой опцией zend.enable_gc и без неё.

Пример #3 Запуск скрипта

time php -dzend.enable_gc=0 -dmemory_limit=-1 -n example2.php
# и
time php -dzend.enable_gc=1 -dmemory_limit=-1 -n example2.php

На тестовой машине первая команда примерно выполняется 10.7 секунд, а вторая примерно 11.4 секунды. Это примерно на 7% медленнее. Однако, максимальное использование памяти скриптом уменьшилось на 98% с 931 Мб до 10 Мб. Этот тест не очень научный, но он действительно демонстрирует преимущество по использованию памяти, обеспечиваемое сборщиком мусора. Также хорошо то, что замедление для этого скрипта всегда примерно 7%, тогда как экономия памяти увеличивается все больше и больше при нахождении нового мусора.

Внутренняя статистика сборщика мусора

Можно получить немного больше информации о том, как механизм сборки мусора выполняется в PHP. Но для этого вам необходимо пересобрать PHP для включения теста производительности и кода для дополнительного сбора данных. Необходимо установить переменную окружения CFLAGS в значение -DGC_BENCH=1 до выполнения команды ./configure с вашими параметрами. Следующие команды должны сработать:

Пример #4 Сборка PHP для включения теста производительности GC

export CFLAGS=-DGC_BENCH=1
./config.nice
make clean
make

При запуске вышеприведённого примера с обновлённым PHP, можно увидеть следующую информацию по завершении работы скрипта:

Пример #5 Статистика GC

GC Statistics
-------------
Runs:               110
Collected:          2072204
Root buffer length: 0
Root buffer peak:   10000

      Possible            Remove from  Marked
        Root    Buffered     buffer     grey
      --------  --------  -----------  ------
ZVAL   7175487   1491291    1241690   3611871
ZOBJ  28506264   1527980     677581   1025731

Наиболее полезная статистика отображена в первом блоке. Можно увидеть, что механизм сборки мусора был запущен 110 раз, и суммарно было освобождено свыше 2 миллионов записей в памяти. Если сборка мусора была запущена хотя бы раз, то максимальное число корней в буфере всегда будет равно 10 000.

Заключение

В целом, сборщик мусора в PHP вызовет ощутимые замедления только во время непосредственной работы механизма сборки циклических ссылок, тогда как в обычных (небольших) скриптах не должно быть никакого падения производительности.

Однако в тех случаях, когда механизм сборки должен срабатывать и в обычных скриптах, снижение используемой памяти позволяет одновременно работать на сервере большему их количеству.

Преимущества наиболее очевидны для долгоработающих скриптов, таких как большие наборы тестов или демоны. Новый механизм также должен снизить утечки памяти для приложений » PHP-GTK, которые выполняются обычно дольше, чем веб-скрипты.




Динамическая трассировка DTrace

Содержание


Введение в PHP и DTrace

DTrace - это всегда доступный, практически не потребляющий ресурсов фреймворк трассировки. Он доступен на множестве платформ, включая Solaris, macOS, Oracle Linux и BSD. DTrace может отслеживать поведение операционной системы и запущенных пользовательских приложений. Он может показывать значения параметров и используется для вывода статистики производительности. Зонды отслеживаются пользовательскими скриптами, написанными на скриптовом языке DTrace D. Это позволяет эффективно анализировать срезы данных.

Зонды PHP, которые не отслеживаются пользовательскими DTrace D скриптами, не содержат никакого дополнительного кода и, следовательно, во время нормальной работы приложения, никакой деградации производительности не происходит. Отслеживаемые зонды, в свою очередь, дают очень низкую просадку производительности, что позволяет использовать их в промышленных средах.

PHP включает в себя зонды "Статически определённой трассировки уровня пользователя" (User-level Statically Defined Tracing, или USDT), которые работают во время исполнения. К примеру, когда D-скрипт отслеживает зонд function-entry, то каждый раз при вызове функции, этот зонд запускает соответствующее действие D-скрипта. Это действие, например, печатает аргументы зонда, такие как расположение этой функции в PHP-скрипте. Или же это может быть агрегация данных, таких как количество запусков каждой из функции.

Здесь описываются только зонды PHP USDT. Для получения информации о том, как следить за произвольными функциями и отслеживать поведение операционной системы, читайте соответствующую литературу, специфичную для каждой операционной системы и внешнюю полноценную документацию DTrace. Обратите внимание, что различные реализации DTrace могут отличаться набором доступного функционала.

Статические зонды DTrace в PHP, также могут быть использованы с SystemTap в некоторых дистрибутивах Linux.



Использование PHP и DTrace

PHP может быть сконфигурирован со статическими зондами DTrace на платформах поддерживающих динамическую трассировку DTrace.

Конфигурирование PHP со статическими зондами DTrace

Обратитесь к документации вашей платформы, чтобы включить поддержку DTrace в вашей операционной системе. К примеру, в Oracle Linux необходимо загрузить ядро UEK3 и сделать следующее:

# modprobe fasttrap
# chmod 666 /dev/dtrace/helper

Вместо chmod, вы можете использовать пакет правил ACL для ограничения доступа для конкретного пользователя.

Сборка PHP с ключом --enable-dtrace:

# ./configure --enable-dtrace ...
# make
# make install

Это включит статические зонды в ядре PHP. Любой модуль PHP, предоставляющий собственные зонды, должен быть собран отдельно как разделяемый модуль.

Статические зонды DTrace в ядре PHP

Следующие статические зонды доступны в PHP
Имя зонда Описание зонда Аргументы зонда
request-startup Срабатывает при начале запроса. char *file, char *request_uri, char *request_method
request-shutdown Срабатывает при окончании запроса. char *file, char *request_uri, char *request_method
compile-file-entry Срабатывает, когда начинается компиляция скрипта. char *compile_file, char *compile_file_translated
compile-file-return Срабатывает, когда заканчивается компиляция скрипта. char *compile_file, char *compile_file_translated
execute-entry Срабатывает, когда запускается массив байт-кода. К примеру, когда вызываются функции, возобновляется работа генератора или происходит include. char *request_file, int lineno
execute-return Срабатывает, после отработки массива байт-кода. char *request_file, int lineno
function-entry Срабатывает, когда движок PHP начинает запуск функции или метода. char *function_name, char *request_file, int lineno, char *classname, char *scope
function-return Срабатывает, когда движок PHP возвращается из функции или метода. char *function_name, char *request_file, int lineno, char *classname, char *scope
exception-thrown Срабатывает, когда выброшено исключение. char *classname
exception-caught Срабатывает, когда исключение поймано. char *classname
error Срабатывает если произошла ошибка, вне зависимости от уровня error_reporting. char *errormsg, char *request_file, int lineno

Модули PHP могут содержать дополнительные зонды.

Список статических зондов DTrace в PHP

Для получения списка зондов, запустите процесс PHP и выполните:

# dtrace -l

Вывод будет примерно такой:

   ID   PROVIDER            MODULE                          FUNCTION NAME
   [ . . . ]
    4   php15271               php               dtrace_compile_file compile-file-entry
    5   php15271               php               dtrace_compile_file compile-file-return
    6   php15271               php                        zend_error error
    7   php15271               php  ZEND_CATCH_SPEC_CONST_CV_HANDLER exception-caught
    8   php15271               php     zend_throw_exception_internal exception-thrown
    9   php15271               php                 dtrace_execute_ex execute-entry
   10   php15271               php           dtrace_execute_internal execute-entry
   11   php15271               php                 dtrace_execute_ex execute-return
   12   php15271               php           dtrace_execute_internal execute-return
   13   php15271               php                 dtrace_execute_ex function-entry
   14   php15271               php                 dtrace_execute_ex function-return
   15   php15271               php              php_request_shutdown request-shutdown
   16   php15271               php               php_request_startup request-startup

Колонка Provider содержит надпись php и pid текущего запущенного процесса PHP.

Если запущен веб-сервер Apache, имя модуля может быть, например, libphp5.so, и может быть множество блоков списка, по одному на каждый процесс Apache.

Колонка Function ссылается на имя внутренней С-функции PHP, реализующей соответствующий зонд.

Если PHP не запущен, то связанных с ним зондов в списке не будет.

Примеры использования DTrace с PHP

Этот пример показывает базовые возможности скриптового языка DTrace D.

Пример #1 all_probes.d - трассировка всех статических зондов PHP с помощью DTrace

#!/usr/sbin/dtrace -Zs

#pragma D option quiet

php*:::compile-file-entry
{
    printf("PHP compile-file-entry\n");
    printf("  compile_file              %s\n", copyinstr(arg0));
    printf("  compile_file_translated   %s\n", copyinstr(arg1));
}

php*:::compile-file-return
{
    printf("PHP compile-file-return\n");
    printf("  compile_file              %s\n", copyinstr(arg0));
    printf("  compile_file_translated   %s\n", copyinstr(arg1));
}

php*:::error
{
    printf("PHP error\n");
    printf("  errormsg                  %s\n", copyinstr(arg0));
    printf("  request_file              %s\n", copyinstr(arg1));
    printf("  lineno                    %d\n", (int)arg2);
}

php*:::exception-caught
{
    printf("PHP exception-caught\n");
    printf("  classname                 %s\n", copyinstr(arg0));
}

php*:::exception-thrown
{
    printf("PHP exception-thrown\n");
    printf("  classname                 %s\n", copyinstr(arg0));
}

php*:::execute-entry
{
    printf("PHP execute-entry\n");
    printf("  request_file              %s\n", copyinstr(arg0));
    printf("  lineno                    %d\n", (int)arg1);
}

php*:::execute-return
{
    printf("PHP execute-return\n");
    printf("  request_file              %s\n", copyinstr(arg0));
    printf("  lineno                    %d\n", (int)arg1);
}

php*:::function-entry
{
    printf("PHP function-entry\n");
    printf("  function_name             %s\n", copyinstr(arg0));
    printf("  request_file              %s\n", copyinstr(arg1));
    printf("  lineno                    %d\n", (int)arg2);
    printf("  classname                 %s\n", copyinstr(arg3));
    printf("  scope                     %s\n", copyinstr(arg4));
}

php*:::function-return
{
    printf("PHP function-return\n");
    printf("  function_name             %s\n", copyinstr(arg0));
    printf("  request_file              %s\n", copyinstr(arg1));
    printf("  lineno                    %d\n", (int)arg2);
    printf("  classname                 %s\n", copyinstr(arg3));
    printf("  scope                     %s\n", copyinstr(arg4));
}

php*:::request-shutdown
{
    printf("PHP request-shutdown\n");
    printf("  file                      %s\n", copyinstr(arg0));
    printf("  request_uri               %s\n", copyinstr(arg1));
    printf("  request_method            %s\n", copyinstr(arg2));
}

php*:::request-startup
{
    printf("PHP request-startup\n");
    printf("  file                      %s\n", copyinstr(arg0));
    printf("  request_uri               %s\n", copyinstr(arg1));
    printf("  request_method            %s\n", copyinstr(arg2));
}

Этот скрипт использует опцию -Z для dtrace, позволяя ему работать даже если ни одного процесса PHP не запущено. Если не использовать эту опцию, то скрипт сразу же завершит выполнения, поскольку не увидит ни одного зонда, который ему надо отслеживать.

Скрипт отслеживает все статические зонды PHP на всем протяжении работы PHP-скрипта. Запускаем D-скрипт:

# ./all_probes.d

Запустите скрипт или приложение PHP. Отслеживающий D-скрипт будет выводить аргументы всех сработавших зондов.

Когда вы увидели все, что хотели, прервать работу скрипта можно комбинацией CTRL+C.

На многопроцессорных машинах, порядок зондов может быть не последовательным, в зависимости от того, на каких процессорах работают зонды и как мигрируют потоки между процессорами. Отображение временных меток позволит избежать конфузов. К примеру:

php*:::function-entry
{
      printf("%lld: PHP function-entry ", walltimestamp);
      [ . . .]
}



Использование SystemTap со статическими зондами PHP DTrace

В некоторых дистрибутивах Linux, можно использовать утилиту трассировки SystemTap для отслеживания статических зондов DTrace. Данный вариант доступен в PHP 5.4.20 и PHP 5.5.

Установка PHP с SystemTap

Установите разработческий пакет SystemTap SDT:

# yum install systemtap-sdt-devel

Установите PHP с DTrace:

# ./configure --enable-dtrace ...
# make

Получение списка статических зондов с помощью SystemTap

Статические зонды PHP можно посмотреть используя stap:

# stap -l 'process.provider("php").mark("*")' -c 'sapi/cli/php -i'

Примерный вывод:

process("sapi/cli/php").provider("php").mark("compile__file__entry")
process("sapi/cli/php").provider("php").mark("compile__file__return")
process("sapi/cli/php").provider("php").mark("error")
process("sapi/cli/php").provider("php").mark("exception__caught")
process("sapi/cli/php").provider("php").mark("exception__thrown")
process("sapi/cli/php").provider("php").mark("execute__entry")
process("sapi/cli/php").provider("php").mark("execute__return")
process("sapi/cli/php").provider("php").mark("function__entry")
process("sapi/cli/php").provider("php").mark("function__return")
process("sapi/cli/php").provider("php").mark("request__shutdown")
process("sapi/cli/php").provider("php").mark("request__startup")

Пример использования SystemTap с PHP

Пример #1 all_probes.stp - трассировка всех статических зондов PHP

probe process("sapi/cli/php").provider("php").mark("compile__file__entry") {
    printf("Probe compile__file__entry\n");
    printf("  compile_file %s\n", user_string($arg1));
    printf("  compile_file_translated %s\n", user_string($arg2));
}
probe process("sapi/cli/php").provider("php").mark("compile__file__return") {
    printf("Probe compile__file__return\n");
    printf("  compile_file %s\n", user_string($arg1));
    printf("  compile_file_translated %s\n", user_string($arg2));
}
probe process("sapi/cli/php").provider("php").mark("error") {
    printf("Probe error\n");
    printf("  errormsg %s\n", user_string($arg1));
    printf("  request_file %s\n", user_string($arg2));
    printf("  lineno %d\n", $arg3);
}
probe process("sapi/cli/php").provider("php").mark("exception__caught") {
    printf("Probe exception__caught\n");
    printf("  classname %s\n", user_string($arg1));
}
probe process("sapi/cli/php").provider("php").mark("exception__thrown") {
    printf("Probe exception__thrown\n");
    printf("  classname %s\n", user_string($arg1));
}
probe process("sapi/cli/php").provider("php").mark("execute__entry") {
    printf("Probe execute__entry\n");
    printf("  request_file %s\n", user_string($arg1));
    printf("  lineno %d\n", $arg2);
}
probe process("sapi/cli/php").provider("php").mark("execute__return") {
    printf("Probe execute__return\n");
    printf("  request_file %s\n", user_string($arg1));
    printf("  lineno %d\n", $arg2);
}
probe process("sapi/cli/php").provider("php").mark("function__entry") {
    printf("Probe function__entry\n");
    printf("  function_name %s\n", user_string($arg1));
    printf("  request_file %s\n", user_string($arg2));
    printf("  lineno %d\n", $arg3);
    printf("  classname %s\n", user_string($arg4));
    printf("  scope %s\n", user_string($arg5));
}
probe process("sapi/cli/php").provider("php").mark("function__return") {
    printf("Probe function__return: %s\n", user_string($arg1));
    printf(" function_name %s\n", user_string($arg1));
    printf("  request_file %s\n", user_string($arg2));
    printf("  lineno %d\n", $arg3);
    printf("  classname %s\n", user_string($arg4));
    printf("  scope %s\n", user_string($arg5));
}
probe process("sapi/cli/php").provider("php").mark("request__shutdown") {
    printf("Probe request__shutdown\n");
    printf("  file %s\n", user_string($arg1));
    printf("  request_uri %s\n", user_string($arg2));
    printf("  request_method %s\n", user_string($arg3));
}
probe process("sapi/cli/php").provider("php").mark("request__startup") {
    printf("Probe request__startup\n");
    printf("  file %s\n", user_string($arg1));
    printf("  request_uri %s\n", user_string($arg2));
    printf("  request_method %s\n", user_string($arg3));
}

Приведённый выше скрипт будет выводить данные статических зондов PHP на всем протяжении работы PHP-скрипта:

# stap -c 'sapi/cli/php test.php' all_probes.stp





Справочник функций

Подсказка

Смотрите также Список/классификация модулей.


Изменение поведения PHP


Пользовательский кеш APC


Введение

APCu - это хранилище "ключ-значение" в памяти для PHP. Ключи являются строками (string), а значения могут быть любыми переменными PHP. APCu поддерживает только кеширование переменных в пользовательском пространстве.

В Windows кеш APCu относится к каждому процессу, поэтому при использовании SAPI, основанного на процессах (а не на потоках), он не будет разделяться между различными процессами.

APCu - это APC без кеширования опкода.

Первая версия APCu имеет номер 4.0.0, так как она была клонирована из основной кодовой ветви APC. Поддержка PHP 7 доступна, начиная с APCu 5.0.0. Поддержка PHP 8 доступна, начиная с APCu 5.1.19.



Установка и настройка

Содержание


Требования

Для сборки этого модуля не требуются внешние библиотеки.



Установка

Информация по установке этого модуля PECL может быть найдена в главе руководства Установка PECL модулей. Дополнительная информация, такая как новые версии, скачивание, исходные файлы, информация о разработчике и CHANGELOG, может быть найдена здесь: » https://pecl.php.net/package/apcu.

Подсказка

В PHP 7 есть отдельный модуль (» apcu-bc) для обратной совместимости с APC.

В режиме обратной совместимости, APCu регистрирует применимые функции APC с помощью специальных, обратно совместимых, прототипов.

Если функция APC принимает параметр cache_type, он просто игнорируется и опускается в прототипе функции APCu.

Внимание

Начиная с PHP 8.0.0, apcu-bc больше не поддерживается.

Замечание: В Windows, APCu необходимо, чтобы был задана временная директория и веб-сервер имел право туда писать. Модуль проверяет переменные окружающей среды в таком порядке: TMP, TEMP, USERPROFILE. Если ни одна из них не задана, то модуль пытается работать с каталогом WINDOWS.

Замечание: Крайне подробная, в техническом плане, документация о реализации этого модуля доступна в » предоставленном разработчиком файле TECHNOTES.

Исходные коды APCu можно найти » тут.



Настройка во время выполнения

Поведение этих функций зависит от установок в php.ini.

Хотя настроек APCu по умолчанию вполне достаточно для большинства задач, но для серьёзных проектов необходимо внимательно изучить следующие настройки.

При настройке APCu необходимо определиться, сколько памяти предоставить в распоряжение APCu. Директива ini-файла, ответственная за эту настройку - apc.shm_size. Внимательно прочитайте нижеследующий раздел.

После запуска сервера скрипт apc.php, который поставляется вместе с модулем, следует скопировать в docroot и просмотреть в браузере, поскольку он предоставляет подробный анализ внутренней работы APCu. Если в PHP включён модуль GD, он даже отобразит некоторые интересные графики.

Если APCu работает, число Cache full count (слева) покажет, сколько раз кеш достигал максимальной ёмкости и был вынужден вытеснять записи, чтобы освободить память. Во время вытеснения, если было указано значение apc.ttl, APCu сначала попытается удалить записи с истёкшим сроком действия, т.е. записи, TTL которых либо истёк, либо записи, у которых TTL не установлен и к которым не было доступа в течение последних apc.ttl секунд. Если значение apc.ttl не было установлена или удаление истёкших записей не освободило достаточно места, APCu очистит весь кеш.

В хорошо настроенном кеше количество вытеснений должно быть минимальным. Если кеш постоянно заполняется и, следовательно, принудительно освобождается, то возникающая в результате этого возня негативно скажется на производительности скрипта. Самый простой способ минимизировать это число - выделить больше памяти для APCu.

Если APCu собран с поддержкой mmap (Memory Mapping), он будет использовать всего один сегмент памяти, если же наоборот, APC собран с поддержкой SHM (SysV Shared Memory), он будет использовать несколько сегментов. MMAP не имеет максимального ограничения, в отличие от SHM, который ограничивается /proc/sys/kernel/shmmax. Обычно рекомендуется использовать MMAP, потому что он гораздо быстрее выделяет память при перезагрузке веб-сервера, что сказывается на скорости запуска сервера.

Опции конфигурации APCu
Имя По умолчанию Место изменения Список изменений
apc.enabled "1" PHP_INI_SYSTEM  
apc.shm_segments "1" PHP_INI_SYSTEM  
apc.shm_size "32M" PHP_INI_SYSTEM  
apc.entries_hint "4096" PHP_INI_SYSTEM  
apc.ttl "0" PHP_INI_SYSTEM  
apc.gc_ttl "3600" PHP_INI_SYSTEM  
apc.mmap_file_mask NULL PHP_INI_SYSTEM  
apc.slam_defense "1" PHP_INI_SYSTEM  
apc.enable_cli "0" PHP_INI_SYSTEM  
apc.use_request_time "0" PHP_INI_ALL До APCu 5.1.19 значение по умолчанию было "1".
apc.serializer "php" PHP_INI_SYSTEM До APCu 5.1.19 значение по умолчанию было "default".
apc.coredump_unmap "0" PHP_INI_SYSTEM  
apc.preload_path NULL PHP_INI_SYSTEM  
Для подробного описания констант PHP_INI_*, обратитесь к разделу Где могут быть установлены параметры конфигурации.

Краткое разъяснение конфигурационных директив.

apc.enabled bool

Если установить apc.enabled равным 0, то APCu не будет запущен. Это полезно, когда APCu статически включён в PHP и нет других вариантов, для запрещения его использования. Если APC собран как DSO, можно просто закомментировать строку extension в php.ini.

apc.shm_segments int

Количество сегментов разделяемой памяти выделенной под кеш. Если APC использовал всю доступную разделяемую память, а apc.shm_size таким большим, как позволяет система, увеличение этого параметра может помочь.

apc.shm_size string

Размер сегмента разделяемой памяти, заданный в короткой нотации (смотрите этот FAQ). По умолчанию, некоторые системы (включая большинство вариантов BSD) ограничивают это значение крайне малым значением.

apc.entries_hint int

Это подсказка о количестве уникальных пользовательских переменных, которые надо кешировать. Установите равным нулю или вообще не указывайте, если не уверены.

apc.ttl int

Записи кеша без явного указания TTL считаются истёкшими, если к ним не обращались в течение этого количества секунд. По сути, это позволяет удалять такие записи оппортунистически во время добавления кеша или перед полным удалением. Обратите внимание, что поскольку удаление происходит по обстоятельствам, записи могут быть доступны для чтения, даже если их срок жизни превышает apc.ttl секунд. Параметр не влияет на записи кеша, для которых явно задан TTL.

apc.gc_ttl int

Количество секунд, которые запись может находиться в списке сборщика мусора. Это значение обеспечивает безотказность в случае падения сервера в момент исполнения закешированного файла. Если исполняемый файл был изменён, память, выделенная под кеширование его старой версии, не будет возвращена до истечения этого времени. Установка в ноль отключает этот функционал.

apc.mmap_file_mask string

Если собран с поддержкой MMAP, с помощью опции --enable-mmap, этот параметр должен содержать файловую маску типа mktemp-style для передачи в модуль MMAP, чтобы определить, будет ли MMAP использовать файловую систему или разделяемую память. Для файловой системы задайте опцию как /tmp/apc.XXXXXX (ровно 6 X). Для использования shm_open/mmap в стиле POSIX, добавьте .shm в любом месте маски, например /apc.shm.XXXXXX Вы также можете установить его как /dev/zero для использования интерфейса ядра /dev/zero для анонимной памяти mmap. Если не задано, то будет принудительно использоваться анонимный mmap.

apc.slam_defense int

На очень загруженных серверах, когда вы запускаете веб-сервер, сразу множество процессов будут пытаться закешировать один и тот же файл одновременно. Этой опцией задаётся вероятность, в процентах, того, что попытка одного конкретного процесса закешировать данные будет отклонена. Например, если apc.slam_defense установить равной 75, то это означает, что вероятность закешировать файл, которого в кеше нет, будет равна 25% и вероятность того, что в кешировании будет отказано равна 75%. Для запрета данного функционала установите этот параметр равным 0.

apc.enable_cli int

Больше для тестирования и отладки. Эта настройка включает APCu для CLI версии PHP. При обычной работе, запускать APCu, который будет создавать, наполнять и уничтожать кеш при каждом запуске сценария в консоли, будет далеко не лучшей идеей. Но в целях тестирования и отладки, можно легко включить APCu для CLI.

apc.serializer string

Указывает APC использовать сторонний сериализатор.

apc.coredump_unmap bool

Разрешает APC перехватывать сигналы, такие как SIGSEGV, который записывает coredump, когда подан. Когда эти сигналы будут получены, APC попытается освободить всю разделяемую память, чтобы не включать её в coredump. Эта настройка может увеличить стабильность системы, когда критический сигнал был получен, а APC сконфигурирован на использование большого объёма памяти.

Внимание

Эта возможность потенциально опасна. Освобождение сегментов разделяемой памяти при получении критического сигнала может привести к непредсказуемому поведению.

Замечание:

Хотя некоторые ядра предоставляют возможность игнорировать некоторые сегменты разделяемой памяти при записи core-файла, эти реализации могут также игнорировать важные сегменты памяти, такие как Apache scoreboard.

apc.preload_path string

Опционально. Задаёт путь, который используется APC для загрузки кешированных данных во время запуска.

apc.use_request_time bool

Использовать время старта запроса SAPI для TTL.



Типы ресурсов

Данный модуль не определяет каких-либо типов ресурсов.




Предопределённые константы

Перечисленные ниже константы определены данным модулем и могут быть доступны только в том случае, если PHP был собран с поддержкой этого модуля или же в том случае, если данный модуль был динамически загружен во время выполнения.

APC_ITER_ALL (int)
APC_ITER_ATIME (int)
APC_ITER_CTIME (int)
APC_ITER_DEVICE (int)
APC_ITER_DTIME (int)
APC_ITER_FILENAME (int)
APC_ITER_INODE (int)
APC_ITER_KEY (int)
APC_ITER_MD5 (int)
APC_ITER_MEM_SIZE (int)
APC_ITER_MTIME (int)
APC_ITER_NONE (int)
APC_ITER_NUM_HITS (int)
APC_ITER_REFCOUNT (int)
APC_ITER_TTL (int)
APC_ITER_TYPE (int)
APC_ITER_VALUE (int)
APC_LIST_ACTIVE (int)
APC_LIST_DELETED (int)



Функции APCu


apcu_add

(PECL apcu >= 4.0.0)

apcu_add Добавить переменную в кеш

Описание

apcu_add(string $key, mixed $var, int $ttl = 0): bool
apcu_add(array $values, mixed $unused = NULL, int $ttl = 0): array

Добавляет переменную в кеш, если её там ещё нет.

Замечание: В отличие от многих других механизмов PHP, переменные, сохранённые apcu_add(), сохраняются между запросами, пока их не удалят из кеша.

Список параметров

key

Имя, под которым будет сохранена переменная. Значение key является уникальным для кеша, так что попытка использовать apcu_add() для сохранения переменной с ключом, который уже существует, не перезапишет запись, а вернёт false. (Это единственное различие между apcu_add() и apcu_store().)

var

Переменная для сохранения

ttl

Время жизни; переменная var будет храниться в течение ttl секунд. Как только ttl секунд пройдут, переменная будет удалена из кеша (при следующем запросе). Если параметр ttl не задан (или ttl задан как 0), значение будет храниться пока не будет удалено явно, либо по технической причине (очистка кеша, перезапуск и т.д.)

values

Имена в ключах, переменные в значениях.

Возвращаемые значения

Возвращает true, если удалось занести значение в кеш, в противном случае возвращает false. Второй тип синтаксиса возвращает массив с ключами, по которым произошла ошибка.

Примеры

Пример #1 Пример использования apcu_add()

<?php
$bar
= 'BAR';
apcu_add('foo', $bar);
var_dump(apcu_fetch('foo'));
echo
"\n";
$bar = 'NEVER GETS SET';
apcu_add('foo', $bar);
var_dump(apcu_fetch('foo'));
echo
"\n";
?>

Результат выполнения данного примера:

string(3) "BAR"
string(3) "BAR"

Смотрите также

  • apcu_store() - Кеширует переменную
  • apcu_fetch() - Извлекает из кеша сохранённую переменную
  • apcu_delete() - Удаляет сохранённое значение из кеша



apcu_cache_info

(PECL apcu >= 4.0.0)

apcu_cache_info Извлекает закешированную информацию из хранилища APCu

Описание

apcu_cache_info(bool $limited = false): array|false

Извлекает закешированную информацию из хранилища APCu.

Список параметров

limited

Если limited задан как true, возвращаемое значение не будет содержать индивидуальный список записей кеша. Это полезно при попытках оптимизировать вызовы для получения статистики.

Возвращаемые значения

Массив кешированных данных (и метаданные) или false в случае возникновения ошибки

Замечание: apcu_cache_info() вызывает предупреждение, если невозможно получить данные кеша APC. Обычно это происходит, если APC не разрешён.

Список изменений

Версия Описание
PECL apcu 3.0.11 Добавлен параметр limited.
PECL apcu 3.0.16 Добавлена опция "filehits" для параметра cache_type.

Примеры

Пример #1 Пример использования apcu_cache_info()

<?php
print_r
(apcu_cache_info());
?>

Результатом выполнения данного примера будет что-то подобное:

Array
(
    [num_slots] => 2000
    [ttl] => 0
    [num_hits] => 9
    [num_misses] => 3
    [start_time] => 1123958803
    [cache_list] => Array
        (
            [0] => Array
                (
                    [filename] => /path/to/apcu_test.php
                    [device] => 29954
                    [inode] => 1130511
                    [type] => file
                    [num_hits] => 1
                    [mtime] => 1123960686
                    [creation_time] => 1123960696
                    [deletion_time] => 0
                    [access_time] => 1123962864
                    [ref_count] => 1
                    [mem_size] => 677
                )
            [1] => Array (...итерирует для каждого закешированного файла)
)

Смотрите также



apcu_cas

(PECL apcu >= 4.0.0)

apcu_casЗаменяет старое значение на новое

Описание

apcu_cas(string $key, int $old, int $new): bool

apcu_cas() заменяет значение уже существующего целочисленного значения, если оно равно old на new.

Список параметров

key

Ключ изменяемого значения.

old

Старое значение (которое в данный момент хранится в кеше).

new

Новое значение.

Возвращаемые значения

Возвращает true в случае успешного выполнения или false в случае возникновения ошибки.

Примеры

Пример #1 Пример использования apcu_cas()

<?php
apcu_store
('foobar', 2);
echo
'$foobar = 2', PHP_EOL;
echo
'$foobar == 1 ? 2 : 1 = ', (apcu_cas('foobar', 1, 2) ? 'ok' : 'fail'), PHP_EOL;
echo
'$foobar == 2 ? 1 : 2 = ', (apcu_cas('foobar', 2, 1) ? 'ok' : 'fail'), PHP_EOL;

echo
'$foobar = ', apcu_fetch('foobar'), PHP_EOL;

echo
'$f__bar == 1 ? 2 : 1 = ', (apcu_cas('f__bar', 1, 2) ? 'ok' : 'fail'), PHP_EOL;

apcu_store('perfection', 'xyz');
echo
'$perfection == 2 ? 1 : 2 = ', (apcu_cas('perfection', 2, 1) ? 'ok' : 'epic fail'), PHP_EOL;

echo
'$foobar = ', apcu_fetch('foobar'), PHP_EOL;
?>

Результатом выполнения данного примера будет что-то подобное:

$foobar = 2
$foobar == 1 ? 2 : 1 = fail
$foobar == 2 ? 1 : 2 = ok
$foobar = 1
$f__bar == 1 ? 2 : 1 = fail
$perfection == 2 ? 1 : 2 = epic fail
$foobar = 1

Смотрите также

  • apcu_dec() - Уменьшить сохранённое число
  • apcu_store() - Кеширует переменную


apcu_clear_cache

(PECL apcu >= 4.0.0)

apcu_clear_cache Очистить кеш APCu

Описание

apcu_clear_cache(): bool

Очищает кеш APCu.

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Всегда возвращает true

Смотрите также

  • apcu_cache_info() - Извлекает закешированную информацию из хранилища APCu



apcu_dec

(PECL apcu >= 4.0.0)

apcu_decУменьшить сохранённое число

Описание

apcu_dec(
    string $key,
    int $step = 1,
    bool &$success = ?,
    int $ttl = 0
): int|false

Уменьшает сохранённое число.

Список параметров

key

Ключ значения, которое надо уменьшить.

step

Величина, на которую необходимо уменьшить.

success

Необязательный параметр. Если задан, то в него будет записано логическое значение true или false в зависимости от успешности операции уменьшения.

ttl

TTL(время жизни), используемое если операция вставляет новое значение (а не уменьшает существующее).

Возвращаемые значения

Возвращает текущее значение key в случае успешного выполнения или false в случае возникновения ошибки

Примеры

Пример #1 Пример использования apcu_dec()

<?php
echo "Сделаем что-то без ошибки", PHP_EOL;

apcu_store('anumber', 42);

echo
apcu_fetch('anumber'), PHP_EOL;

echo
apcu_dec('anumber'), PHP_EOL;
echo
apcu_dec('anumber', 10), PHP_EOL;
echo
apcu_dec('anumber', 10, $success), PHP_EOL;

var_dump($success);

echo
"А теперь с ошибкой", PHP_EOL, PHP_EOL;

apcu_store('astring', 'foo');

$ret = apcu_dec('astring', 1, $fail);

var_dump($ret);
var_dump($fail);
?>

Результатом выполнения данного примера будет что-то подобное:

Сделаем что-то без ошибки
42
41
31
21
bool(true)
А теперь с ошибкой

bool(false)
bool(false)

Смотрите также

  • apcu_inc() - Увеличить сохранённое число


apcu_delete

(PECL apcu >= 4.0.0)

apcu_delete Удаляет сохранённое значение из кеша

Описание

apcu_delete(mixed $key): mixed

Удаляет сохранённое значение из кеша.

Список параметров

key

key можно задать как строку, для удаления одного значения, либо как массив строк, для удаления нескольких значений, либо как объект APCUIterator.

Возвращаемые значения

Если key является массивом (array), возвращается индексированный массив (array) ключей. В противном случае возвращается true в случае успешного выполнения или false в случае возникновения ошибки.

Примеры

Пример #1 Пример использования apcu_delete()

<?php
$bar
= 'BAR';
apcu_store('foo', $bar);

//Удаляем одну запись.
apcu_delete('foo');

// Удаляем несколько записей.
apcu_delete(['foo', 'bar', 'baz']);

// Используем итератор с регулярным выражением.
apcu_delete(new APCUIterator('#^myprefix_#'));
?>

Смотрите также



apcu_enabled

(PECL apcu >= 4.0.3)

apcu_enabledВозможно ли использовать APCu в текущем окружении

Описание

apcu_enabled(): bool

Определяет, возможно ли использовать APCu в текущем окружении.

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Возвращает true или false в зависимости от возможности использовать APCu.



apcu_entry

(PECL apcu >= 5.1.0)

apcu_entry Автоматическое извлечение или создание записи в кеше

Описание

apcu_entry(string $key, callable $generator, int $ttl = 0): mixed

Автоматически пытается найти запись с заданным ключом key. Если не может, то вызывается генератор generator и ему передаётся ключ key как единственный аргумент. Сгенерированное значение заносится в кеш с указанным ttl и возвращается.

Замечание: Когда контроль передаётся apcu_entry(), производится эксклюзивная блокировка кеша, которая снимается после завершения работы apcu_entry(): это приводит к тому, что тело генератора generator помещается в критическую секцию, запрещая двум процессам запустить выполнение одинакового кода конкурентно. К тому же, это приводит к запрету конкурентного запуска любых других функций APCu, так как они будут выставлять ту же блокировку.

Внимание

Единственная функция APCu, которую можно безопасно вызывать в генераторе generator - это apcu_entry().

Список параметров

key

Идентификатор записи

generator

Callback-функция, принимающая один параметр key и возвращающая значение для кеширования.

ttl

Время жизни; переменная var будет храниться в течение ttl секунд. Как только ttl секунд пройдут, переменная будет удалена из кеша (при следующем запросе). Если параметр ttl не задан (или ttl задан как 0), значение будет храниться пока не будет удалено явно, либо по технической причине (очистка кеша, перезапуск и т.д.)

Возвращаемые значения

Возвращает закешированное значение

Примеры

Пример #1 Пример использования apcu_entry()

<?php
$config
= apcu_entry("config", function($key) {
return [
"fruit" => apcu_entry("config.fruit", function($key){
return [
"apples",
"pears"
];
}),
"people" => apcu_entry("config.people", function($key){
return [
"bob",
"joe",
"niki"
];
})
];
});

var_dump($config);
?>

Результат выполнения данного примера:

array(2) {
  ["fruit"]=>
  array(2) {
    [0]=>
    string(6) "apples"
    [1]=>
    string(5) "pears"
  }
  ["people"]=>
  array(3) {
    [0]=>
    string(3) "bob"
    [1]=>
    string(3) "joe"
    [2]=>
    string(4) "niki"
  }
}

Смотрите также

  • apcu_store() - Кеширует переменную
  • apcu_fetch() - Извлекает из кеша сохранённую переменную
  • apcu_delete() - Удаляет сохранённое значение из кеша



apcu_exists

(PECL apcu >= 4.0.0)

apcu_existsПроверяет, существуют ли записи

Описание

apcu_exists(mixed $keys): mixed

Проверяет, существуют ли записи.

Список параметров

keys

Строка или массив строк, содержащие ключи для проверки.

Возвращаемые значения

Возвращает true, если ключ существует или false, если нет. Если же был передан массив ключей, то вернётся массив с существующими ключами, либо пустой массив, если ни одного ключа не существует.

Примеры

Пример #1 Пример использования apcu_exists()

<?php
$fruit
= 'apple';
$veggie = 'carrot';

apcu_store('foo', $fruit);
apcu_store('bar', $veggie);

if (
apcu_exists('foo')) {
echo
"Foo с: ";
echo
apcu_fetch('foo');
} else {
echo
"Foo не существует";
}

echo
PHP_EOL;
if (
apcu_exists('baz')) {
echo
"Baz не существует.";
} else {
echo
"Baz не существует";
}

echo
PHP_EOL;

$ret = apcu_exists(array('foo', 'donotexist', 'bar'));
var_dump($ret);

?>

Результатом выполнения данного примера будет что-то подобное:

Foo существует: apple
Baz не существует
array(2) {
  ["foo"]=>
  bool(true)
  ["bar"]=>
  bool(true)
}

Смотрите также

  • apcu_cache_info() - Извлекает закешированную информацию из хранилища APCu
  • apcu_fetch() - Извлекает из кеша сохранённую переменную


apcu_fetch

(PECL apcu >= 4.0.0)

apcu_fetch Извлекает из кеша сохранённую переменную

Описание

apcu_fetch(mixed $key, bool &$success = ?): mixed

Извлекает из кеша сохранённую переменную.

Список параметров

key

Ключ key, под которым запись была сохранена в кеш (с помощью apcu_store()). Если задан массив, то будет извлечён и возвращён каждый элемент.

success

Устанавливается в true в случае успешного выполнения и false в случае возникновения ошибки.

Возвращаемые значения

Сохранённая переменная либо массив; false в случае возникновения ошибки

Список изменений

Версия Описание
PECL apcu 3.0.17 Добавлен параметр success.

Примеры

Пример #1 Пример использования apcu_fetch()

<?php
$bar
= 'BAR';
apcu_store('foo', $bar);
var_dump(apcu_fetch('foo'));
?>

Результат выполнения данного примера:

string(3) "BAR"

Смотрите также



apcu_inc

(PECL apcu >= 4.0.0)

apcu_incУвеличить сохранённое число

Описание

apcu_inc(
    string $key,
    int $step = 1,
    bool &$success = ?,
    int $ttl = 0
): int|false

Увеличивает сохранённое число.

Список параметров

key

Ключ значения, которое надо увеличить.

step

Величина, на которую необходимо увеличить.

success

Необязательный параметр. Если задан, то в него будет записано логическое значение true или false в зависимости от успешности операции увеличения.

ttl

TTL(время жизни), используемое если операция вставляет новое значение (а не увеличивает существующее).

Возвращаемые значения

Возвращает текущее значение key в случае успешного выполнения или false в случае возникновения ошибки

Примеры

Пример #1 Пример использования apcu_inc()

<?php
echo "Сделаем что-то без ошибки", PHP_EOL;

apcu_store('anumber', 42);

echo
apcu_fetch('anumber'), PHP_EOL;

echo
apcu_inc('anumber'), PHP_EOL;
echo
apcu_inc('anumber', 10), PHP_EOL;
echo
apcu_inc('anumber', 10, $success), PHP_EOL;

var_dump($success);

echo
"А теперь с ошибкой", PHP_EOL, PHP_EOL;

apcu_store('astring', 'foo');

$ret = apcu_inc('astring', 1, $fail);

var_dump($ret);
var_dump($fail);
?>

Результатом выполнения данного примера будет что-то подобное:

Сделаем что-то без ошибки
42
43
53
63
bool(true)
А теперь с ошибкой

bool(false)
bool(false)

Смотрите также

  • apcu_dec() - Уменьшить сохранённое число


apcu_key_info

(No version information available, might only be in Git)

apcu_key_info Получить детальную информацию о ключе в кеше

Описание

apcu_key_info(string $key): ?array

Получить детальную информацию о ключе в кеше

Список параметров

key

Получить детальную информацию о ключе в кеше

Возвращаемые значения

Массив, содержащий подробную информацию о ключе кеша или null, если ключ не существует.

Примеры

Пример #1 Пример использования apcu_key_info()

<?php
apcu_add
('a','b');
var_dump(apcu_key_info('a'));
?>

Результат выполнения данного примера:

array(7) {
  ["hits"]=>
  int(0)
  ["access_time"]=>
  int(1606701783)
  ["mtime"]=>
  int(1606701783)
  ["creation_time"]=>
  int(1606701783)
  ["deletion_time"]=>
  int(0)
  ["ttl"]=>
  int(0)
  ["refs"]=>
  int(0)
}

Смотрите также

  • apcu_store() - Кеширует переменную
  • apcu_fetch() - Извлекает из кеша сохранённую переменную
  • apcu_delete() - Удаляет сохранённое значение из кеша



apcu_sma_info

(PECL apcu >= 4.0.0)

apcu_sma_info Извлекает информацию о выделении разделяемой памяти APCu

Описание

apcu_sma_info(bool $limited = false): array|false

Извлекает информацию о выделении разделяемой памяти APCu.

Список параметров

limited

Если установлен в false (по умолчанию), apcu_sma_info() вернёт детальную информацию о каждом сегменте.

Возвращаемые значения

Массив данных о выделенной разделяемой памяти; false в случае возникновения ошибки.

Примеры

Пример #1 Пример использования apcu_sma_info()

<?php
print_r
(apcu_sma_info());
?>

Результатом выполнения данного примера будет что-то подобное:

Array
(
    [num_seg] => 1
    [seg_size] => 31457280
    [avail_mem] => 31448408
    [block_lists] => Array
        (
            [0] => Array
                (
                    [0] => Array
                        (
                            [size] => 31448408
                            [offset] => 8864
                        )

                )

        )

)



apcu_store

(PECL apcu >= 4.0.0)

apcu_store Кеширует переменную

Описание

apcu_store(string $key, mixed $var, int $ttl = 0): bool
apcu_store(array $values, mixed $unused = NULL, int $ttl = 0): array

Кеширует переменную.

Замечание: В отличие от многих других механизмов PHP, переменные, сохранённые apcu_store(), сохраняются между запросами, пока их не удалят из кеша.

Список параметров

key

Имя, под которым будет сохранена переменная. Значение key является уникальным для кеша, так что попытка сохранить запись с ключом key, который уже существует, приведёт к её перезаписи.

var

Переменная для сохранения

ttl

Время жизни; переменная var будет храниться в течение ttl секунд. Как только ttl секунд пройдут, переменная будет удалена из кеша (при следующем запросе). Если параметр ttl не задан (или ttl задан как 0), значение будет храниться пока не будет удалено явно, либо по технической причине (очистка кеша, перезапуск и т.д.)

values

Имена в ключах, переменные в значениях.

Возвращаемые значения

Возвращает true в случае успешного выполнения или false в случае возникновения ошибки. Второй тип синтаксиса возвращает массив с ключами, по которым произошла ошибка.

Примеры

Пример #1 Пример использования apcu_store()

<?php
$bar
= 'BAR';
apcu_store('foo', $bar);
var_dump(apcu_fetch('foo'));
?>

Результат выполнения данного примера:

string(3) "BAR"

Смотрите также

  • apcu_add() - Добавить переменную в кеш
  • apcu_fetch() - Извлекает из кеша сохранённую переменную
  • apcu_delete() - Удаляет сохранённое значение из кеша


Содержание

  • apcu_add — Добавить переменную в кеш
  • apcu_cache_info — Извлекает закешированную информацию из хранилища APCu
  • apcu_cas — Заменяет старое значение на новое
  • apcu_clear_cache — Очистить кеш APCu
  • apcu_dec — Уменьшить сохранённое число
  • apcu_delete — Удаляет сохранённое значение из кеша
  • apcu_enabled — Возможно ли использовать APCu в текущем окружении
  • apcu_entry — Автоматическое извлечение или создание записи в кеше
  • apcu_exists — Проверяет, существуют ли записи
  • apcu_fetch — Извлекает из кеша сохранённую переменную
  • apcu_inc — Увеличить сохранённое число
  • apcu_key_info — Получить детальную информацию о ключе в кеше
  • apcu_sma_info — Извлекает информацию о выделении разделяемой памяти APCu
  • apcu_store — Кеширует переменную


Класс APCUIterator

(PECL apcu >= 5.0.0)

Введение

Класс APCUIterator позволяет с лёгкостью итерировать большой APCu кеш. Это полезно, так как позволяет перебирать большой кеш по шагам, забирая заданное количество записей используя одну блокировку, позволяя другим активностям использовать блокировку, а не задерживать весь кеш для чтения ста (по умолчанию) записей. Также, использование регулярных выражений более эффективно, так как выполняется на уровне скомпилированного кода C.

Обзор классов

class APCUIterator implements Iterator {
/* Методы */
public __construct(
    array|string|null $search = null,
    int $format = APC_ITER_ALL,
    int $chunk_size = 100,
    int $list = APC_LIST_ACTIVE
)
public current(): mixed
public getTotalCount(): int
public getTotalHits(): int
public getTotalSize(): int
public key(): string
public next(): bool
public rewind(): void
public valid(): bool
}

APCUIterator::__construct

(PECL apcu >= 5.0.0)

APCUIterator::__constructСоздаёт объект итератор класса APCUIterator

Описание

public APCUIterator::__construct(
    array|string|null $search = null,
    int $format = APC_ITER_ALL,
    int $chunk_size = 100,
    int $list = APC_LIST_ACTIVE
)

Создаёт объект APCUIterator.

Список параметров

search

Либо регулярное выражение PCRE, которое соответствует именам ключей APCu, заданным как строки (string). Или массив (array) строк (string) с именами ключей APCu. Или, необязательно, null чтобы пропустить поиск.

format

Формат, заданный одной из констант APC_ITER_*.

chunk_size

Размер блока данных. Должно быть больше 0. По умолчанию 100.

list

Тип списка. Задаётся константами APC_LIST_ACTIVE или APC_LIST_DELETED.

Примеры

Пример #1 Пример использования APCUIterator::__construct()

<?php
foreach (new APCUIterator('/^counter\./') as $counter) {
echo
"$counter[key]: $counter[value]\n";
apc_dec($counter['key'], $counter['value']);
}
?>

Смотрите также

  • apcu_exists() - Проверяет, существуют ли записи
  • apcu_cache_info() - Извлекает закешированную информацию из хранилища APCu


APCUIterator::current

(PECL apcu >= 5.0.0)

APCUIterator::currentПолучить текущий элемент

Описание

public APCUIterator::current(): mixed

Получает текущий элемент стека APCUIterator.

Список параметров

У этой функции нет параметров.

Возвращаемые значения

В случае успешного выполнения возвращает текущий элемент либо false, если элементов больше нет или произошла ошибка.

Смотрите также



APCUIterator::getTotalCount

(PECL apcu >= 5.0.0)

APCUIterator::getTotalCountПолучить общее количество записей

Описание

public APCUIterator::getTotalCount(): int

Получить общее количество записей.

Внимание

К настоящему времени эта функция ещё не была документирована; для ознакомления доступен только список аргументов.

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Общее количество записей.

Смотрите также



APCUIterator::getTotalHits

(PECL apcu >= 5.0.0)

APCUIterator::getTotalHitsПолучить общее количество попаданий в кеш

Описание

public APCUIterator::getTotalHits(): int

Получить общее количество попаданий в кеш.

Внимание

К настоящему времени эта функция ещё не была документирована; для ознакомления доступен только список аргументов.

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Количество попаданий в случае успешного выполнения или false в случае возникновения ошибки.

Смотрите также



APCUIterator::getTotalSize

(PECL apcu >= 5.0.0)

APCUIterator::getTotalSizeОбщий размер кеша

Описание

public APCUIterator::getTotalSize(): int

Возвращает общий размер кеша.

Внимание

К настоящему времени эта функция ещё не была документирована; для ознакомления доступен только список аргументов.

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Общий размер кеша.

Смотрите также



APCUIterator::key

(PECL apcu >= 5.0.0)

APCUIterator::keyПолучить ключ итератора

Описание

public APCUIterator::key(): string

Возвращает текущий ключ итератора.

Список параметров

У этой функции нет параметров.

Возвращаемые значения

В случае успешного выполнения возвращает ключ или false в случае возникновения ошибки.

Смотрите также



APCUIterator::next

(PECL apcu >= 5.0.0)

APCUIterator::nextПеремещает указатель на следующий элемент

Описание

public APCUIterator::next(): bool

Перемещает указатель на следующий элемент.

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Возвращает true в случае успешного выполнения или false в случае возникновения ошибки.

Смотрите также



APCUIterator::rewind

(PECL apcu >= 5.0.0)

APCUIterator::rewindПеремотка итератора

Описание

public APCUIterator::rewind(): void

Устанавливает указатель итератора на первый элемент.

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Функция не возвращает значения после выполнения.

Смотрите также

  • APCUIterator::next() - Перемещает указатель на следующий элемент
  • Iterator::next() - Переходит к следующему элементу


APCUIterator::valid

(PECL apcu >= 5.0.0)

APCUIterator::validПроверяет, корректна ли текущая позиция итератора

Описание

public APCUIterator::valid(): bool

Проверяет, корректна ли текущая позиция итератора.

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Возвращает true или false, в зависимости от того, корректна ли позиция.

Смотрите также


Содержание




Componere


Введение

Componere (латинский, английский: compose) предназначен для производственных окружений и предоставляет API для составления классов, обезьяньих патчей и приведения.

Структура:

Componere\Definition используется для определения (или переопределения) класса во время выполнения; Затем класс может быть зарегистрирован и в случае переопределения он заменяет исходный класс до тех пор, пока существует Componere\Definition.

public Componere\Definition::__construct(string $name)
public Componere\Definition::__construct(string $name, string $parent)
public Componere\Definition::__construct(string $name, array $interfaces)
public Componere\Definition::__construct(string $name, string $parent, array $interfaces)

Патчинг:

Componere\Patch используется для изменения класса конкретного экземпляра объекта во время выполнения; После применения исправление будет применяться до тех пор, пока существует Componere\Patch и его можно явно отменить.

public Componere\Patch::__construct(object $instance)
public Componere\Patch::__construct(object $instance, array $interfaces)

Приведение:

Componere\ функции приведения могут приводить среди определённых пользователем совместимых типов; В случае совместимости означает, что Type является подчинённым или супер типом object.

Componere\cast(Type $type, $object): Type
Componere\cast_by_ref(Type $type, $object): Type



Установка и настройка

Содержание


Требования

Для работы модуля требуется Reflection



Установка

Исходный код Componere и выпуски доступны на » github




Класс Componere\Abstract\Definition

(Componere 2 >= 2.1.0)

Введение

Окончательный абстрактный класс представляет собой структуру класса и не должен использоваться программистом.

Обзор классов

final abstract class Componere\Abstract\Definition {
/* Методы */
public addInterface(string $interface): Definition
public addMethod(string $name, Componere\Method $method): Definition
public addTrait(string $trait): Definition
}

Componere\Abstract\Definition::addInterface

(Componere 2 >= 2.1.0)

Componere\Abstract\Definition::addInterfaceДобавляет интерфейс

Описание

public Componere\Abstract\Definition::addInterface(string $interface): Definition

Реализует данный интерфейс по текущему определению

Список параметров

interface

Имя интерфейса без учёта регистра

Возвращаемые значения

The current Definition

Exceptions

Внимание

Выбрасывает исключение RuntimeException, если Definition был зарегистрирован



Componere\Abstract\Definition::addMethod

(Componere 2 >= 2.1.0)

Componere\Abstract\Definition::addMethodДобавляет метод

Описание

public Componere\Abstract\Definition::addMethod(string $name, Componere\Method $method): Definition

Должен создать или переопределить метод в текущем определении.

Список параметров

name

Нечувствительное к регистру имя метода

method

Componere\Method ранее не добавленный к другому Definition

Возвращаемые значения

The current Definition

Exceptions

Внимание

Выбрасывает исключение RuntimeException, если Definition был зарегистрирован

Внимание

Выбрасывает исключение RuntimeException, если метод был добавлен к другому определению



Componere\Abstract\Definition::addTrait

(Componere 2 >= 2.1.0)

Componere\Abstract\Definition::addTraitДобавляет трейт

Описание

public Componere\Abstract\Definition::addTrait(string $trait): Definition

Использовать данный трейт для текущего определения

Список параметров

trait

Нечувствительное к регистру имя трейта

Возвращаемые значения

The current Definition

Exceptions

Внимание

Выбрасывает исключение RuntimeException, если Definition был зарегистрирован



Componere\Abstract\Definition::getReflector

(Componere 2 >= 2.1.0)

Componere\Abstract\Definition::getReflectorReflection

Описание

public Componere\Abstract\Definition::getReflector(): ReflectionClass

Должен создать или вернуть ReflectionClass

Возвращаемые значения

ReflectionClass для текущего определения (кешируется)


Содержание



Класс Componere\Definition

(Componere 2 >= 2.1.0)

Введение

Класс Definition позволяет программисту создавать и регистрировать тип во время выполнения.

Если Definition заменит существующий класс, существующий класс будет восстановлен после уничтожения Definition.

Обзор классов

final class Componere\Definition extends Componere\Abstract\Definition {
/* Конструкторы класса */
public __construct(string $name)
public __construct(string $name, string $parent)
public __construct(string $name, array $interfaces)
public __construct(string $name, string $parent, array $interfaces)
/* Методы */
public addConstant(string $name, Componere\Value $value): Definition
public addProperty(string $name, Componere\Value $value): Definition
public register(): void
public isRegistered(): bool
public getClosure(string $name): Closure
public getClosures(): array
/* Наследуемые методы */
public Componere\Abstract\Definition::addInterface(string $interface): Definition
public Componere\Abstract\Definition::addMethod(string $name, Componere\Method $method): Definition
public Componere\Abstract\Definition::addTrait(string $trait): Definition
}

Componere\Definition::__construct

(Componere 2 >= 2.1.0)

Componere\Definition::__constructОпределение конструктора

Описание

public Componere\Definition::__construct(string $name)
public Componere\Definition::__construct(string $name, string $parent)
public Componere\Definition::__construct(string $name, array $interfaces)
public Componere\Definition::__construct(string $name, string $parent, array $interfaces)

Список параметров

name

Регистронезависимое имя класса

parent

Регистронезависимое имя класса

interfaces

Массив регистронезависимых имён классов

Исключения

Внимание

Выбрасывает исключение InvalidArgumentException, если сделана попытка заменить внутренний класс

Внимание

Выбрасывает исключение InvalidArgumentException, если сделана попытка заменить интерфейс

Внимание

Выбрасывает исключение InvalidArgumentException, если сделана попытка заменить трейт

Внимание

Выбрасывает исключение RuntimeException, если класс, указанный в interfaces не найден

Внимание

Выбрасывает исключение RuntimeException, если класс, указанный в interfaces не является интерфейсом



Componere\Definition::addConstant

(Componere 2 >= 2.1.0)

Componere\Definition::addConstantДобавляет константу

Описание

public Componere\Definition::addConstant(string $name, Componere\Value $value): Definition

Должен объявить константу класса в текущем определении

Список параметров

name

Регистронезависимое имя константы

value

Значение для константы не должно быть неопределённым (undefined) или статичным

Возвращаемые значения

Текущее определение

Исключения

Внимание

Выбрасывает исключение RuntimeException, если Definition уже было зарегистрировано

Внимание

Выбрасывает исключение RuntimeException, если name уже объявлено как константа

Внимание

Выбрасывает исключение RuntimeException, если value является статичным

Внимание

Выбрасывает исключение RuntimeException, если value является неопределённым



Componere\Definition::addProperty

(Componere 2 >= 2.1.0)

Componere\Definition::addPropertyДобавляет свойство

Описание

public Componere\Definition::addProperty(string $name, Componere\Value $value): Definition

Должен объявить свойство класса в текущем определении

Список параметров

name

Регистронезависимое имя свойства

value

Значение свойства по умолчанию

Возвращаемые значения

Текущее определение

Исключения

Внимание

Выбрасывает исключение RuntimeException, если Definition уже было зарегистрировано

Внимание

Выбрасывает исключение RuntimeException, если name уже объявлен как свойство



Componere\Definition::register

(Componere 2 >= 2.1.0)

Componere\Definition::registerРегистрация

Описание

public Componere\Definition::register(): void

Регистрирует текущее определение

Исключения

Внимание

Выбрасывает исключение RuntimeException, если Definition уже был зарегистрирован



Componere\Definition::isRegistered

(Componere 2 >= 2.1.0)

Componere\Definition::isRegisteredОпределение состояния

Описание

public Componere\Definition::isRegistered(): bool

Определяет состояние регистрации этого определения

Возвращаемые значения

Возвращает true, если определение зарегистрировано



Componere\Definition::getClosure

(Componere 2 >= 2.1.0)

Componere\Definition::getClosureПолучает замыкание

Описание

public Componere\Definition::getClosure(string $name): Closure

Должен вернуть замыкание для указанного метода

Список параметров

name

Регистронезависимое имя метода

Возвращаемые значения

Замыкание, привязанное к корректной области

Исключения

Внимание

Выбрасывает исключение RuntimeException, если Definition уже было зарегистрировано

Внимание

Выбрасывает исключение RuntimeException, если name не найдено



Componere\Definition::getClosures

(Componere 2 >= 2.1.0)

Componere\Definition::getClosuresПолучает замыкание

Описание

public Componere\Definition::getClosures(): array

Возвращает массив замыканий

Возвращаемые значения

Возвращает все методы в виде массива объектов Closure, привязанных к корректной области

Исключения

Внимание

Выбрасывает исключение RuntimeException, если Definition уже было зарегистрировано


Содержание



Класс Componere\Patch

(Componere 2 >= 2.1.0)

Введение

Класс Patch позволяет программисту изменять тип экземпляра во время выполнения без регистрации нового Definition.

Когда Patch уничтожается, он возвращается, поэтому экземпляры, которые были исправлены в течение срока действия Patch, возвращаются к их формальному типу.

Обзор классов

final class Componere\Patch extends Componere\Abstract\Definition {
/* Конструкторы класса */
public __construct(object $instance)
public __construct(object $instance, array $interfaces)
/* Методы */
public apply(): void
public revert(): void
public isApplied(): bool
public derive(object $instance): Patch
public getClosure(string $name): Closure
public getClosures(): array
/* Наследуемые методы */
public Componere\Abstract\Definition::addInterface(string $interface): Definition
public Componere\Abstract\Definition::addMethod(string $name, Componere\Method $method): Definition
public Componere\Abstract\Definition::addTrait(string $trait): Definition
}

Componere\Patch::__construct

(Componere 2 >= 2.1.0)

Componere\Patch::__constructКонструктор класса Patch

Описание

public Componere\Patch::__construct(object $instance)
public Componere\Patch::__construct(object $instance, array $interfaces)

Список параметров

instance

Назначение для этого патча

interfaces

Регистронезависимый массив имён классов

Исключения

Внимание

Выбрасывает исключение RuntimeException, если класс не может быть найден interfaces

Внимание

Выбрасывает исключение RuntimeException, если класс в interfaces не является интерфейсом



Componere\Patch::apply

(Componere 2 >= 2.1.0)

Componere\Patch::applyПриложение

Описание

public Componere\Patch::apply(): void

Применяет текущий патч



Componere\Patch::revert

(Componere 2 >= 2.1.0)

Componere\Patch::revertОтмена

Описание

public Componere\Patch::revert(): void

Отменяет текущий патч



Componere\Patch::isApplied

(Componere 2 >= 2.1.0)

Componere\Patch::isAppliedОпределение состояния

Описание

public Componere\Patch::isApplied(): bool


Componere\Patch::derive

(Componere 2 >= 2.1.1)

Componere\Patch::deriveПолучение патча

Описание

public Componere\Patch::derive(object $instance): Patch

Должен получить Patch для заданного экземпляра instance

Список параметров

instance

Назначение для полученного патча

Возвращаемые значения

Patch для instance получается из текущего Patch

Исключения

Внимание

Выбрасывает исключение InvalidArgumentException если instance не совместим



Componere\Patch::getClosure

(Componere 2 >= 2.1.0)

Componere\Patch::getClosureПолучает замыкание

Описание

public Componere\Patch::getClosure(string $name): Closure

Должен вернуть замыкание для указанного метода

Список параметров

name

Регистронезависимое имя метода

Возвращаемые значения

Замыкание, привязанное к правильной области и объекту

Исключения

Внимание

Выбрасывает исключение RuntimeException если name не найден



Componere\Patch::getClosures

(Componere 2 >= 2.1.0)

Componere\Patch::getClosuresПолучает замыкания

Описание

public Componere\Patch::getClosures(): array

Должен вернуть массив замыканий

Возвращаемые значения

Должен вернуть все методы в виде массива объектов Closure, привязанных к правильной области и объекту


Содержание



Класс Componere\Method

(Componere 2 >= 2.1.0)

Введение

Method представляет функцию с изменяемыми флагами доступности

Обзор классов

final class Componere\Method {
/* Конструктор класса */
public __construct(Closure $closure)
/* Методы */
public setPrivate(): Method
public setProtected(): Method
public setStatic(): Method
}

Componere\Method::__construct

(Componere 2 >= 2.1.0)

Componere\Method::__constructКонструктор класса Method

Описание

public Componere\Method::__construct(Closure $closure)

Список параметров

closure



Componere\Method::setPrivate

(Componere 2 >= 2.1.0)

Componere\Method::setPrivateИзменение доступности

Описание

public Componere\Method::setPrivate(): Method

Возвращаемые значения

Текущий метод

Исключения

Внимание

Выбрасывает исключение RuntimeException, если уровень доступа был ранее установлен



Componere\Method::setProtected

(Componere 2 >= 2.1.0)

Componere\Method::setProtectedИзменение доступности

Описание

public Componere\Method::setProtected(): Method

Возвращаемые значения

Текущий метод

Исключения

Внимание

Выбрасывает исключение RuntimeException, если уровень доступа был ранее установлен



Componere\Method::setStatic

(Componere 2 >= 2.1.0)

Componere\Method::setStaticИзменение доступности

Описание

public Componere\Method::setStatic(): Method

Возвращаемые значения

Текущий метод



Componere\Method::getReflector

(Componere 2 >= 2.1.0)

Componere\Method::getReflectorReflection

Описание

public Componere\Method::getReflector(): ReflectionMethod

Должен создать и вернуть ReflectionMethod

Возвращаемые значения

ReflectionMethod для текущего метода (кешируется)


Содержание



Класс Componere\Value

(Componere 2 >= 2.1.0)

Введение

Value представляет переменную PHP всех типов, включая неопределённую (undefined)

Обзор классов

final class Componere\Value {
/* Конструктор класса */
public __construct( $default = ?)
/* Методы */
public setPrivate(): Value
public setProtected(): Value
public setStatic(): Value
public isPrivate(): bool
public isProtected(): bool
public isStatic(): bool
public hasDefault(): bool
}

Componere\Value::__construct

(Componere 2 >= 2.1.0)

Componere\Value::__constructКонструктор класса Value

Описание

public Componere\Value::__construct( $default = ?)

Список параметров

default

Исключения

Внимание

Выбрасывает исключение InvalidArgumentException, если default не имеет подходящего значения



Componere\Value::setPrivate

(Componere 2 >= 2.1.0)

Componere\Value::setPrivateИзменение доступности

Описание

public Componere\Value::setPrivate(): Value

Возвращаемые значения

Текущее значение

Исключения

Внимание

Выбрасывает исключение RuntimeException, если уровень доступа был ранее установлен



Componere\Value::setProtected

(Componere 2 >= 2.1.0)

Componere\Value::setProtectedИзменение доступности

Описание

public Componere\Value::setProtected(): Value

Возвращаемые значения

Текущее значение

Исключения

Внимание

Выбрасывает исключение RuntimeException, если уровень доступа был ранее установлен



Componere\Value::setStatic

(Componere 2 >= 2.1.0)

Componere\Value::setStaticИзменение доступности

Описание

public Componere\Value::setStatic(): Value

Возвращаемые значения

Текущее значение



Componere\Value::isPrivate

(Componere 2 >= 2.1.0)

Componere\Value::isPrivateОпределение доступности

Описание

public Componere\Value::isPrivate(): bool



Componere\Value::isProtected

(Componere 2 >= 2.1.0)

Componere\Value::isProtectedОпределение доступности

Описание

public Componere\Value::isProtected(): bool



Componere\Value::isStatic

(Componere 2 >= 2.1.0)

Componere\Value::isStaticОпределение доступности

Описание

public Componere\Value::isStatic(): bool



Componere\Value::hasDefault

(Componere 2 >= 2.1.0)

Componere\Value::hasDefaultВзаимодействие с классом Value

Описание

public Componere\Value::hasDefault(): bool


Содержание



Функции Componere


Componere\cast

(Componere 2 >= 2.1.2)

Componere\castПриведение к типу

Описание

Componere\cast(Type $type, $object): Type

Список параметров

type

Пользовательский тип

object

Объект с пользовательским типом, совместимый с Type

Возвращаемые значения

object типа Type, приведённый из object

Ошибки

Внимание

Выбрасывает исключение InvalidArgumentException, если тип object является производным от внутреннего класса

Внимание

Выбрасывает исключение InvalidArgumentException, если Type является интерфейсом

Внимание

Выбрасывает исключение InvalidArgumentException, если Type является трейтом

Внимание

Выбрасывает исключение InvalidArgumentException, если Type является абстрактным классом

Внимание

Выбрасывает исключение InvalidArgumentException, если Type не совместим с типом object

Смотрите также



Componere\cast_by_ref

(Componere 2 >= 2.1.2)

Componere\cast_by_refПриведение к типу

Описание

Componere\cast_by_ref(Type $type, $object): Type

Список параметров

type

Пользовательский тип

object

Объект с пользовательским типом, совместимым с Type

Возвращаемые значения

object типа Type, приведённый из object, где элементы являются ссылками на элементы object

Ошибки

Внимание

Выбрасывает исключение InvalidArgumentException, если тип object является производным от внутреннего класса

Внимание

Выбрасывает исключение InvalidArgumentException, если Type является интерфейсом

Внимание

Выбрасывает исключение InvalidArgumentException, если Type является трейтом

Внимание

Выбрасывает исключение InvalidArgumentException, если Type является абстрактным классом

Внимание

Выбрасывает исключение InvalidArgumentException, если Type не совместим с типом object

Смотрите также


Содержание




Обработка и логирование ошибок


Введение

В данном разделе представлены функции, связанные с обработкой и логированием ошибок. Они дают возможность определять собственные правила обработки ошибок, а также изменять способы их логирования. Это позволяет пользователю настраивать обработку ошибок под собственные нужды.

С помощью функций логирования возможно напрямую отправлять сообщения об ошибках на другие машины, по электронной почте (или на смс-шлюзы), записывать в системные журналы и т.д. Это позволяет выборочно следить за наиболее важными частями приложений и сайтов.

Функции логирования позволяют настраивать тип и детализацию информации об ошибках того или иного типа от простых уведомлений до трассировки функций, вызвавших ошибку.



Установка и настройка

Содержание


Требования

Для сборки этого модуля не требуются внешние библиотеки.



Установка

Для использования этих функций не требуется проведение установки, поскольку они являются частью ядра PHP.



Настройка во время выполнения

Поведение этих функций зависит от установок в php.ini.

Настройки конфигурации протоколирования событий и ошибок
Имя По умолчанию Место изменения Список изменений
error_reporting NULL PHP_INI_ALL  
display_errors "1" PHP_INI_ALL  
display_startup_errors "1" PHP_INI_ALL До PHP 8.0.0 значение по умолчанию было "0".
log_errors "0" PHP_INI_ALL  
log_errors_max_len "1024" PHP_INI_ALL Не имеет смысла в версии PHP 8.0.0, удалено в версии PHP 8.1.0.
ignore_repeated_errors "0" PHP_INI_ALL  
ignore_repeated_source "0" PHP_INI_ALL  
report_memleaks "1" PHP_INI_ALL  
track_errors "0" PHP_INI_ALL Объявлено устаревшим в PHP 7.2.0, удалено в PHP 8.0.0.
html_errors "1" PHP_INI_ALL  
xmlrpc_errors "0" PHP_INI_SYSTEM  
xmlrpc_error_number "0" PHP_INI_ALL  
docref_root "" PHP_INI_ALL  
docref_ext "" PHP_INI_ALL  
error_prepend_string NULL PHP_INI_ALL  
error_append_string NULL PHP_INI_ALL  
error_log NULL PHP_INI_ALL  
error_log_mode 0o644 PHP_INI_ALL Доступно, начиная с PHP 8.2.0
syslog.facility "LOG_USER" PHP_INI_SYSTEM Доступно, начиная с PHP 7.3.0.
syslog.filter "no-ctrl" PHP_INI_ALL Доступно, начиная с PHP 7.3.0.
syslog.ident "php" PHP_INI_SYSTEM Доступно, начиная с PHP 7.3.0.
Для подробного описания констант PHP_INI_*, обратитесь к разделу Где могут быть установлены параметры конфигурации.

Краткое разъяснение конфигурационных директив.

error_reporting int

Задаёт уровень протоколирования ошибки. Параметр может быть либо числом, представляющим битовое поле, либо именованной константой. Соответствующие уровни и константы приведены в разделе Предопределённые константы, а также в php.ini. Для установки настройки во время выполнения используйте функцию error_reporting(). Смотрите также описание директивы display_errors.

Значение по умолчанию равно E_ALL.

До PHP 8.0.0 значение по умолчанию было: E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED. При этой настройке не отображаются уровни ошибок E_NOTICE, E_STRICT и E_DEPRECATED.

Замечание: PHP-константы за пределами PHP

Использование PHP-констант за пределами PHP, например в файле httpd.conf, не имеет смысла, так как в таких случаях требуются целочисленные значения (int). Более того, с течением времени будут добавляться новые уровни ошибок, а максимальное значение константы E_ALL соответственно будет расти. Поэтому в месте, где предполагается указать E_ALL, лучше задать большое целое число, чтобы перекрыть все возможные битовые поля. Таким числом может быть, например, 2147483647 (оно включит все возможные ошибки, не только E_ALL).

display_errors string

Эта настройка определяет, требуется ли выводить ошибки на экран вместе с остальным выводом, либо ошибки должны быть скрыты от пользователя.

Значение "stderr" посылает ошибки в поток stderr вместо stdout.

Замечание:

Эта функциональность предназначена только для разработки и не должен использоваться в готовых производственных системах (например, системах, имеющих доступ в интернет).

Замечание:

Несмотря на то, что display_errors может быть установлена во время выполнения (функцией ini_set()), это ни на что не повлияет, если в скрипте есть фатальные ошибки. Это обусловлено тем, что ожидаемые действия программы во время выполнения не получат управления (не будут выполняться).

display_startup_errors bool

Даже если display_errors включена, ошибки, возникающие во время запуска PHP, не будут отображаться. Настойчиво рекомендуем включать директиву display_startup_errors только для отладки.

log_errors bool

Отвечает за выбор журнала, в котором будут сохраняться сообщения об ошибках. Это может быть журнал сервера или error_log. Применимость этой настройки зависит от конкретного сервера.

Замечание:

Настоятельно рекомендуем при работе на готовых работающих web сайтах протоколировать ошибки там, где они отображаются.

log_errors_max_len int

Задание максимальной длины log_errors в байтах. В error_log добавляется информация об источнике. Значение по умолчанию 1024. Установка значения в 0 позволяет снять ограничение на длину log_errors. Это ограничение распространяется на записываемые в журнал ошибки, на отображаемые ошибки, а также на $php_errormsg, но не на явно вызываемые функции, такие как error_log().

Если используется int, значение измеряется байтами. Вы также можете использовать сокращённую запись, которая описана в этом разделе FAQ.
ignore_repeated_errors bool

Не заносить в журнал повторяющиеся ошибки. Ошибка считается повторяющейся, если происходит в том же файле и в той же строке, и если настройка ignore_repeated_source выключена.

ignore_repeated_source bool

Игнорировать источник ошибок при пропуске повторяющихся сообщений. Когда эта настройка включена, повторяющиеся сообщения об ошибках не будут заноситься в журнал вне зависимости от того, в каких файлах и строках они происходят.

report_memleaks bool

Если настройка включена (по умолчанию), будет формироваться отчёт об утечках памяти, зафиксированных менеджером памяти Zend. На POSIX платформах этот отчёт будет направляться в поток stderr. На Windows платформах он будет посылаться в отладчик функцией OutputDebugString(), просмотреть отчёт в этом случае можно с помощью утилит, вроде » DbgView. Эта настройка имеет смысл в сборках, предназначенных для отладки. При этом E_WARNING должна быть включена в список error_reporting.

track_errors bool

Если включена, последняя произошедшая ошибка будет первой в переменной $php_errormsg.

html_errors bool

Если разрешена, сообщения об ошибках будут включать теги HTML. Формат для HTML-ошибок производит нажимаемые ссылки, ведущие на описание ошибки, либо функии, в которой она произошла. За такие ссылки ответственны docref_root и docref_ext.

Если запрещена, то ошибки будут выдаваться простым текстом, без форматирования.

xmlrpc_errors bool

Если включена, то нормальное оповещение об ошибках отключается и, вместо него, ошибки выводятся в формате XML-RPC.

xmlrpc_error_number int

Используется в качестве значения XML-RPC элемента faultCode.

docref_root string

Новый формат ошибок содержит ссылку на страницу с описанием ошибки или функции, вызвавшей эту ошибку. Можно разместить копию описаний ошибок и функций локально и задать ini директиве значение URL этой копии. Если, например, локальная копия описаний доступна по адресу "/manual/", достаточно прописать docref_root=/manual/. Дополнительно, необходимо задать значение директиве docref_ext, отвечающей за соответствие расширений файлов файлам описаний вашей локальной копии, docref_ext=.html. Также возможно использование внешних ссылок. Например, docref_root=http://manual/en/ или docref_root="http://landonize.it/?how=url&theme=classic&filter=Landon &url=http%3A%2F%2Fwww.php.net%2F"

В большинстве случаев вам потребуется, чтобы значение docref_root оканчивалось слешем "/". Тем не менее, бывают случаи, когда это не требуется (смотрите выше, второй пример).

Замечание:

Эта функциональность предназначена только для разработки, так как он облегчает поиск описаний функций и ошибок. Не используйте его в готовых производственных системах (например, имеющих доступ в интернет).

docref_ext string

Смотрите docref_root.

Замечание:

Значение docref_ext должно начинаться с точки ".".

error_prepend_string string

Строка, которая будет выводиться непосредственно перед сообщением об ошибке. Используется только тогда, когда на экране отображается сообщение об ошибке. Основная цель - добавить дополнительную HTML-разметку к сообщению об ошибке.

error_append_string string

Строка, которая будет выводиться после сообщения об ошибке. Используется только тогда, когда на экране отображается сообщение об ошибке. Основная цель - добавить дополнительную HTML-разметку к сообщению об ошибке.

error_log string

Имя файла, в который будут добавляться сообщения об ошибках. Файл должен быть открыт для записи пользователем веб-сервера. Если используется специальное значение syslog, то сообщения будут посылаться в системный журнал. На Unix-системах это syslog(3), на Windows NT - журнал событий. Смотрите также: syslog(). Если директива не задана, ошибки будут направляться в SAPI журналы. Например, это могут быть журналы ошибок Apache или поток stderr командной строки CLI. Смотрите также функцию error_log().

error_log_mode int

Режим файла, описанного в error_log.

syslog.facility string

Указывает, какой тип программы регистрирует сообщение. Действует только в том случае, если опция error_log установлена в "syslog".

syslog.filter string

Указывает тип фильтра для фильтрации регистрируемых сообщений. Разрешённые символы передаются без изменений; все остальные записываются в шестнадцатеричном представлении с префиксом \x.

  • all – строка будет разделена на символы новой строки и все символы будут переданы без изменений
  • ascii – строка будет разделена на символы новой строки, а любые непечатаемые 7-битные символы ASCII будут экранированы
  • no-ctrl – строка будет разделена на символы новой строки, а любые непечатаемые символы будут экранированы
  • raw – все символы передаются в системный журнал без изменений, без разделения на новые строки (идентично PHP до 7.3)
Параметр влияет на ведение журнала через error_log установленного в "syslog" и вызовы syslog().

Замечание:

Тип фильтра raw доступен начиная с PHP 7.3.8 и PHP 7.4.0.

Директива не поддерживается в Windows.
syslog.ident string

Определяет строку идентификатора, которая добавляется к каждому сообщению. Действует только в том случае, если опция error_log установлена в "syslog".



Типы ресурсов

Данный модуль не определяет каких-либо типов ресурсов.




Предопределённые константы

Перечисленные ниже константы всегда доступны как часть ядра PHP.

Замечание: Данные имена констант можно использовать в файле php.ini но не вне PHP, как например в файле httpd.conf, где вместо них необходимо использовать значения их битовых масок.

Ошибки и протоколирование
Значение Константа Описание Примечание
1 E_ERROR (int) Фатальные ошибки времени выполнения. Это неустранимые средствами самого скрипта ошибки, такие как ошибка распределения памяти и т.п. Выполнение скрипта в таком случае прекращается.  
2 E_WARNING (int) Предупреждения времени выполнения (не фатальные ошибки). Выполнение скрипта в таком случае не прекращается.  
4 E_PARSE (int) Ошибки на этапе компиляции. Должны генерироваться только парсером.  
8 E_NOTICE (int) Уведомления времени выполнения. Указывают на то, что во время выполнения скрипта произошло что-то, что может указывать на ошибку, хотя это может происходить и при обычном выполнении программы.  
16 E_CORE_ERROR (int) Фатальные ошибки, которые происходят во время запуска РНР. Такие ошибки схожи с E_ERROR, за исключением того, что они генерируются ядром PHP.  
32 E_CORE_WARNING (int) Предупреждения (не фатальные ошибки), которые происходят во время начального запуска РНР. Такие предупреждения схожи с E_WARNING, за исключением того, что они генерируются ядром PHP.  
64 E_COMPILE_ERROR (int) Фатальные ошибки на этапе компиляции. Такие ошибки схожи с E_ERROR, за исключением того, что они генерируются скриптовым движком Zend.  
128 E_COMPILE_WARNING (int) Предупреждения на этапе компиляции (не фатальные ошибки). Такие предупреждения схожи с E_WARNING, за исключением того, что они генерируются скриптовым движком Zend.  
256 E_USER_ERROR (int) Сообщения об ошибках, сгенерированные пользователем. Такие ошибки схожи с E_ERROR, за исключением того, что они генерируются в коде скрипта средствами функции PHP trigger_error().  
512 E_USER_WARNING (int) Предупреждения, сгенерированные пользователем. Такие предупреждения схожи с E_WARNING, за исключением того, что они генерируются в коде скрипта средствами функции PHP trigger_error().  
1024 E_USER_NOTICE (int) Уведомления, сгенерированные пользователем. Такие уведомления схожи с E_NOTICE, за исключением того, что они генерируются в коде скрипта, средствами функции PHP trigger_error().  
2048 E_STRICT (int) Включаются для того, чтобы PHP предлагал изменения в коде, которые обеспечат лучшее взаимодействие и совместимость кода.  
4096 E_RECOVERABLE_ERROR (int) Фатальные ошибки с возможностью обработки. Такие ошибки указывают, что, вероятно, возникла опасная ситуация, но при этом, скриптовый движок остаётся в стабильном состоянии. Если такая ошибка не обрабатывается функцией, определённой пользователем для обработки ошибок (смотрите set_error_handler()), выполнение приложения прерывается, как происходит при ошибках E_ERROR.  
8192 E_DEPRECATED (int) Уведомления времени выполнения об использовании устаревших конструкций. Включаются для того, чтобы получать предупреждения о коде, который не будет работать в следующих версиях PHP.  
16384 E_USER_DEPRECATED (int) Уведомления времени выполнения об использовании устаревших конструкций, сгенерированные пользователем. Такие уведомления схожи с E_DEPRECATED за исключением того, что они генерируются в коде скрипта, с помощью функции PHP trigger_error().  
32767 E_ALL (int) Все поддерживаемые ошибки, предупреждения и замечания.  

Представленные выше значения (как числовые, так и символьные) используются для задания битовой маски, определяющей об ошибках какого типа будет даваться отчёт. Вы можете использовать побитовые операторы, чтобы совмещать эти значения для указания определённых типов ошибок. Стоит отметить, что в php.ini допустимы только следующие операторы: '|', '~', '!', '^' и '&'.



Примеры

Ниже представлен пример использования возможностей обработки ошибок в PHP. Мы определим функцию для обработки ошибок, которая будет записывать информацию об ошибках в файл (используя формат XML), а в случае возникновения критических ошибок, будем дополнительно отправлять разработчикам письмо с уведомлением.

Пример #1 Обработка ошибок в скрипте

<?php
// мы будем делать нашу собственную обработку ошибок
error_reporting(0);

// пользовательская функция для обработки ошибок
function userErrorHandler($errno, $errmsg, $filename, $linenum, $vars)
{
// временная метка возникновения ошибки
$dt = date("Y-m-d H:i:s (T)");

// определим ассоциативный массив соответствия всех
// констант уровней ошибок с их названиями, хотя
// в действительности мы будем рассматривать только
// следующие типы: E_WARNING, E_NOTICE, E_USER_ERROR,
// E_USER_WARNING и E_USER_NOTICE
$errortype = array (
E_ERROR => 'Ошибка',
E_WARNING => 'Предупреждение',
E_PARSE => 'Ошибка разбора исходного кода',
E_NOTICE => 'Уведомление',
E_CORE_ERROR => 'Ошибка ядра',
E_CORE_WARNING => 'Предупреждение ядра',
E_COMPILE_ERROR => 'Ошибка на этапе компиляции',
E_COMPILE_WARNING => 'Предупреждение на этапе компиляции',
E_USER_ERROR => 'Пользовательская ошибка',
E_USER_WARNING => 'Пользовательское предупреждение',
E_USER_NOTICE => 'Пользовательское уведомление',
E_STRICT => 'Уведомление времени выполнения',
E_RECOVERABLE_ERROR => 'Отлавливаемая фатальная ошибка'
);
// определим набор типов ошибок, для которых будет сохранён стек переменных
$user_errors = array(E_USER_ERROR, E_USER_WARNING, E_USER_NOTICE);

$err = "<errorentry>\n";
$err .= "\t<datetime>" . $dt . "</datetime>\n";
$err .= "\t<errornum>" . $errno . "</errornum>\n";
$err .= "\t<errortype>" . $errortype[$errno] . "</errortype>\n";
$err .= "\t<errormsg>" . $errmsg . "</errormsg>\n";
$err .= "\t<scriptname>" . $filename . "</scriptname>\n";
$err .= "\t<scriptlinenum>" . $linenum . "</scriptlinenum>\n";

if (
in_array($errno, $user_errors)) {
$err .= "\t<vartrace>" . wddx_serialize_value($vars, "Переменные") . "</vartrace>\n";
}
$err .= "</errorentry>\n\n";

// для тестирования
// echo $err;

// сохраняем в журнал ошибок, а если произошла пользовательская критическая ошибка, то отправляем письмо
error_log($err, 3, "/usr/local/php4/error.log");
if (
$errno == E_USER_ERROR) {
mail("phpdev@example.com", "Пользовательская критическая ошибка", $err);
}
}


function
distance($vect1, $vect2)
{
if (!
is_array($vect1) || !is_array($vect2)) {
trigger_error("Некорректные параметры функции, ожидаются массивы в качестве параметров", E_USER_ERROR);
return
NULL;
}

if (
count($vect1) != count($vect2)) {
trigger_error("Векторы должны быть одинаковой размерности", E_USER_ERROR);
return
NULL;
}

for (
$i=0; $i<count($vect1); $i++) {
$c1 = $vect1[$i]; $c2 = $vect2[$i];
$d = 0.0;
if (!
is_numeric($c1)) {
trigger_error("Координата $i в векторе 1 не является числом, будет использовать ноль",
E_USER_WARNING);
$c1 = 0.0;
}
if (!
is_numeric($c2)) {
trigger_error("Координата $i в векторе 2 не является числом, будет использовать ноль",
E_USER_WARNING);
$c2 = 0.0;
}
$d += $c2*$c2 - $c1*$c1;
}
return
sqrt($d);
}

$old_error_handler = set_error_handler("userErrorHandler");

// использование неопределённой константы, будет генерироваться предупреждение
$t = I_AM_NOT_DEFINED;

// определим несколько "векторов"
$a = array(2, 3, "foo");
$b = array(5.5, 4.3, -1.6);
$c = array(1, -3);

// генерируем пользовательскую ошибку
$t1 = distance($c, $b) . "\n";

// генерируем ещё одну пользовательскую ошибку
$t2 = distance($b, "я не массив") . "\n";

// генерируем пользовательское предупреждение
$t3 = distance($a, $b) . "\n";

?>



Функции обработки ошибок

Смотрите также

Смотрите также функцию syslog().


debug_backtrace

(PHP 4 >= 4.3.0, PHP 5, PHP 7, PHP 8)

debug_backtraceВыводит стек вызовов функций в массив

Описание

debug_backtrace(int $options = DEBUG_BACKTRACE_PROVIDE_OBJECT, int $limit = 0): array

debug_backtrace() выводит стек вызовов функций PHP в массив.

Список параметров

options

Аргумент является битовой маской для следующих настроек:

Опции debug_backtrace()
DEBUG_BACKTRACE_PROVIDE_OBJECT Нужно ли заполнять данные для ключа object.
DEBUG_BACKTRACE_IGNORE_ARGS Нужно ли исключить аргументы всех функций/методов в ключе "args" для уменьшения расхода памяти.

Замечание:

Возможны четыре комбинации:

Опции debug_backtrace()
debug_backtrace() Заполняются оба индекса.
debug_backtrace(DEBUG_BACKTRACE_PROVIDE_OBJECT)
debug_backtrace(1)
debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS & DEBUG_BACKTRACE_PROVIDE_OBJECT) Опускается индекс "object".
debug_backtrace(0)
debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS) Опускается индекс "object" и индекс "args".
debug_backtrace(2)

limit

Аргумент используется для ограничения количества вызовов функций, которые будут выведены. По умолчанию (limit=0) будет выведен весь стек вызовов.

Возвращаемые значения

Возвращает массив вложенных ассоциативных массивов (array). Описание элементов массива приведено ниже:

Список возможных элементов массивов, возвращаемых функцией debug_backtrace()
Имя Тип Описание
function string Имя текущей функции. Смотрите также __FUNCTION__.
line int Текущий номер строки. Смотрите также __LINE__.
file string Имя текущего файла. Смотрите также __FILE__.
class string Имя текущего класса. Смотрите также __CLASS__
object object Текущий объект.
type string Текущий тип вызова функции. Если это вызов метода объекта, будет выведено "->". Если это вызов статического метода класса, то "::". Если это простой вызов функции, не выводится ничего.
args array При нахождении внутри функции, будет выведен список аргументов этой функции. Если внутри включаемого файла, будет выведен список включаемых файлов.

Примеры

Пример #1 Пример использования debug_backtrace()

<?php
// файл /tmp/a.php

function a_test($str)
{
echo
"\nПривет, $str";
var_dump(debug_backtrace());
}

a_test('друг');
?>

<?php
// файл /tmp/b.php
include_once '/tmp/a.php';
?>

Результат аналогичен приведённому ниже, если запустить /tmp/b.php:

Привет, друг
array(2) {
[0]=>
array(4) {
    ["file"] => string(10) "/tmp/a.php"
    ["line"] => int(10)
    ["function"] => string(6) "a_test"
    ["args"]=>
    array(1) {
      [0] => &string(8) "друг"
    }
}
[1]=>
array(4) {
    ["file"] => string(10) "/tmp/b.php"
    ["line"] => int(2)
    ["args"] =>
    array(1) {
      [0] => string(10) "/tmp/a.php"
    }
    ["function"] => string(12) "include_once"
  }
}

Смотрите также

  • trigger_error() - Вызывает пользовательскую ошибку/предупреждение/уведомление
  • debug_print_backtrace() - Выводит стек вызовов функций



debug_print_backtrace

(PHP 5, PHP 7, PHP 8)

debug_print_backtrace Выводит стек вызовов функций

Описание

debug_print_backtrace(int $options = 0, int $limit = 0): void

debug_print_backtrace() выводит стек вызовов функций. Выводит вызовы функций, имена включённых/требуемых файлов и другую информацию из функций (eval()).

Список параметров

options

Аргумент является битовой маской для следующих настроек:

Опции debug_print_backtrace()
DEBUG_BACKTRACE_IGNORE_ARGS Нужно ли исключить ключ "args", то есть списки аргументов всех функций/методов, чтобы уменьшить расход памяти.

limit

Аргумент используется для ограничения количества вызовов функций, которые будут выведены. По умолчанию (limit=0) будет выведен весь стек вызовов.

Возвращаемые значения

Функция не возвращает значения после выполнения.

Примеры

Пример #1 Пример использования debug_print_backtrace()

<?php
// файл include.php

function a() {
b();
}

function
b() {
c();
}

function
c(){
debug_print_backtrace();
}

a();

?>
<?php
// файл test.php
// этот файл нужно запустить
include 'include.php';
?>

Результатом выполнения данного примера будет что-то подобное:

#0  c() called at [/tmp/include.php:10]
#1  b() called at [/tmp/include.php:6]
#2  a() called at [/tmp/include.php:17]
#3  include(/tmp/include.php) called at [/tmp/test.php:3]

Смотрите также

  • debug_backtrace() - Выводит стек вызовов функций в массив



error_clear_last

(PHP 7, PHP 8)

error_clear_lastОчистить самую последнюю ошибку

Описание

error_clear_last(): void

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Очищает самую последнюю ошибку, делая невозможным получение её с помощью error_get_last().

Примеры

Пример #1 Пример error_clear_last()

<?php
var_dump
(error_get_last());
error_clear_last();
var_dump(error_get_last());

@
$a = $b;

var_dump(error_get_last());
error_clear_last();
var_dump(error_get_last());
?>

Результатом выполнения данного примера будет что-то подобное:

NULL
NULL
array(4) {
  ["type"]=>
  int(8)
  ["message"]=>
  string(21) "Undefined variable: b"
  ["file"]=>
  string(9) "%s"
  ["line"]=>
  int(6)
}
NULL

Смотрите также



error_get_last

(PHP 5 >= 5.2.0, PHP 7, PHP 8)

error_get_last Получение информации о последней произошедшей ошибке

Описание

error_get_last(): ?array

Получает информацию о последней произошедшей ошибке.

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Возвращает ассоциативный массив с описанием последней произошедшей ошибки. Ключи массива: "type", "message", "file" и "line". Если ошибка произошла во внутренней функции PHP, элемент с ключом "message" будет начинаться с имени этой функции. Возвращает null, если ошибок ещё не произошло.

Примеры

Пример #1 Пример использования error_get_last()

<?php
echo $a;
print_r(error_get_last());
?>

Результатом выполнения данного примера будет что-то подобное:

Array
(
    [type] => 8
    [message] => Undefined variable: a
    [file] => C:\WWW\index.php
    [line] => 2
)

Смотрите также



error_log

(PHP 4, PHP 5, PHP 7, PHP 8)

error_logОтправляет сообщение об ошибке заданному обработчику ошибок

Описание

error_log(
    string $message,
    int $message_type = 0,
    ?string $destination = null,
    ?string $additional_headers = null
): bool

Отправляет сообщение об ошибке в лог веб-сервера или в пользовательский файл.

Список параметров

message

Сообщение об ошибке, которое должно быть логировано.

message_type

Определяет куда отправлять ошибку. Возможны следующие значения:

Типы журналов error_log()
0 Сообщение message отправляется в системный регистратор PHP, используя механизм логирования операционной системы, или файл, в зависимости от значения директивы error_log в конфигурационном файле. Это значение по умолчанию.
1 Сообщение message отправляется электронной почтой на адрес, установленный в параметре destination. Это единственный тип сообщения, где используется четвёртый параметр additional_headers.
2 Больше не используется.
3 message применяется к указанному в destination файлу. Перенос строки автоматически не добавляется в конец message.
4 Сообщение message отправляется напрямую в обработчик логера SAPI.

destination

Назначение. Устанавливается в зависимости от параметра message_type.

additional_headers

Дополнительные заголовки. Используется, когда значение параметра message_type - 1. Данный тип сообщения использует ту же внутреннюю функцию, что и mail().

Возвращаемые значения

Возвращает true в случае успешного выполнения или false в случае возникновения ошибки. Если message_type равен нулю, функция всегда возвращает true, независимо от того, может ли ошибка логироваться или нет.

Список изменений

Версия Описание
8.0.0 Параметр destination и additional_headers теперь допускают значение null.

Примеры

Пример #1 Примеры использования error_log()

<?php
// Отправляет уведомление посредством серверного лога, если мы не можем
// подключиться к базе данных.
if (!Ora_Logon($username, $password)) {
error_log("База данных Oracle недоступна!", 0);
}

// Уведомить администратора по электронной почте, если невозможно выделить ресурсы для FOO
if (!($foo = allocate_new_foo())) {
error_log("Большая проблема, мы выпали из FOO!", 1,
"operator@example.com");
}

// другой способ вызвать error_log():
error_log("Вы ошиблись!", 3, "/var/tmp/my-errors.log");
?>

Примечания

Внимание

error_log() не является бинарно-безопасной функцией. message обрезается по null-символу.

Подсказка

message не должен содержать null-символ. Учтите, что message может передаваться в файл, по почте, в syslog и т.д. Используйте подходящую преобразующую или экранирующую функцию, base64_encode(), rawurlencode() или addslashes() перед вызовом error_log().



error_reporting

(PHP 4, PHP 5, PHP 7, PHP 8)

error_reporting Задаёт, какие ошибки PHP попадут в отчёт

Описание

error_reporting(?int $error_level = null): int

Функция error_reporting() задаёт значение директивы error_reporting во время выполнения. В PHP есть много уровней ошибок. Используя эту функцию, можно задать уровень ошибок времени выполнения скрипта, которые попадут в отчёт. Если необязательный аргумент error_level не задан, error_reporting() вернёт текущее значение уровня протоколирования ошибок.

Список параметров

error_level

Новое значение уровня error_reporting. Это может быть битовая маска или именованные константы. При использовании именованных констант нужно будет следить за совместимостью с новыми версиями PHP. В новых версиях могут добавиться новые уровни ошибок, увеличиться диапазон целочисленных типов. Все это может привести к нестабильной работе при использовании старых целочисленных обозначений уровней ошибок.

Доступные константы уровней ошибок и их описания приведены в разделе Предопределённые константы.

Возвращаемые значения

Возвращает старое значение уровня error_reporting либо текущее значение, если аргумент error_level не задан.

Список изменений

Версия Описание
8.0.0 error_level теперь допускает значение null.

Примеры

Пример #1 Примеры использования error_reporting()

<?php

// Выключение протоколирования ошибок
error_reporting(0);

// Включать в отчёт простые описания ошибок
error_reporting(E_ERROR | E_WARNING | E_PARSE);

// Включать в отчёт E_NOTICE сообщения (добавятся сообщения о
// непроинициализированных переменных или ошибках в именах переменных)
error_reporting(E_ERROR | E_WARNING | E_PARSE | E_NOTICE);

// Добавлять сообщения обо всех ошибках, кроме E_NOTICE
error_reporting(E_ALL & ~E_NOTICE);

// Добавлять в отчёт все ошибки PHP
error_reporting(E_ALL);

// Добавлять в отчёт все ошибки PHP
error_reporting(-1);

// То же, что и error_reporting(E_ALL);
ini_set('error_reporting', E_ALL);

?>

Примечания

Подсказка

Если передать -1, будут отображаться все возможные ошибки, даже если в новых версиях PHP добавятся уровни или константы. Поведение эквивалентно передаче константы E_ALL.

Смотрите также



restore_error_handler

(PHP 4 >= 4.0.1, PHP 5, PHP 7, PHP 8)

restore_error_handler Восстанавливает предыдущий обработчик ошибок

Описание

restore_error_handler(): true

Используется после смены обработчика ошибок функцией set_error_handler(), чтобы вернуть предыдущий обработчик (который может быть как встроенной функцией, так и определённой пользователем).

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Функция всегда возвращает true.

Примеры

Пример #1 Пример использования restore_error_handler()

Определение, произошла ли ошибка в функции unserialize(), а затем восстановление исходного обработчика ошибок.

<?php
function unserialize_handler($errno, $errstr)
{
echo
"Сериализуемое значение недопустимо.\n";
}

$serialized = 'foo';
set_error_handler('unserialize_handler');
$original = unserialize($serialized);
restore_error_handler();
?>

Результат выполнения данного примера:

Сериализуемое значение недопустимо.

Смотрите также

  • error_reporting() - Задаёт, какие ошибки PHP попадут в отчёт
  • set_error_handler() - Задаёт пользовательский обработчик ошибок
  • restore_exception_handler() - Восстанавливает предыдущий обработчик исключений
  • trigger_error() - Вызывает пользовательскую ошибку/предупреждение/уведомление



restore_exception_handler

(PHP 5, PHP 7, PHP 8)

restore_exception_handler Восстанавливает предыдущий обработчик исключений

Описание

restore_exception_handler(): true

Используется после смены обработчика исключений функцией set_exception_handler(), чтобы вернуть предыдущий обработчик (который может быть как встроенной функцией, так и определённой пользователем).

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Функция всегда возвращает true.

Примеры

Пример #1 Пример использования restore_exception_handler()

<?php
function exception_handler_1(Exception $e)
{
echo
'[' . __FUNCTION__ . '] ' . $e->getMessage();
}

function
exception_handler_2(Exception $e)
{
echo
'[' . __FUNCTION__ . '] ' . $e->getMessage();
}

set_exception_handler('exception_handler_1');
set_exception_handler('exception_handler_2');

restore_exception_handler();

throw new
Exception('Вызван первый обработчик исключений...');
?>

Результат выполнения данного примера:

[exception_handler_1] Вызван первый обработчик исключений...

Смотрите также

  • set_exception_handler() - Задаёт пользовательский обработчик исключений
  • set_error_handler() - Задаёт пользовательский обработчик ошибок
  • restore_error_handler() - Восстанавливает предыдущий обработчик ошибок
  • error_reporting() - Задаёт, какие ошибки PHP попадут в отчёт



set_error_handler

(PHP 4 >= 4.0.1, PHP 5, PHP 7, PHP 8)

set_error_handler Задаёт пользовательский обработчик ошибок

Описание

set_error_handler(?callable $callback, int $error_levels = E_ALL): ?callable

Задаёт пользовательскую функцию (callback), как обработчик ошибок в скрипте.

Функция может быть использована для определения пользовательских обработчиков ошибок во время выполнения, например, в приложениях, которые должны выполнять очистку файлов/данных в случае возникновения критической ошибки или при инициировании ошибки в ответ на определённые условия (используя функцию trigger_error()).

Важно помнить, что стандартный обработчик ошибок PHP не будет обрабатывать никакие типы ошибок, определённые в error_levels, пока callback-функция не вернёт false. Пользовательский обработчик будет вызываться в случае возникновения любой ошибки, независимо от настроек, заданных функцией error_reporting.

Также обратите внимание, что обработчик обязан при необходимости остановить выполнение скрипта, вызвав функцию exit(). Если происходит возврат из обработчика ошибок, управление передаётся следующему выражению, стоящему за тем, что вызвало ошибку.

Ошибки следующих типов не могут быть обработаны пользователем: E_ERROR, E_PARSE, E_CORE_ERROR, E_CORE_WARNING, E_COMPILE_ERROR, E_COMPILE_WARNING независимо от того, где они были сгенерированы и большинство ошибок E_STRICT, произошедших в файле, где вызвана функция set_error_handler().

Если ошибки возникают до запуска скрипта (например, пока файл загружается), пользовательский обработчик не будет вызываться, если на этот момент он ещё не зарегистрирован.

Список параметров

callback

Если передано значение null, обработчик сбрасывается в состояние по умолчанию. В противном случае обработчик представляет собой callback-функцию со следующей сигнатурой:

handler(
    int $errno,
    string $errstr,
    string $errfile = ?,
    int $errline = ?,
    array $errcontext = ?
): bool
errno
В первый аргумент errno будет передан уровень ошибки в виде целого числа.
errstr
Во второй аргумент errstr будет передано сообщение об ошибке в виде строки.
errfile
Если функция обратного вызова принимает третий параметр errfile, то в него будет передано имя файла, в котором произошла ошибка, в виде строки.
errline
Если функция обратного вызова принимает четвёртый параметр errline, то в него будет передан номер строки, в которой произошла ошибка, в виде целого числа.
errcontext
Если функция обратного вызова принимает пятый параметр errcontext, то в него будет передан массив указателей на активную таблицу символов в точке, где произошла ошибка. Другими словами, errcontext будет содержать массив всех переменных, существующих в области видимости, где произошла ошибка. Пользовательские обработчики ошибок не должны изменять этот контекст.
Внимание

Этот параметр объявлен УСТАРЕВШИМ начиная с PHP 7.2.0 и был УДАЛЁН в PHP 8.0.0. Если в вашей функции этот параметр используется и для него не задано значение по умолчанию, то при вызове функции обработчика будет выдана ошибка "too few arguments".

Если функция возвращает false, управление передаётся встроенному обработчику ошибок.

error_levels

Может использоваться для задания маски, в соответствии с которой будет вызываться callback, по аналогии с ini-настройкой error_reporting, которая отвечает за то, какие ошибки будут показаны в отчёте. Без этой маски callback будет вызываться для обработки всех происходящих ошибок, вне зависимости от настроек в error_reporting.

Возвращаемые значения

Возвращает ранее определённый обработчик ошибок (если есть) Если на данный момент используется встроенный обработчик, функция вернёт null. Если предыдущий определённый обработчик является методом класса, функция вернёт массив, содержащий имя класса и имя метода.

Список изменений

Версия Описание
8.0.0 Параметр errcontext был удалён и больше не передаётся в пользовательскую функцию обработки ошибок.
7.2.0 Параметр errcontext объявлен устаревшим. Теперь при его использовании будет вызываться ошибка уровня E_DEPRECATED.

Примеры

Пример #1 Обработка ошибок с помощью функций set_error_handler() и trigger_error()

Пример ниже демонстрирует обработку внутренних исключений путём вызова ошибок разных типов и их обработки пользовательской функцией:

<?php
// функция обработки ошибок
function myErrorHandler($errno, $errstr, $errfile, $errline)
{
if (!(
error_reporting() & $errno)) {
// Этот код ошибки не включён в error_reporting,
// так что пусть обрабатываются стандартным обработчиком ошибок PHP
return false;
}

// может потребоваться экранирование $errstr:
$errstr = htmlspecialchars($errstr);

switch (
$errno) {
case
E_USER_ERROR:
echo
"<b>Пользовательская ОШИБКА</b> [$errno] $errstr<br />\n";
echo
" Фатальная ошибка в строке $errline файла $errfile";
echo
", PHP " . PHP_VERSION . " (" . PHP_OS . ")<br />\n";
echo
"Завершение работы...<br />\n";
exit(
1);

case
E_USER_WARNING:
echo
"<b>Пользовательское ПРЕДУПРЕЖДЕНИЕ</b> [$errno] $errstr<br />\n";
break;

case
E_USER_NOTICE:
echo
"<b>Пользовательское УВЕДОМЛЕНИЕ</b> [$errno] $errstr<br />\n";
break;

default:
echo
"Неизвестная ошибка: [$errno] $errstr<br />\n";
break;
}

/* Не запускаем внутренний обработчик ошибок PHP */
return true;
}

// функция для тестирования обработчика ошибок
function scale_by_log($vect, $scale)
{
if (!
is_numeric($scale) || $scale <= 0) {
trigger_error("log(x) для x <= 0 не определён, вы используете: scale = $scale", E_USER_ERROR);
}

if (!
is_array($vect)) {
trigger_error("Некорректный входной вектор, пропущен массив значений", E_USER_WARNING);
return
null;
}

$temp = array();
foreach(
$vect as $pos => $value) {
if (!
is_numeric($value)) {
trigger_error("Значение на позиции $pos не является числом, будет использован 0 (ноль)", E_USER_NOTICE);
$value = 0;
}
$temp[$pos] = log($scale) * $value;
}

return
$temp;
}

// переключаемся на пользовательский обработчик
$old_error_handler = set_error_handler("myErrorHandler");

// вызовем несколько ошибок, во-первых, определим массив с нечисловым элементом
echo "vector a\n";
$a = array(2, 3, "foo", 5.5, 43.3, 21.11);
print_r($a);

// теперь создадим ещё один массив
echo "----\nvector b - a notice (b = log(PI) * a)\n";
/* Значение на позиции $pos не является числом, будет использован 0 (ноль)*/
$b = scale_by_log($a, M_PI);
print_r($b);

// проблема, мы передаём строку вместо массива
echo "----\nvector c - a warning\n";
/* Некорректный входной вектор, пропущен массив значений */
$c = scale_by_log("not array", 2.3);
var_dump($c); // NULL

// критическая ошибка, логарифм от неположительного числа не определён
echo "----\nvector d - fatal error\n";
/* log(x) для x <= 0 не определён, вы используете: scale = $scale */
$d = scale_by_log($a, -2.5);
var_dump($d); // До сюда не дойдём никогда
?>

Результатом выполнения данного примера будет что-то подобное:

vector a
Array
(
    [0] => 2
    [1] => 3
    [2] => foo
    [3] => 5.5
    [4] => 43.3
    [5] => 21.11
)
----
vector b - a notice (b = log(PI) * a)
<b>Пользовательское УВЕДОМЛЕНИЕ</b> [1024]  Значение на позиции 2 не является числом, будет использован 0 (ноль)<br />
Array
(
    [0] => 2.2894597716988
    [1] => 3.4341896575482
    [2] => 0
    [3] => 6.2960143721717
    [4] => 49.566804057279
    [5] => 24.165247890281
)
----
vector c - a warning
<b>Пользовательское ПРЕДУПРЕЖДЕНИЕ</b> [512] Некорректный входной вектор, пропущен массив значений<br />
NULL
----
vector d - fatal error
<b>Пользовательская ОШИБКА</b> [256] log(x) for x <= 0 is undefined, you used: scale = -2.5<br />
  Фатальная ошибка в строке 35 файла trigger_error.php, PHP 5.2.1 (FreeBSD)<br />
Завершение работы...<br />

Смотрите также



set_exception_handler

(PHP 5, PHP 7, PHP 8)

set_exception_handler Задаёт пользовательский обработчик исключений

Описание

set_exception_handler(?callable $callback): ?callable

Задаёт обработчик по умолчанию для случаев, когда исключение выброшено вне блока try/catch. После вызова callback выполнение будет остановлено.

Список параметров

callback

Функция, вызываемая при возникновении неперехваченного исключения. Эта функция-обработчик должна принимать один параметр, которым будет объект выброшенного исключения Throwable. И Error и Exception реализуют интерфейс Throwable. Сигнатура обработчика:

handler(Throwable $ex): void

В качестве этого аргумента можно передать null. В этом случае обработчик вернётся к своему изначальному состоянию.

Возвращаемые значения

Возвращает ранее определённый обработчик исключений или null в случае ошибки. Если предыдущих обработчиков определено не было, то также возвращается null.

Примеры

Пример #1 Пример использования set_exception_handler()

<?php
function exception_handler(Throwable $exception) {
echo
"Неперехваченное исключение: " , $exception->getMessage(), "\n";
}

set_exception_handler('exception_handler');

throw new
Exception('Неперехваченное исключение');
echo
"Не выполнено\n";
?>

Смотрите также



trigger_error

(PHP 4 >= 4.0.1, PHP 5, PHP 7, PHP 8)

trigger_error Вызывает пользовательскую ошибку/предупреждение/уведомление

Описание

trigger_error(string $message, int $error_level = E_USER_NOTICE): bool

Используется для вызова пользовательских ошибок. Можно использовать в связке со встроенным обработчиком ошибок, а также с пользовательским обработчиком, заданным функцией set_error_handler().

Эта функция может быть полезной, если требуется сгенерировать определённую реакцию на исключение во время выполнения.

Список параметров

message

Сообщение, соответствующее этой ошибке. Ограничено 1024 байтами в длину. Символы дальше 1024-го будут обрезаны.

error_level

Назначенный тип ошибки. Работает только с семейством констант E_USER. По умолчанию E_USER_NOTICE.

Возвращаемые значения

Функция возвращает false, если задан неправильный error_level, и true в остальных случаях.

Примеры

Пример #1 Пример использования trigger_error()

Более подробный пример приведён в описании функции set_error_handler().

<?php
if ($divisor == 0) {
trigger_error("Не могу поделить на ноль", E_USER_ERROR);
}
?>

Примечания

Внимание

HTML-сущности в message не экранированы. Чтобы сообщение можно было отобразить в браузере, преобразуйте его функцией htmlentities().

Смотрите также



user_error

(PHP 4, PHP 5, PHP 7, PHP 8)

user_errorПсевдоним trigger_error()

Описание

Функция является псевдонимом: trigger_error().


Содержание

  • debug_backtrace — Выводит стек вызовов функций в массив
  • debug_print_backtrace — Выводит стек вызовов функций
  • error_clear_last — Очистить самую последнюю ошибку
  • error_get_last — Получение информации о последней произошедшей ошибке
  • error_log — Отправляет сообщение об ошибке заданному обработчику ошибок
  • error_reporting — Задаёт, какие ошибки PHP попадут в отчёт
  • restore_error_handler — Восстанавливает предыдущий обработчик ошибок
  • restore_exception_handler — Восстанавливает предыдущий обработчик исключений
  • set_error_handler — Задаёт пользовательский обработчик ошибок
  • set_exception_handler — Задаёт пользовательский обработчик исключений
  • trigger_error — Вызывает пользовательскую ошибку/предупреждение/уведомление
  • user_error — Псевдоним trigger_error



Интерфейс внешней функции (Foreign Function Interface)


Введение

Модуль позволяет загружать общие(shared) библиотеки (.DLL или .so), вызывать C-функции и получать доступ с структурам языка C из PHP без необходимости глубоко изучать API модулей Zend и стороннего, "промежуточного" языка. Публичный API реализован как один единственный класс FFI с некоторым набором статических методов (некоторые из них могут вызываться динамически) и переопределёнными методами объекта, что позволяет взаимодействовать с данными С.

Предостережение

Модуль FFI довольно опасен, поскольку позволяет взаимодействовать с системой на очень низком уровне. Модуль FFI должен использоваться только разработчиками, знакомыми с языком С и умеющими использовать его API. Для минимизации риска, модуль может быть запрещён директивой ffi.enable в php.ini.

Замечание:

Модуль FFI не делает классический API модулей PHP устаревшим; он предназначен для взаимодействия с функциями и структурами данных C.

Подсказка

Сейчас доступ к структурам данных FFI примерно в 2 раза медленнее чем доступ к объектам и массивам PHP. Таким образом, нет повода использовать FFI для ускорения; однако его можно использовать для сокращения потребляемой памяти.



Установка и настройка

Содержание


Требования

Для работы модуля необходимо установить библиотеку » libffi.



Установка

Для включения модуля FFI, PHP надо сконфигурировать с ключом --with-ffi.

Пользователям Windows будет необходимо добавить php_ffi.dll в php.ini.



Настройка во время выполнения

Поведение этих функций зависит от установок в php.ini.

Опции настройки FFI
Имя По умолчанию Место изменения Список изменений
ffi.enable "preload" PHP_INI_SYSTEM  
ffi.preload "" PHP_INI_SYSTEM  
Для подробного описания констант PHP_INI_*, обратитесь к разделу Где могут быть установлены параметры конфигурации.

Краткое разъяснение конфигурационных директив.

ffi.enable string

Позволяет разрешить ("true") или запретить ("false") использование FFI API, либо ограничить использование только для CLI SAPI и предзагруженных файлов ("preload").

Ограничения FFI API влияют только на класс FFI, но не на перезагруженные функции объекта FFI\CData. Это значит, что можно создать объекты FFI\CData в предзагружаемых файлах и использовать потом напрямую из скриптов PHP.

ffi.preload string

Позволяет предзагружать привязки FFI во время старта, что невозможно с FFI::load(), если включено opcache.preload_user. Эта директива принимает список разделителей имён файлов DIRECTORY_SEPARATOR. Предзагруженные привязки доступны с помощью вызова FFI::scope().



Типы ресурсов

Данный модуль не определяет каких-либо типов ресурсов.




Предопределённые константы

Данный модуль не определяет никакие константы.



Примеры

Содержание


Простые примеры использования FFI

Перед погружением в детали FFI API, давайте рассмотрим несколько примеров упрощённого использования FFI API в стандартных задачах.

Замечание:

Для некоторых из этих примеров понадобится библиотека libc.so.6. Они не будут работать в системах, где её нет.

Пример #1 Вызов функции из общей библиотеки

<?php
// создаём объект FFI, загружаем libc и экспортируем функцию printf()
$ffi = FFI::cdef(
"int printf(const char *format, ...);", // это стандартная декларация C
"libc.so.6");
// вызываем printf()
$ffi->printf("Привет, %s!\n", "мир");
?>

Результат выполнения данного примера:

Привет, мир!

Замечание:

Обратите внимание, что для некоторых функций C требуются определённые соглашения о вызовах, например: __fastcall, __stdcall или ,__vectorcall.

Пример #2 Вызов функции и возврат структуры через аргумент

<?php
// создаём привязку gettimeofday()
$ffi = FFI::cdef("
typedef unsigned int time_t;
typedef unsigned int suseconds_t;

struct timeval {
time_t tv_sec;
suseconds_t tv_usec;
};

struct timezone {
int tz_minuteswest;
int tz_dsttime;
};

int gettimeofday(struct timeval *tv, struct timezone *tz);
"
, "libc.so.6");
// создаём структуры данных C
$tv = $ffi->new("struct timeval");
$tz = $ffi->new("struct timezone");
// вызываем gettimeofday()
var_dump($ffi->gettimeofday(FFI::addr($tv), FFI::addr($tz)));
// получаем доступ к полю структуры данных C
var_dump($tv->tv_sec);
// печатаем всю структуру данных
var_dump($tz);
?>

Результатом выполнения данного примера будет что-то подобное:

int(0)
int(1555946835)
object(FFI\CData:struct timezone)#3 (2) {
  ["tz_minuteswest"]=>
  int(0)
  ["tz_dsttime"]=>
  int(0)
}

Пример #3 Доступ к существующим переменным C

<?php
// создаём объект FFI, загружаем libc и экспортируем переменную errno
$ffi = FFI::cdef(
"int errno;", // это стандартная декларация C
"libc.so.6");
// печатаем errno
var_dump($ffi->errno);
?>

Результат выполнения данного примера:

int(0)

Пример #4 Создание и модификация переменной C

<?php
// создаём переменную C типа int
$x = FFI::new("int");
var_dump($x->cdata);

// простое присваивание
$x->cdata = 5;
var_dump($x->cdata);

// не простое присвоение
$x->cdata += 2;
var_dump($x->cdata);
?>

Результат выполнения данного примера:

int(0)
int(5)
int(7)

Пример #5 Работа с массивами C

<?php
// создаём структуру данных
$a = FFI::new("long[1024]");
// работаем с ней как с обычным массивом PHP
for ($i = 0; $i < count($a); $i++) {
$a[$i] = $i;
}
var_dump($a[25]);
$sum = 0;
foreach (
$a as $n) {
$sum += $n;
}
var_dump($sum);
var_dump(count($a));
var_dump(FFI::sizeof($a));
?>

Результат выполнения данного примера:

int(25)
int(523776)
int(1024)
int(8192)

Пример #6 Работа с перечислениями C

<?php
$a
= FFI::cdef('typedef enum _zend_ffi_symbol_kind {
ZEND_FFI_SYM_TYPE,
ZEND_FFI_SYM_CONST = 2,
ZEND_FFI_SYM_VAR,
ZEND_FFI_SYM_FUNC
} zend_ffi_symbol_kind;
'
);
var_dump($a->ZEND_FFI_SYM_TYPE);
var_dump($a->ZEND_FFI_SYM_CONST);
var_dump($a->ZEND_FFI_SYM_VAR);
?>

Результат выполнения данного примера:

int(0)
int(2)
int(3)



Callback-функции PHP

Можно присвоить замыкание PHP переменной типа "указатель" (pointer) либо передать его как аргумент функции:

<?php
$zend
= FFI::cdef("
typedef int (*zend_write_func_t)(const char *str, size_t str_length);
extern zend_write_func_t zend_write;
"
);

echo
"Привет, мир 1!\n";

$orig_zend_write = clone $zend->zend_write;
$zend->zend_write = function($str, $len) {
global
$orig_zend_write;
$orig_zend_write("{\n\t", 3);
$ret = $orig_zend_write($str, $len);
$orig_zend_write("}\n", 2);
return
$ret;
};
echo
"Привет, мир 2!\n";
$zend->zend_write = $orig_zend_write;
echo
"Привет, мир 3!\n";
?>

Результат выполнения данного примера:

Привет, мир 1!
{
        Привет, мир 2!
}
Привет, мир 3!
Хоть это и работает, но данная функциональность поддерживается не на всех платформах libffi, не эффективна и вызывает утечку ресурсов при завершении запросов.
Подсказка

Поэтому рекомендуется минимизировать использование callback-функций PHP.



Комплексный пример PHP/FFI/preloading

php.ini

ffi.enable=preload
opcache.preload=preload.php

preload.php

<?php
FFI
::load(__DIR__ . "/dummy.h");
opcache_compile_file(__DIR__ . "/dummy.php");
?>

dummy.h

#define FFI_SCOPE "DUMMY"
#define FFI_LIB "libc.so.6"

int printf(const char *format, ...);

dummy.php

<?php
final class Dummy {
private static
$ffi = null;
function
__construct() {
if (
is_null(self::$ffi)) {
self::$ffi = FFI::scope("DUMMY");
}
}
function
printf($format, ...$args) {
return (int)
self::$ffi->printf($format, ...$args);
}
}
?>

test.php

<?php
$d
= new Dummy();
$d->printf("Привет, %s!\n", "мир");
?>



Основной интерфейс к коду и данным C

(PHP 7 >= 7.4.0, PHP 8)

Введение

Объекты этого класса создаются фабричными методами FFI::cdef(), FFI::load() и FFI::scope(). Объявленные переменные C доступны как свойства экземпляра FFI, а функции как его методы. Объявленные типы C можно использовать для создания структур данных с помощью FFI::new() и FFI::type().

Разбор объявлений FFI и загрузка разделяемой библиотеки может занять значительное время. Не имеет смысла делать это для каждого HTTP-запроса в окружении Web. Тем не менее можно перезагрузить объявления FFI и библиотеки при старте PHP и инстанциировать объекты FFI по необходимости. Заголовочные файлы могут быть расширены специальными объявлениями FFI_SCOPE (например, #define FFI_SCOPE "foo"; скоуп по умолчанию "C") и загружены с помощью FFI::load() во время предзагрузки. Это приведёт к созданию постоянных привязок, которые будут доступны для всех запросов через FFI::scope(). Более подробно читайте на странице Простые примеры использования FFI.

В один и тот же скоуп можно загрузить несколько заголовочных файлов.

Обзор классов

final class FFI {
/* Константы */
public const int __BIGGEST_ALIGNMENT__;
/* Методы */
public static addr(FFI\CData &$ptr): FFI\CData
public static alignof(FFI\CData|FFI\CType &$ptr): int
public static arrayType(FFI\CType $type, array $dimensions): FFI\CType
public static cast(FFI\CType|string $type, FFI\CData|int|float|bool|null &$ptr): ?FFI\CData
public cast(FFI\CType|string $type, FFI\CData|int|float|bool|null &$ptr): ?FFI\CData
public static cdef(string $code = "", ?string $lib = null): FFI
public static free(FFI\CData &$ptr): void
public static isNull(FFI\CData &$ptr): bool
public static load(string $filename): ?FFI
public static memcmp(string|FFI\CData &$ptr1, string|FFI\CData &$ptr2, int $size): int
public static memcpy(FFI\CData &$to, FFI\CData|string &$from, int $size): void
public static memset(FFI\CData &$ptr, int $value, int $size): void
public static new(FFI\CType|string $type, bool $owned = true, bool $persistent = false): ?FFI\CData
public new(FFI\CType|string $type, bool $owned = true, bool $persistent = false): ?FFI\CData
public static scope(string $name): FFI
public static sizeof(FFI\CData|FFI\CType &$ptr): int
public static string(FFI\CData &$ptr, ?int $size = null): string
public static type(string $type): ?FFI\CType
public type(string $type): ?FFI\CType
public static typeof(FFI\CData &$ptr): FFI\CType
}

Предопределённые константы

FFI::__BIGGEST_ALIGNMENT__


FFI::addr

(PHP 7 >= 7.4.0, PHP 8)

FFI::addrСоздаёт неуправляемый указатель на данные C

Описание

public static FFI::addr(FFI\CData &$ptr): FFI\CData

Создаёт неуправляемый указатель на данные C, представленные заданным FFI\CData. Исходный ptr должен пережить результирующий указатель. Эта функция используется главным образом для передачи аргументов в функцию C по указателю.

Список параметров

ptr

Дескриптор неуправляемого указателя на структуру данных.

Возвращаемые значения

Возвращает новый объект FFI\CData.



FFI::alignof

(PHP 7 >= 7.4.0, PHP 8)

FFI::alignofВозвращает величину выравнивания

Описание

public static FFI::alignof(FFI\CData|FFI\CType &$ptr): int

Возвращает величину выравнивания объектов FFI\CData или FFI\CType.

Список параметров

ptr

Дескриптор указателя на данные или тип C.

Возвращаемые значения

Возвращает величину выравнивания объектов FFI\CData или FFI\CType.



FFI::arrayType

(PHP 7 >= 7.4.0, PHP 8)

FFI::arrayTypeДинамически конструирует новый тип С массива

Описание

public static FFI::arrayType(FFI\CType $type, array $dimensions): FFI\CType

Динамически конструирует новый тип С массива с элементами типа type и размерностями, заданными в dimensions. В следующем примере $t1 и $t2 определяют массивы одинакового типа:

<?php
$t1
= FFI::type("int[2][3]");
$t2 = FFI::arrayType(FFI::type("int"), [2, 3]);
?>

Список параметров

type

Корректная декларация типа С, например string, или заранее созданный объект класса FFI\CType.

dimensions

Массив, определяющий размерность типа.

Возвращаемые значения

Возвращает новый объект FFI\CType.



FFI::cast

(PHP 7 >= 7.4.0, PHP 8)

FFI::castПроизводит преобразование типа C

Описание

public static FFI::cast(FFI\CType|string $type, FFI\CData|int|float|bool|null &$ptr): ?FFI\CData
public FFI::cast(FFI\CType|string $type, FFI\CData|int|float|bool|null &$ptr): ?FFI\CData

FFI::cast() создаёт новый объект класса FFI\CData, который указывает на ту же структуру C, но ассоциирован с другим типом. Полученный объект не становится владельцем данных, так что исходный указатель ptr должен оставаться живым дольше полученного объекта. Тип C должен быть задан как строка, содержащая имя любого корректного типа С, либо как объект FFI\CType. Если метод вызывается статически, то можно использовать только предопределённые имена типов С (например, int, char, etc.); если метод вызывается как метод объекта, то допустимы любые определённые для него типы.

Список параметров

type

Строка с именем типа С или объект класса FFI\CType.

ptr

Дескриптор указателя на структуру данных С.

Возвращаемые значения

Возвращает новый объект FFI\CData.



FFI::cdef

(PHP 7 >= 7.4.0, PHP 8)

FFI::cdefСоздаёт новый объект FFI

Описание

public static FFI::cdef(string $code = "", ?string $lib = null): FFI

Создаёт новый объект FFI.

Список параметров

code

Строка, содержащая последовательность деклараций на языке С (типы, структуры, функции, переменные и т.д.). Фактически можно скопировать кусок заголовочного файла С.

Замечание:

Директивы сопроцессора С не поддерживаются. Т.е. #include, #define и макросы CPP работать не будут.

lib

Имя файла библиотеки, который будет загружен и связан с заданными декларациями.

Замечание:

Если параметр lib не задан или null, то для платформ, поддерживающих RTLD_DEFAULT, будет произведён поиск задекларированных в code сущностей в глобальной области видимости. Для прочих платформ произвести привязку не получится.

Возвращаемые значения

Возвращает новый объект FFI.

Список изменений

Версия Описание
8.0.0 lib теперь допускает значение null.


FFI::free

(PHP 7 >= 7.4.0, PHP 8)

FFI::freeВысвобождает неуправляемую структуру данных

Описание

public static FFI::free(FFI\CData &$ptr): void

Высвобождает созданную ранее неуправляемую структуру данных.

Список параметров

ptr

Дескриптор неуправляемого указателя на структуру данных.

Возвращаемые значения

Функция не возвращает значения после выполнения.



FFI::isNull

(PHP 7 >= 7.4.0, PHP 8)

FFI::isNullПроверяет, является ли FFI\CData нулевым указателем

Описание

public static FFI::isNull(FFI\CData &$ptr): bool

Проверяет, является ли FFI\CData нулевым указателем.

Список параметров

ptr

Указатель на структуру данных C.

Возвращаемые значения

Возвращает true или false в зависимости от того, является ли FFI\CData нулевым указателем.



FFI::load

(PHP 7 >= 7.4.0, PHP 8)

FFI::loadЗагрузить декларации C из заголовочного файла

Описание

public static FFI::load(string $filename): ?FFI

Загружает декларации C из заголовочного файла. Можно указать общие библиотеки для загрузки с помощью специальной #define директивы FFI_LIB в заголовочном файле.

Список параметров

filename

Имя заголовочного файла C.

Директивы сопроцессора С не поддерживаются. Т.е. #include, #define и макросы CPP работать не будут, за исключением особых случаев, перечисленных ниже.

Заголовочный файл должен содержать оператор #define для переменной FFI_SCOPE, например, #define FFI_SCOPE "MYLIB". За подробностями обратитесь к Введению в FFI.

Заголовочный файл может содержать оператор #define для переменной FFI_LIB, чтобы указать библиотеку, которую он раскрывает. Если это системная библиотека, требуется только имя файла, например: #define FFI_LIB "libc.so.6". Если это пользовательская библиотека, требуется относительный путь, например: #define FFI_LIB "./mylib.so".

Возвращаемые значения

Возвращает новый объект FFI или null в случае возникновения ошибки.

Смотрите также

  • FFI::scope() - Инстанциирует объект FFI в соответствии с декларацией С, разобранной на этапе предзагрузки



FFI::memcmp

(PHP 7 >= 7.4.0, PHP 8)

FFI::memcmpСравнивает две области памяти

Описание

public static FFI::memcmp(string|FFI\CData &$ptr1, string|FFI\CData &$ptr2, int $size): int

Сравнивает size байт памяти по указателям ptr1 и ptr2. И ptr1 и ptr2 могут быть любыми нативными структурами данных (FFI\CData), либо строками PHP.

Список параметров

ptr1

Указатель на первую область памяти.

ptr2

Указатель на вторую область памяти.

size

Количество байт для сравнения.

Возвращаемые значения

Возвращает < 0, если содержимое памяти для ptr1 меньше, чем для ptr2, > 0, если первое больше второго и 0, если равны.



FFI::memcpy

(PHP 7 >= 7.4.0, PHP 8)

FFI::memcpyКопирует содержимое одной области памяти в другую

Описание

public static FFI::memcpy(FFI\CData &$to, FFI\CData|string &$from, int $size): void

Копирует size байт из области памяти from в область памяти to.

Список параметров

to

Целевая область памяти.

from

Область памяти, откуда будет происходить копирование.

size

Количество байт для копирования.

Возвращаемые значения

Функция не возвращает значения после выполнения.



FFI::memset

(PHP 7 >= 7.4.0, PHP 8)

FFI::memsetЗаполнить область памяти

Описание

public static FFI::memset(FFI\CData &$ptr, int $value, int $size): void

Заполняет size байт памяти по указателю ptr значением value.

Список параметров

ptr

Указатель на начало участка памяти.

value

Значение для заполнения.

size

Количество байт, которые будут заполнены.

Возвращаемые значения

Функция не возвращает значения после выполнения.



FFI::new

(PHP 7 >= 7.4.0, PHP 8)

FFI::newСоздаёт структуру данных C

Описание

public static FFI::new(FFI\CType|string $type, bool $owned = true, bool $persistent = false): ?FFI\CData
public FFI::new(FFI\CType|string $type, bool $owned = true, bool $persistent = false): ?FFI\CData

Создаёт нативную структуру данных заданного типа. При статическом вызове данного метода необходимо использовать только предопределённые имена типов С (такие как int, char, и т.д.); при вызове как метод объекта, допустим любой тип объявленный для него.

Список параметров

type

type - корректная декларация типа С, например, string или заранее созданный объект класса FFI\CType.

owned

Создавать ли управляемые или неуправляемые данные. Управляемые данные живут в связке с возвращённым объектом FFI\CData и высвобождается когда стандартный подсчёт ссылок PHP или GC (сборщик мусора) освободят последнюю ссылку на этот объект. Неуправляемые данные необходимо высвобождать вручную с помощью FFI::free().

persistent

Располагать ли данные на постоянной основе к системной куче(heap) (используя malloc()), или в куче запроса PHP (используя emalloc()).

Возвращаемые значения

Возвращает новый объект FFI\CData или null в случае возникновения ошибки.



FFI::scope

(PHP 7 >= 7.4.0, PHP 8)

FFI::scopeИнстанциирует объект FFI в соответствии с декларацией С, разобранной на этапе предзагрузки

Описание

public static FFI::scope(string $name): FFI

Инстанциирует объект FFI в соответствии с декларацией С, разобранной на этапе предзагрузки.

Метод FFI::scope() можно многократно вызывать для одного и того же контекста. Множество ссылок на один и тот же контекст могут быть загружены одновременно.

Список параметров

name

Имя скоупа, заданного с помощью специальной #define директивы FFI_SCOPE.

Возвращаемые значения

Возвращает новый объект FFI.

Смотрите также

  • FFI::load() - Загрузить декларации C из заголовочного файла



FFI::sizeof

(PHP 7 >= 7.4.0, PHP 8)

FFI::sizeofВозвращает размер данных или типа C

Описание

public static FFI::sizeof(FFI\CData|FFI\CType &$ptr): int

Возвращает размер объектов FFI\CData или FFI\CType.

Список параметров

ptr

Дескриптор указателя на тип или данные C.

Возвращаемые значения

Размер области памяти, на который указывает ptr.



FFI::string

(PHP 7 >= 7.4.0, PHP 8)

FFI::stringСоздаёт строку PHP из области памяти

Описание

public static FFI::string(FFI\CData &$ptr, ?int $size = null): string

Создаёт переменную PHP типа string из size байт памяти, начиная с адреса по указателю ptr.

Список параметров

ptr

Начало участка памяти, из которой будет создаваться строка.

size

Количество байт для копирования в строку. Если параметр size не задан или null, то ptr должен указывать на массив C типа char, завершающийся нулевым байтом.

Возвращаемые значения

Строка PHP.

Список изменений

Версия Описание
8.0.0 size теперь допускает значение null; ранее значением по умолчанию был 0.


FFI::type

(PHP 7 >= 7.4.0, PHP 8)

FFI::typeСоздаёт объект FFI\CType из декларации С

Описание

public static FFI::type(string $type): ?FFI\CType
public FFI::type(string $type): ?FFI\CType

Функция создаёт и возвращает объект FFI\CType для заданной строки, содержащей декларацию типа С. Если метод вызывается статически, то можно использовать только предопределённые имена типов С (например, int, char, и т.д.); если метод вызывается как метод объекта, то допустимы любые определённые для него типы.

Список параметров

type

Корректная декларация типа C в качестве строки (string).

Возвращаемые значения

Возвращает новый объект FFI\CType или null в случае возникновения ошибки.



FFI::typeof

(PHP 7 >= 7.4.0, PHP 8)

FFI::typeofПолучает FFI\CType для FFI\CData

Описание

public static FFI::typeof(FFI\CData &$ptr): FFI\CType

Возвращает объект FFI\CType, представляющий тип объекта FFI\CData.

Список параметров

ptr

Указатель на структуру данных C.

Возвращаемые значения

Возвращает объект FFI\CType, представляющий тип объекта FFI\CData.


Содержание

  • FFI::addr — Создаёт неуправляемый указатель на данные C
  • FFI::alignof — Возвращает величину выравнивания
  • FFI::arrayType — Динамически конструирует новый тип С массива
  • FFI::cast — Производит преобразование типа C
  • FFI::cdef — Создаёт новый объект FFI
  • FFI::free — Высвобождает неуправляемую структуру данных
  • FFI::isNull — Проверяет, является ли FFI\CData нулевым указателем
  • FFI::load — Загрузить декларации C из заголовочного файла
  • FFI::memcmp — Сравнивает две области памяти
  • FFI::memcpy — Копирует содержимое одной области памяти в другую
  • FFI::memset — Заполнить область памяти
  • FFI::new — Создаёт структуру данных C
  • FFI::scope — Инстанциирует объект FFI в соответствии с декларацией С, разобранной на этапе предзагрузки
  • FFI::sizeof — Возвращает размер данных или типа C
  • FFI::string — Создаёт строку PHP из области памяти
  • FFI::type — Создаёт объект FFI\CType из декларации С
  • FFI::typeof — Получает FFI\CType для FFI\CData


Доступ к данным C

(PHP 7 >= 7.4.0, PHP 8)

Введение

Объекты FFI\CData могут использоваться множеством разных способов как обычные данные PHP:

  • Данные C скалярных типов могут читаться и присваиваться через свойство $cdata: $x = FFI::new('int'); $x->cdata = 42;
  • Поля структур(struct) и объединений(union) C доступны как обычные свойства объекта PHP: $cdata->field
  • Доступ к элементам массивов C происходит так же, как доступ к элементам обычного массива PHP: $cdata[$offset]
  • Массивы C можно перебирать с помощью foreach.
  • Для массивов C можно использовать функцию count().
  • Указатели C могут быть разыменованы как массив: $cdata[0]
  • Указатели C можно сравнивать обычными операторами сравнения (<, <=, ==, !=, >=, >).
  • Для указателей C можно использовать операции инкремента и декремента +/-/ ++/–-: $cdata += 5
  • Указатели C можно вычитать друг из друга с помощью операции -.
  • Указатели на функции можно вызывать как обычные замыкания PHP: $cdata()
  • Любые данные C можно клонировать с помощью clone: $cdata2 = clone $cdata;
  • Любые данные C можно визуализировать с помощью var_dump(), print_r(), и т.д.

Замечание: Обратите внимание, что для экземпляров FFI\CData не поддерживаются функции isset(), empty() и unset(). А для тех, что оборачивают структуры и объединения не реализован интерфейс Traversable.

Обзор классов

final class FFI\CData {
}


Доступ к типам C

(PHP 7 >= 7.4.0, PHP 8)

Введение

Обзор классов

final class FFI\CType {
/* Константы */
public const int TYPE_VOID;
public const int TYPE_FLOAT;
public const int TYPE_DOUBLE;
public const int TYPE_LONGDOUBLE;
public const int TYPE_UINT8;
public const int TYPE_SINT8;
public const int TYPE_UINT16;
public const int TYPE_SINT16;
public const int TYPE_UINT32;
public const int TYPE_SINT32;
public const int TYPE_UINT64;
public const int TYPE_SINT64;
public const int TYPE_ENUM;
public const int TYPE_BOOL;
public const int TYPE_CHAR;
public const int TYPE_POINTER;
public const int TYPE_FUNC;
public const int TYPE_ARRAY;
public const int TYPE_STRUCT;
public const int ATTR_CONST;
public const int ATTR_INCOMPLETE_TAG;
public const int ATTR_VARIADIC;
public const int ATTR_INCOMPLETE_ARRAY;
public const int ATTR_VLA;
public const int ATTR_UNION;
public const int ATTR_PACKED;
public const int ATTR_MS_STRUCT;
public const int ATTR_GCC_STRUCT;
public const int ABI_DEFAULT;
public const int ABI_CDECL;
public const int ABI_FASTCALL;
public const int ABI_THISCALL;
public const int ABI_STDCALL;
public const int ABI_PASCAL;
public const int ABI_REGISTER;
public const int ABI_MS;
public const int ABI_SYSV;
public const int ABI_VECTORCALL;
/* Методы */
public getAlignment(): int
public getArrayLength(): int
public getAttributes(): int
public getEnumKind(): int
public getFuncABI(): int
public getFuncParameterCount(): int
public getFuncParameterType(int $index): FFI\CType
public getKind(): int
public getName(): string
public getSize(): int
public getStructFieldNames(): array
public getStructFieldOffset(string $name): int
public getStructFieldType(string $name): FFI\CType
}

Предопределённые константы

FFI\CType::TYPE_VOID

FFI\CType::TYPE_FLOAT

FFI\CType::TYPE_DOUBLE

FFI\CType::TYPE_LONGDOUBLE

FFI\CType::TYPE_UINT8

FFI\CType::TYPE_SINT8

FFI\CType::TYPE_UINT16

FFI\CType::TYPE_SINT16

FFI\CType::TYPE_UINT32

FFI\CType::TYPE_SINT32

FFI\CType::TYPE_UINT64

FFI\CType::TYPE_SINT64

FFI\CType::TYPE_ENUM

FFI\CType::TYPE_BOOL

FFI\CType::TYPE_CHAR

FFI\CType::TYPE_POINTER

FFI\CType::TYPE_FUNC

FFI\CType::TYPE_ARRAY

FFI\CType::TYPE_STRUCT

FFI\CType::ATTR_CONST

FFI\CType::ATTR_INCOMPLETE_TAG

FFI\CType::ATTR_VARIADIC

FFI\CType::ATTR_INCOMPLETE_ARRAY

FFI\CType::ATTR_VLA

FFI\CType::ATTR_UNION

FFI\CType::ATTR_PACKED

FFI\CType::ATTR_MS_STRUCT

FFI\CType::ATTR_GCC_STRUCT

FFI\CType::ABI_DEFAULT

FFI\CType::ABI_CDECL

FFI\CType::ABI_FASTCALL

FFI\CType::ABI_THISCALL

FFI\CType::ABI_STDCALL

FFI\CType::ABI_PASCAL

FFI\CType::ABI_REGISTER

FFI\CType::ABI_MS

FFI\CType::ABI_SYSV

FFI\CType::ABI_VECTORCALL


FFI\CType::getAlignment

(PHP 8 >= 8.1.0)

FFI\CType::getAlignmentОписание

Описание

public FFI\CType::getAlignment(): int

Внимание

К настоящему времени эта функция ещё не была документирована; для ознакомления доступен только список аргументов.

Список параметров

У этой функции нет параметров.

Возвращаемые значения



FFI\CType::getArrayElementType

(PHP 8 >= 8.1.0)

FFI\CType::getArrayElementTypeОписание

Описание

public FFI\CType::getArrayElementType(): FFI\CType

Внимание

К настоящему времени эта функция ещё не была документирована; для ознакомления доступен только список аргументов.

Список параметров

У этой функции нет параметров.

Возвращаемые значения



FFI\CType::getArrayLength

(PHP 8 >= 8.1.0)

FFI\CType::getArrayLengthОписание

Описание

public FFI\CType::getArrayLength(): int

Внимание

К настоящему времени эта функция ещё не была документирована; для ознакомления доступен только список аргументов.

Список параметров

У этой функции нет параметров.

Возвращаемые значения



FFI\CType::getAttributes

(PHP 8 >= 8.1.0)

FFI\CType::getAttributesОписание

Описание

public FFI\CType::getAttributes(): int

Внимание

К настоящему времени эта функция ещё не была документирована; для ознакомления доступен только список аргументов.

Список параметров

У этой функции нет параметров.

Возвращаемые значения



FFI\CType::getEnumKind

(PHP 8 >= 8.1.0)

FFI\CType::getEnumKindОписание

Описание

public FFI\CType::getEnumKind(): int

Внимание

К настоящему времени эта функция ещё не была документирована; для ознакомления доступен только список аргументов.

Список параметров

У этой функции нет параметров.

Возвращаемые значения



FFI\CType::getFuncABI

(PHP 8 >= 8.1.0)

FFI\CType::getFuncABIОписание

Описание

public FFI\CType::getFuncABI(): int

Внимание

К настоящему времени эта функция ещё не была документирована; для ознакомления доступен только список аргументов.

Список параметров

У этой функции нет параметров.

Возвращаемые значения



FFI\CType::getFuncParameterCount

(PHP 8 >= 8.1.0)

FFI\CType::getFuncParameterCountОписание

Описание

public FFI\CType::getFuncParameterCount(): int

Внимание

К настоящему времени эта функция ещё не была документирована; для ознакомления доступен только список аргументов.

Список параметров

У этой функции нет параметров.

Возвращаемые значения



FFI\CType::getFuncParameterType

(PHP 8 >= 8.1.0)

FFI\CType::getFuncParameterTypeОписание

Описание

public FFI\CType::getFuncParameterType(int $index): FFI\CType

Внимание

К настоящему времени эта функция ещё не была документирована; для ознакомления доступен только список аргументов.

Список параметров

index

Возвращаемые значения



FFI\CType::getFuncReturnType

(PHP 8 >= 8.1.0)

FFI\CType::getFuncReturnTypeОписание

Описание

public FFI\CType::getFuncReturnType(): FFI\CType

Внимание

К настоящему времени эта функция ещё не была документирована; для ознакомления доступен только список аргументов.

Список параметров

У этой функции нет параметров.

Возвращаемые значения



FFI\CType::getKind

(PHP 8 >= 8.1.0)

FFI\CType::getKindОписание

Описание

public FFI\CType::getKind(): int

Внимание

К настоящему времени эта функция ещё не была документирована; для ознакомления доступен только список аргументов.

Список параметров

У этой функции нет параметров.

Возвращаемые значения



FFI\CType::getName

(PHP 7 >= 7.4.0, PHP 8)

FFI\CType::getNameОписание

Описание

public FFI\CType::getName(): string

Внимание

К настоящему времени эта функция ещё не была документирована; для ознакомления доступен только список аргументов.

Список параметров

У этой функции нет параметров.

Возвращаемые значения



FFI\CType::getPointerType

(PHP 8 >= 8.1.0)

FFI\CType::getPointerTypeОписание

Описание

public FFI\CType::getPointerType(): FFI\CType

Внимание

К настоящему времени эта функция ещё не была документирована; для ознакомления доступен только список аргументов.

Список параметров

У этой функции нет параметров.

Возвращаемые значения



FFI\CType::getSize

(PHP 8 >= 8.1.0)

FFI\CType::getSizeОписание

Описание

public FFI\CType::getSize(): int

Внимание

К настоящему времени эта функция ещё не была документирована; для ознакомления доступен только список аргументов.

Список параметров

У этой функции нет параметров.

Возвращаемые значения



FFI\CType::getStructFieldNames

(PHP 8 >= 8.1.0)

FFI\CType::getStructFieldNamesОписание

Описание

public FFI\CType::getStructFieldNames(): array

Внимание

К настоящему времени эта функция ещё не была документирована; для ознакомления доступен только список аргументов.

Список параметров

У этой функции нет параметров.

Возвращаемые значения



FFI\CType::getStructFieldOffset

(PHP 8 >= 8.1.0)

FFI\CType::getStructFieldOffsetОписание

Описание

public FFI\CType::getStructFieldOffset(string $name): int

Внимание

К настоящему времени эта функция ещё не была документирована; для ознакомления доступен только список аргументов.

Список параметров

name

Возвращаемые значения



FFI\CType::getStructFieldType

(PHP 8 >= 8.1.0)

FFI\CType::getStructFieldTypeОписание

Описание

public FFI\CType::getStructFieldType(string $name): FFI\CType

Внимание

К настоящему времени эта функция ещё не была документирована; для ознакомления доступен только список аргументов.

Список параметров

name

Возвращаемые значения


Содержание



Исключения FFI

(PHP 7 >= 7.4.0, PHP 8)

Введение

Обзор классов

class FFI\Exception extends Error {
/* Наследуемые свойства */
protected string $message = "";
private string $string = "";
protected int $code;
protected string $file = "";
protected int $line;
private array $trace = [];
private ?Throwable $previous = null;
/* Наследуемые методы */
public Error::__construct(string $message = "", int $code = 0, ?Throwable $previous = null)
final public Error::getMessage(): string
final public Error::getPrevious(): ?Throwable
final public Error::getCode(): int
final public Error::getFile(): string
final public Error::getLine(): int
final public Error::getTrace(): array
final public Error::getTraceAsString(): string
public Error::__toString(): string
private Error::__clone(): void
}


Исключения парсера FFI

(PHP 7 >= 7.4.0, PHP 8)

Введение

Обзор классов

final class FFI\ParserException extends FFI\Exception {
/* Наследуемые свойства */
protected string $message = "";
private string $string = "";
protected int $code;
protected string $file = "";
protected int $line;
private array $trace = [];
private ?Throwable $previous = null;
/* Наследуемые методы */
public Error::__construct(string $message = "", int $code = 0, ?Throwable $previous = null)
final public Error::getMessage(): string
final public Error::getPrevious(): ?Throwable
final public Error::getCode(): int
final public Error::getFile(): string
final public Error::getLine(): int
final public Error::getTrace(): array
final public Error::getTraceAsString(): string
public Error::__toString(): string
private Error::__clone(): void
}



OPcache


Введение

OPcache улучшает производительность PHP путём сохранения скомпилированного байт-кода скриптов в разделяемой памяти, тем самым избавляя PHP от необходимости загружать и анализировать скрипты при каждом запросе.

Этот модуль доступен по умолчанию с PHP 5.5.0 и » доступен в PECL для версий 5.2, 5.3 и 5.4.



Установка и настройка

Содержание


Требования

Для сборки этого модуля не требуются внешние библиотеки.



Установка

OPcache можно собирать только как разделяемый модуль. Если вы запретили сборку модулей по умолчанию с помощью --disable-all, то вам будет необходимо компилировать PHP с ключом --enable-opcache для включения OPcache.

Единожды скомпилировав, вы можете использовать директиву конфигурации zend_extension для загрузки OPcache в PHP. Это можно сделать с помощью zend_extension=/full/path/to/opcache.so для платформ, отличных от Windows, и zend_extension=C:\path\to\php_opcache.dll в Windows.

Замечание:

Если вы хотите использовать OPcache с » Xdebug, то сперва нужно загружать OPcache, а потом Xdebug.

Рекомендованные настройки php.ini

Данные опции рекомендованы для обеспечения хорошей производительности:

opcache.memory_consumption=128
opcache.interned_strings_buffer=8
opcache.max_accelerated_files=4000
opcache.revalidate_freq=60
opcache.fast_shutdown=1 ; до PHP 7.2.0
opcache.enable_cli=1

Вы также можете рассмотреть возможность отключения opcache.save_comments и включения opcache.enable_file_override. Однако обратите внимание, что вам придётся протестировать свой код, прежде чем использовать его в промышленной эксплуатации так как известны случаи, когда некоторые фреймворки и приложения переставали работать, особенно в случае использования аннотаций в комментариях.

В Windows должен быть включён параметр opcache.file_cache_fallback и opcache.file_cache должна быть установлена на уже существующий и доступный для записи каталог.

Полный список опций настройки OPcache смотрите тут.



Настройка во время выполнения

Поведение этих функций зависит от установок в php.ini.

Опции настройки OPcache
Имя По умолчанию Место изменения Список изменений
opcache.enable "1" PHP_INI_ALL  
opcache.enable_cli "0" PHP_INI_SYSTEM В версиях с PHP 7.1.2 по 7.1.6 включительно, значение по умолчанию "1" (включено)
opcache.memory_consumption "128" PHP_INI_SYSTEM  
opcache.interned_strings_buffer "8" PHP_INI_SYSTEM  
opcache.max_accelerated_files "10000" PHP_INI_SYSTEM  
opcache.max_wasted_percentage "5" PHP_INI_SYSTEM  
opcache.use_cwd "1" PHP_INI_SYSTEM  
opcache.validate_timestamps "1" PHP_INI_ALL  
opcache.revalidate_freq "2" PHP_INI_ALL  
opcache.revalidate_path "0" PHP_INI_ALL  
opcache.save_comments "1" PHP_INI_SYSTEM  
opcache.fast_shutdown "0" PHP_INI_SYSTEM  
opcache.enable_file_override "0" PHP_INI_SYSTEM  
opcache.optimization_level "0x7FFEBFFF" PHP_INI_SYSTEM До PHP 7.3.0 было 0x7FFFBFFF
opcache.inherited_hack "1" PHP_INI_SYSTEM Удалено в PHP 7.3.0
opcache.dups_fix "0" PHP_INI_ALL  
opcache.blacklist_filename "" PHP_INI_SYSTEM  
opcache.max_file_size "0" PHP_INI_SYSTEM  
opcache.consistency_checks "0" PHP_INI_ALL  
opcache.force_restart_timeout "180" PHP_INI_SYSTEM  
opcache.error_log "" PHP_INI_SYSTEM  
opcache.log_verbosity_level "1" PHP_INI_SYSTEM  
opcache.record_warnings "0" PHP_INI_SYSTEM Доступно, начиная с PHP 8.0.0.
opcache.preferred_memory_model "" PHP_INI_SYSTEM  
opcache.protect_memory "0" PHP_INI_SYSTEM  
opcache.mmap_base null PHP_INI_SYSTEM  
opcache.restrict_api "" PHP_INI_SYSTEM  
opcache.file_update_protection "2" PHP_INI_ALL  
opcache.huge_code_pages "0" PHP_INI_SYSTEM  
opcache.lockfile_path "/tmp" PHP_INI_SYSTEM  
opcache.opt_debug_level "0" PHP_INI_SYSTEM Доступно с PHP 7.1.0
opcache.file_cache NULL PHP_INI_SYSTEM  
opcache.file_cache_only "0" PHP_INI_SYSTEM  
opcache.file_cache_consistency_checks "1" PHP_INI_SYSTEM  
opcache.file_cache_fallback "1" PHP_INI_SYSTEM  
opcache.validate_permission "0" PHP_INI_SYSTEM Доступно с PHP 7.0.14
opcache.validate_root "0" PHP_INI_SYSTEM Доступно с PHP 7.0.14
opcache.preload "" PHP_INI_SYSTEM Доступно с PHP 7.4.0
opcache.preload_user "" PHP_INI_SYSTEM Доступно с PHP 7.4.0
opcache.cache_id "" PHP_INI_SYSTEM Только в Windows. Доступно с PHP 7.4.0
opcache.jit "tracing" PHP_INI_ALL Доступно с PHP 8.0.0
opcache.jit_buffer_size "0" PHP_INI_SYSTEM Доступно с PHP 8.0.0
opcache.jit_debug "0" PHP_INI_ALL Доступно с PHP 8.0.0
opcache.jit_bisect_limit "0" PHP_INI_ALL Доступно с PHP 8.0.0
opcache.jit_prof_threshold "0.005" PHP_INI_ALL Доступно с PHP 8.0.0
opcache.jit_max_root_traces "1024" PHP_INI_SYSTEM Доступно с PHP 8.0.0
opcache.jit_max_side_traces "128" PHP_INI_SYSTEM Доступно с PHP 8.0.0
opcache.jit_max_exit_counters "8192" PHP_INI_SYSTEM Доступно с PHP 8.0.0
opcache.jit_hot_loop "64" PHP_INI_SYSTEM Доступно с PHP 8.0.0
opcache.jit_hot_func "127" PHP_INI_SYSTEM Доступно с PHP 8.0.0
opcache.jit_hot_return "8" PHP_INI_SYSTEM Доступно с PHP 8.0.0
opcache.jit_hot_side_exit "8" PHP_INI_SYSTEM Доступно с PHP 8.0.0
opcache.jit_blacklist_root_trace "16" PHP_INI_ALL Доступно с PHP 8.0.0
opcache.jit_blacklist_side_trace "8" PHP_INI_ALL Доступно с PHP 8.0.0
opcache.jit_max_loop_unrolls "8" PHP_INI_ALL Доступно с PHP 8.0.0
opcache.jit_max_recursive_calls "2" PHP_INI_ALL Доступно с PHP 8.0.0
opcache.jit_max_recursive_returns "2" PHP_INI_ALL Доступно с PHP 8.0.0
opcache.jit_max_polymorphic_calls "2" PHP_INI_ALL Доступно с PHP 8.0.0
Для подробного описания констант PHP_INI_*, обратитесь к разделу Где могут быть установлены параметры конфигурации.

Краткое разъяснение конфигурационных директив.

opcache.enable bool

Разрешает кеширование опкодов. Если запрещено, код не будет оптимизироваться и кешироваться. Опцию opcache.enable нельзя включить во время исполнения с помощью ini_set(), но можно выключить. Попытка включить её таким образом приведёт к генерации предупреждения.

opcache.enable_cli bool

Разрешает кеширование опкодов для CLI-версии PHP.

opcache.memory_consumption int

Размер разделяемой памяти в мегабайтах для OPcache. Минимально допустимое значение - "8", которое применяется, если установлено меньшее значение.

opcache.interned_strings_buffer int

Количество памяти в мегабайтах для хранения интернированных строк.

opcache.max_accelerated_files int

Максимальное количество ключей (и, соответственно, скриптов) в хеш-таблице OPcache. Фактическое используемое значение будет первым числом из набора { 223, 463, 983, 1979, 3907, 7963, 16229, 32531, 65407, 130987, 262237, 524521, 1048793 }, которое больше или равно заданному в этом параметре. Минимум 200, максимум 1000000. Значения за пределами этого диапазона ограничены до допустимого диапазона.

opcache.max_wasted_percentage int

Максимальное значение потерянной памяти (в процентах) после которого планируется перезапуск, если недостаточно свободной памяти. Максимально допустимое значение: "50", которое применяется, если установлено большее значение.

opcache.use_cwd bool

Если включено, OPcache добавляет текущую рабочую директорию к ключу скрипта, тем самым устраняя возможность коллизий для файлов с одинаковым именем. Отключение этой опции повышает производительность, но может привести к сбоям.

opcache.validate_timestamps bool

Если включено, OPcache будет проверять актуальность закешированных скриптов каждые opcache.revalidate_freq секунд. Когда запрещено, вы можете перезапустить OPcache вручную с помощью opcache_reset(), opcache_invalidate() или перезапустив веб-сервер для того, чтобы изменения вступили в силу.

Замечание: OPcache всё ещё может проверять временную метку файла, если для опций opcache.file_update_protection или opcache.max_file_size установлены ненулевые значения.

opcache.revalidate_freq int

Как часто в секундах проверять временные метки файлов. 0 приведёт к тому, что OPcache будет производить эту проверку при каждом запросе.

Эта директива игнорируется, если выключена opcache.validate_timestamps.

opcache.revalidate_path bool

Если выключено, существующие закешированные файлы, использующие один и тот же include_path, будут повторно использоваться. Таким образом, если файл с тем же именем находится в другом месте в include_path, он не будет найден.

opcache.save_comments bool

Если выключено, все комментарии будут отброшены из кеша опкодов для минимизации размера кода. Отключение этой опции может привести к тому, что некоторые фреймворки, полагающиеся на аннотации в комментариях, перестанут работать, включая Doctrine, Zend Framework 2 и PHPUnit.

opcache.fast_shutdown bool

Если включено, то будет использована быстрая последовательность перезагрузки, при которой не происходит очистки всех выделенных блоков памяти. Вместо этого для освобождения всего набора переменных используется стандартный менеджер памяти Zend Engine.

Эта директива была удалена в PHP 7.2.0. Вариант быстрой последовательности перезагрузки был интегрирован в PHP и автоматически будет использоваться, если это возможно.

opcache.enable_file_override bool

Если включено, то кеш опкодов будет проверять, закеширован ли уже файл при вызове функций file_exists(), is_file() и is_readable(). Это может повысить производительность для приложений, проверяющих присутствие и доступность для чтения скриптом PHP, но несёт риск возврата устаревших данных, если запрещена опция opcache.validate_timestamps.

opcache.optimization_level int

Битовая маска, контролирующая, какие шаги оптимизации выполняются. По умолчанию применяются все безопасные оптимизации. Изменение значения по умолчанию в основном полезно для отладки/разработки оптимизатора (смотрите также opcache.opt_debug_level).

opcache.inherited_hack bool

Эта директива игнорируется.

opcache.dups_fix bool

Этот хак требуется только для обхода ошибок "Cannot redeclare class".

opcache.blacklist_filename string

Местоположение чёрного списка OPcache. Файл чёрного списка содержит имена файлов, которые не нужно ускорять, по одной записи на строку. Допустимы шаблоны поиска и префиксы. Строки, начинающиеся с точки с запятой игнорируются

Пример простого чёрного списка:

; Указываем конкретный файл.
/var/www/broken.php
; Префикс, обозначающий все файлы, начинающиеся с x.
/var/www/x
; Шаблон поиска.
/var/www/*-broken.php
opcache.max_file_size int

Максимальный размер файла для кеширования в байтах. Если задать 0, то кешироваться будут все файлы.

opcache.consistency_checks int

Если не ноль, OPcache будет сверять контрольную сумму кеша каждые N запросов, где N - заданное в этой директиве значение. Рекомендуется включать только при отладке, так как сильно влияет на производительность.

opcache.force_restart_timeout int

Количество секунд ожидания освобождения кеша, после которого будет принудительно произведён запланированный перезапуск. Если это время превышено, OPcache считает, что происходит что-то неправильное и убивает процесс, блокирующий кеш.

Если параметр opcache.log_verbosity_level задать равным 2 или больше, то, при возникновении подобной ситуации, в лог ошибок будет записано предупреждение.

Директива не поддерживается в Windows.

opcache.error_log string

Лог ошибок OPcache. Пустая строка считается как stderr, и ошибки будут выведены в стандартный поток ошибок (в большинстве случаев это лог ошибок веб-сервера).

opcache.log_verbosity_level int

Уровень подробности лога ошибок. По умолчанию будут записываться только фатальные ошибки (уровень 0) и ошибки (уровень 1). Также значения могут быть следующими: предупреждения (уровень 2), информационные сообщения (уровень 3) и сообщения отладки (уровень 4).

opcache.record_warnings bool

Если включено, OPcache запишет предупреждения во время компиляции и воспроизведёт их при следующем включении, даже если оно выполняется из кеша.

opcache.preferred_memory_model string

Предпочитаемая модель памяти для OPcache. Если оставить пустым, то OPcache самостоятельно выберет наиболее подходящую модель, которая будет вести себя корректно практически в любых случаях.

Возможные значения включают mmap, shm, posix и win32.

opcache.protect_memory bool

Защищает разделяемую память от неожиданной записи во время запуска скриптов. Полезно только для внутренней отладки.

opcache.mmap_base string

Базовое значение для сегмента разделяемой памяти в Windows. Все процессы PHP должны отображать разделяемую память в одинаковое адресное пространство. Данная опция помогает починить ошибки типа "Unable to reattach to base address".

opcache.restrict_api string

Позволяет вызывать функции API OPcache только скриптам, чей путь начинается с указанной строки. Значение по умолчанию "" означает отсутствие ограничений.

opcache.file_update_protection string

Предотвращает кеширование файлов младше указанного количества секунд. Это помогает предотвратить кеширование не до конца обновлённых файлов. В случае, если у вас все обновления файлов атомарны, можно повысить производительность, задав этот параметр равным "0".

opcache.huge_code_pages bool

Включает или отключает копирование кода PHP (текстового сегмента) в HUGE PAGES. Это может повысить производительность, но требует соответствующих системных настроек. Доступно в Linux начиная с PHP 7.0.0 и FreeBSD начиная с PHP 7.4.0.

opcache.lockfile_path string

Абсолютный путь к хранилищу общих файлов блокировок (только *nix)

opcache.opt_debug_level string

Производит вывод опкодов для отладки разных этапов оптимизации. 0x10000 приведёт к выводу опкодов как только они сгенерированы компилятором, до применения какой-либо оптимизации. 0x20000 приведёт к выводу опкодов после оптимизации.

opcache.file_cache string

Разрешает и задаёт директорию кеша второго уровня. Это должно повысить производительность в случае, если память SHM заполнена, сервер перезапущен или SHM сброшена. Значение по умолчанию "" запрещает кеширование на файловой системе.

opcache.file_cache_only bool

Включает или выключает кеширование опкодов в разделяемой памяти.

Замечание:

До PHP 8.1.0 отключение этой директивы с уже заполненным файловым кешем требовало ручной очистки файлового кеша.

opcache.file_cache_consistency_checks bool

Включает или выключает проверку контрольной суммы при загрузке скрипта из файлового кеша.

opcache.file_cache_fallback bool

Применяет opcache.file_cache_only=1 для некоторых процессов, которые завершились ошибкой при переподключении к разделяемой памяти (только для Windows). Требуется явно разрешённое кеширование на файловую систему.

Предостережение

Отключение этой опции конфигурации может помешать запуску процессов, и поэтому не рекомендуется.

opcache.validate_permission bool

Проверяет права доступа к кешированному файлу для текущего пользователя.

opcache.validate_root bool

Предотвращает коллизии имён в chroot-окружении. Должно быть включено для всех случаев использования chroot-окружений для предотвращения доступа к файлам за пределами chroot.

opcache.preload string

Задаёт скрипт PHP, который будет скомпилирован и запущен при старте сервера и сможет предзагрузить другие файлы, либо с помощью include, либо используя функцию opcache_compile_file(). Все сущности (например функции и классы), определённые в этих файлах, автоматически будут доступны до момента выключения сервера.

Замечание:

Предварительная загрузка не поддерживается в Windows.

opcache.preload_user string

Позволяет запускать предварительную загрузку от имени указанного пользователя системы. Полезно для серверов, которые запускаются от имени root перед переключением на непривилегированного пользователя системы. По умолчанию предварительная загрузка от имени root запрещена по соображениям безопасности, если только этой директиве явно не установлено значение root.

opcache.cache_id string

В Windows все процессы, выполняющие один и тот же PHP SAPI под одной и той же учётной записью пользователя с одинаковым идентификатором кеша, совместно используют один экземпляр OPcache. Значение идентификатора кеша может быть свободно выбрано.

Подсказка

Для IIS разные пулы приложений могут иметь собственный экземпляр OPcache, используя переменную среды APP_POOL_ID как opcache.cache_id.

opcache.jit string|int

Для обычного использования параметр принимает одно из четырёх строковых значений:

  • disable: Полностью отключён, не может быть включён во время выполнения.
  • off: Отключено, но может быть включено во время выполнения.
  • tracing/on: Используйте трассировку JIT. Включено по умолчанию и рекомендуется для большинства пользователей.
  • function: Используйте функцию JIT.

Для расширенного использования параметр принимает 4-значное целое число CRTO, где цифры означают:

C (Флаги оптимизации для процессора)
  • 0: Отключить оптимизацию для ЦП.
  • 1: Включите использование AVX, если ЦП поддерживает его.
R (распределение регистров)
  • 0: Не выполнять распределение регистров.
  • 1: Выполнять выделение локального блочного регистра.
  • 2: Выполнять выделение глобального регистра.
T (триггер)
  • 0: Компиляция всех функций при загрузке скрипта.
  • 1: Компиляция функций при первом выполнении.
  • 2: Профилирование функций при первом запросе и затем компилирование самых популярных функций.
  • 3: Профилирование на лету и компиляция горячих функций.
  • 4: В настоящее время не используется.
  • 5: Использование трассировки JIT. Профилирование на лету и компиляция трассировки для горячих сегментов кода.
O (уровень оптимизации)
  • 0: Без JIT.
  • 1: Минимальный JIT (вызов стандартных обработчиков виртуальных машин).
  • 2: Встроенные обработчики виртуальных машин.
  • 3: Использовать вывод типа.
  • 4: Использовать график вызовов.
  • 5: Оптимизировать весь скрипт.
Режим "tracing" соответствует CRTO = 1254, Режим "function" соответствует CRTO = 1205.

opcache.jit_buffer_size int

Объем разделяемой памяти, резервируемый для скомпилированного JIT-кода. Нулевое значение отключает JIT.

Если используется int, значение измеряется байтами. Вы также можете использовать сокращённую запись, которая описана в этом разделе FAQ.
opcache.jit_debug int

Битовая маска, определяющая, какой вывод отладки JIT следует включить. Возможные значения смотрите в файле » zend_jit.h (поиск макроопределений, начинающихся с ZEND_JIT_DEBUG).

opcache.jit_bisect_limit int

Опция отладки, отключающая JIT-компиляцию после компиляции определённого количества функций. Может быть полезно для разделения источника неправильной компиляции JIT. Примечание: этот параметр работает, только если для триггера JIT установлено значение 0 (компиляция при загрузке скрипта) или 1 (компиляция при первом выполнении), например, opcache.jit=1215. Подробнее смотрите в разделе opcache.jit.

opcache.jit_prof_threshold float

При использовании режима триггера "профилирование функций при первом запросе" этот порог определяет, считается ли функция горячей. Количество вызовов функции, разделённое на количество вызовов всех функций, должно быть выше порогового значения. Например, порог 0,005 означает, что функции, составляющие более 0,5% всех вызовов, будут скомпилированы JIT.

opcache.jit_max_root_traces int

Максимальное количество корневых стеков вызова. Корневой стек вызова - это поток выполнения, проходящий по коду сначала по одному пути, что является единицей компиляции JIT. JIT не будет компилировать новый код, если он достигнет этого предела.

opcache.jit_max_side_traces int

Максимальное количество боковых стеков вызова, которые может иметь корневой стек. Боковой стек вызова - это другой поток выполнения, который не следует по пути скомпилированного корневого стека вызова. Боковые стеки вызова, принадлежащие одному и тому же корневому стеку вызова, не будут компилироваться, если они достигают этого предела.

opcache.jit_max_exit_counters int

Максимальное количество счётчиков выхода бокового стека вызова. Это ограничивает общее количество боковых стеков, которые могут быть во всех корневых стеках.

opcache.jit_hot_loop int

Через сколько итераций цикл считается горячим. Допустимый диапазон значений: [0,255]; для любого значения вне этого диапазона, например, -1 или 256, будет использоваться значение по умолчанию. В частности, нулевое значение отключит JIT для отслеживания и компиляции любых циклов.

opcache.jit_hot_func int

Через сколько вызовов функция считается горячей. Допустимый диапазон значений: [0,255]; для любого значения вне этого диапазона, например, -1 или 256, будет использоваться значение по умолчанию. В частности, нулевое значение отключит JIT для отслеживания и компиляции любых функций.

opcache.jit_hot_return int

Через сколько возвратов возврат считается горячим. Допустимый диапазон значений: [0,255]; для любого значения вне этого диапазона, например, -1 или 256, будет использоваться значение по умолчанию. В частности, нулевое значение отключит JIT для отслеживания и компиляции любых возвратов.

opcache.jit_hot_side_exit int

Через сколько выходов боковой стек считается горячим. Допустимый диапазон значений: [0,255]; для любого значения вне этого диапазона, например, -1 или 256, будет использоваться значение по умолчанию. В частности, нулевое значение отключит JIT для отслеживания и компиляции любых побочных выходов.

opcache.jit_blacklist_root_trace int

Максимальное количество попыток компиляции корневой трассировки, прежде чем она будет занесена в чёрный список.

opcache.jit_blacklist_side_trace int

Максимальное количество попыток компиляции боковой трассировки до того, как она будет занесена в чёрный список.

opcache.jit_max_loop_unrolls int

Максимальное количество попыток развернуть цикл в боковой трассировке, пытаясь достичь корневой трассировки и закрыть внешний цикл.

opcache.jit_max_recursive_calls int

Максимальное количество развёрнутых рекурсивных циклов вызова.

opcache.jit_max_recursive_returns int

Максимальное количество развёрнутых рекурсивных циклов возврата.

opcache.jit_max_polymorphic_calls int

Максимальное количество попыток встроенных полиморфных (динамических или методических) вызовов. Вызовы выше этого лимита обрабатываются как метаморфические и не встраиваются.



Типы ресурсов

Данный модуль не определяет каких-либо типов ресурсов.




Preloading

Начиная с PHP 7.4.0, можно настроить предзагрузку скриптов в opcache в момент старта PHP. Любые функции, классы, интерфейсы или трейты (но не константы) в этих файлах будут глобально доступны для всех запросов без необходимости их явной загрузки. Такая предзагрузка позволяет добиться больших удобства и производительности (потому, что код всегда доступен) за счёт использования большего количества памяти. Также, при внесении изменений в предзагруженные скрипты, чтобы эти изменения стали доступны, придётся перезагрузить PHP. Из этого следует, что предзагрузку имеет смысл использовать только в промышленном окружении, но не в разработческом.

Обратите внимание, что баланс повышения производительности и потребления памяти сильно зависит от вашего приложения. "Предзагрузка всего на свете" может быть простейшей стратегией, но совсем не обязательно лучшей. Также, предзагрузка будет работать только в случае, когда PHP работает в режиме обслуживания запросов без перезагрузки. Таким образом, хоть предзагрузку и можно использовать в режиме CLI с включённым opcache, но, в большинстве случаев бессмысленно. Исключением является использование предзагрузки с библиотеками FFI.

Замечание:

Предзагрузка не поддерживается в Windows.

Настройка предзагрузки состоит из двух этапов и требует включённого opcache. Для начала, настройте opcache.preload в php.ini:

opcache.preload=preload.php

preload.php - это обязательный файл, который будет запущен один раз при старте сервера (PHP-FPM, mod_php, etc.) и который загрузит код в постоянную память. В серверах, которые запускаются от имени root перед переключением на непривилегированного пользователя системы или если PHP запускается от имени root (не рекомендуется), значение opcache.preload_user может указывать системного пользователя для запуска предварительной загрузки. Запуск предварительной загрузки от имени root по умолчанию запрещён. Установите opcache.preload_user=root, чтобы явно разрешить это.

В скрипте preload.php, любой файл указанный в include, include_once, require, require_once или opcache_compile_file() будет загружен в постоянную память. В следующем примере, будут загружены все файлы .php в директории src, если они не содержат Test в имени.

<?php
$directory
= new RecursiveDirectoryIterator(__DIR__ . '/src');
$fullTree = new RecursiveIteratorIterator($directory);
$phpFiles = new RegexIterator($fullTree, '/.+((?<!Test)+\.php$)/i', RecursiveRegexIterator::GET_MATCH);

foreach (
$phpFiles as $key => $file) {
require_once(
$file[0]);
}
?>

И include и opcache_compile_file() будут работать, но при этом будут немного по разному обработаны.

  • include запустит код из файла, а opcache_compile_file() нет. Это повлияет только на условные декларации (функции объявленные в блоках if).
  • Из за того, что include запустит код, вложенные include также будут обработаны и предзагружены.
  • opcache_compile_file() может загружать файлы в любом порядке. То есть, если файл a.php определяет класс A и b.php определяет класс B, который является наследником A, то opcache_compile_file() может загрузить эти два файла в любом порядке. При использовании include, с другой стороны, a.php должен быть загружен первым.
  • В любом случае, если какой-то скрипт в последствии запросит включение уже предзагруженного скрипта, то он будет выполнен, но сущности пересоздаваться не будут. Использование include_once не предотвратит повторное включение файла. Может потребоваться загрузить файл снова, чтобы включить в него определённые глобальные константы, поскольку они не обрабатываются предварительной загрузкой.
Какой подход использовать - зависит от желаемого поведения. Для кода, который использует автозагрузчик, подход с opcache_compile_file() даст больше гибкости. С кодом, который будет загружаться вручную, вариант с include может быть более надёжным.



Функции OPcache


opcache_compile_file

(PHP 5 >= 5.5.5, PHP 7, PHP 8, PECL ZendOpcache > 7.0.2)

opcache_compile_fileСкомпилировать и закешировать, но не исполнять скрипт PHP

Описание

opcache_compile_file(string $filename): bool

Эта функция компилирует PHP-скрипт и помещает его в кеш опкодов, но не запускает его. Можно использовать для прогрева кеша после перезапуска веб-сервера.

Список параметров

filename

Путь к скрипту PHP.

Возвращаемые значения

Возвращает true, если filename успешно скомпилирован или false в случае возникновения ошибки.

Ошибки

Если filename не может быть загружен или скомпилирован, будет выдана ошибка уровня E_WARNING. Для подавления предупреждения можно использовать @.

Смотрите также



opcache_get_configuration

(PHP 5 >= 5.5.0, PHP 7, PHP 8, PECL ZendOpcache > 7.0.2)

opcache_get_configurationПолучить конфигурационную информацию кеша

Описание

opcache_get_configuration(): array|false

Эта функция возвращает настройки конфигурации экземпляра кеша.

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Возвращает массив с информацией, включая INI-настройки, чёрный список и версию

Ошибки

Если используется opcache.restrict_api и текущий путь подпадает под запрет, то будет вызвана ошибка уровня E_WARNING и никаких данных возвращено не будет.

Смотрите также



opcache_get_status

(PHP 5 >= 5.5.0, PHP 7, PHP 8, PECL ZendOpcache > 7.0.2)

opcache_get_statusПолучить информацию о состоянии кеша

Описание

opcache_get_status(bool $include_scripts = true): array|false

Функция возвращает информацию о состоянии экземпляра кеша в памяти. Она не возвращает никакой информации о файловом кеше.

Список параметров

include_scripts

Включить информацию о состоянии конкретного скрипта.

Возвращаемые значения

Возвращает массив, опционально содержащий информацию о состоянии конкретного скрипта или false в случае возникновения ошибки.

Ошибки

Если используется opcache.restrict_api и текущий путь подпадает под запрет, то будет вызвана ошибка уровня E_WARNING и никаких данных возвращено не будет.

Смотрите также



opcache_invalidate

(PHP 5 >= 5.5.0, PHP 7, PHP 8, PECL ZendOpcache >= 7.0.0)

opcache_invalidateАннулирует закешированный скрипт

Описание

opcache_invalidate(string $filename, bool $force = false): bool

Функция аннулирует закешированный скрипт. Если параметр force не задан или задан как false, скрипт аннулируется, только если скрипт был модифицирован после помещения в кеш. Функция аннулирует только кеш в памяти, не затрагивая файловый кеш.

Список параметров

filename

Путь к скрипту.

force

Если установлено как true, кеш скрипта будет принудительно аннулирован независимо от того, требуется ли это или нет

Возвращаемые значения

Возвращает true, если кеш опкодов для filename аннулирован, либо если аннулировать нечего. В случае, если кеш опкодов отключён, возвращается false.

Смотрите также

  • opcache_compile_file() - Скомпилировать и закешировать, но не исполнять скрипт PHP
  • opcache_reset() - Сбрасывает содержимое кеша опкодов



opcache_is_script_cached

(PHP 5 >= 5.5.11, PHP 7, PHP 8, PECL ZendOpcache >= 7.0.4)

opcache_is_script_cachedПроверяет, закеширован ли скрипт в OPCache

Описание

opcache_is_script_cached(string $filename): bool

Функция проверяет, закеширован ли указанный скрипт в OPCache. Может быть использована для определения, прогрет ли кеш для конкретного скрипта. Функция проверяет только кеш в памяти, не проверяя файловый кеш.

Список параметров

filename

Путь к файлу скрипта.

Возвращаемые значения

Возвращает true, если filename закеширован в OPCache, false если нет.

Смотрите также

  • opcache_compile_file() - Скомпилировать и закешировать, но не исполнять скрипт PHP



opcache_reset

(PHP 5 >= 5.5.0, PHP 7, PHP 8, PECL ZendOpcache >= 7.0.0)

opcache_resetСбрасывает содержимое кеша опкодов

Описание

opcache_reset(): bool

Функция сбрасывает весь кеш. После вызова opcache_reset() все скрипты будут заново загружены, скомпилированы и помещены в кеш после их следующего вызова. Функция сбрасывает только кеш в памяти, не затрагивая файловый кеш.

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Возвращает true, если кеш опкодов был сброшен или false, если кеш отключён, ожидается перезапуск или перезапуск выполняется (смотрите opcache_get_status()).

Смотрите также


Содержание

  • opcache_compile_file — Скомпилировать и закешировать, но не исполнять скрипт PHP
  • opcache_get_configuration — Получить конфигурационную информацию кеша
  • opcache_get_status — Получить информацию о состоянии кеша
  • opcache_invalidate — Аннулирует закешированный скрипт
  • opcache_is_script_cached — Проверяет, закеширован ли скрипт в OPCache
  • opcache_reset — Сбрасывает содержимое кеша опкодов



Управление буфером вывода


Введение

Функции управления выводом позволяют вам контролировать вывод, отправляемый скриптом. Это может быть полезно в различных ситуациях, особенно если вам необходимо отправить заголовки в браузер после того, как ваш скрипт уже начал выводить данные. Функции управления выводом не влияют на заголовки, отправленные с помощью функций header() или setcookie(), а влияют только на такие функции, как echo и данные между блоками PHP-кода.



Установка и настройка

Содержание


Требования

Для сборки этого модуля не требуются внешние библиотеки.



Установка

Для использования этих функций не требуется проведение установки, поскольку они являются частью ядра PHP.



Настройка во время выполнения

Поведение этих функций зависит от установок в php.ini.

Конфигурационные опции управления выводом
Имя По умолчанию Место изменения Список изменений
output_buffering "0" PHP_INI_PERDIR  
output_handler NULL PHP_INI_PERDIR  
implicit_flush "0" PHP_INI_ALL  
url_rewriter.tags "a=href,area=href,frame=src,form=,fieldset=" PHP_INI_ALL До PHP 7.1.0 использовалась для установки перезаписи сессии "trans sid". С PHP 7.1.0 используется только output_add_rewrite_var().
url_rewriter.hosts $_SERVER['HTTP_HOST'] используется по умолчанию. PHP_INI_ALL Доступно с PHP 7.1.0
Для подробного описания констант PHP_INI_*, обратитесь к разделу Где могут быть установлены параметры конфигурации.

Краткое разъяснение конфигурационных директив.

output_buffering bool/integer

Вы можете разрешить буферизацию вывода для всех файлов, установив эту директиву в 'On'. Если вы хотите ограничить размер буфера до определённого размера, вы можете установить не 'On', а максимальное количество байт в этой директиве (например, output_buffering=4096). Эта директива всегда отключена в PHP-CLI.

output_handler string

Вы можете перенаправить весь вывод вашего скрипта в функцию. Для примера, если вы установите output_handler в mb_output_handler(), то кодировка символов прозрачно преобразуется в соответствии с указанной кодировкой. Настройка любого обработчика вывода автоматически включает буферизацию вывода.

Замечание:

Вы не можете использовать вместе mb_output_handler() с ob_iconv_handler(), и вы не можете использовать вместе ob_gzhandler() и zlib.output_compression.

Замечание:

Только встроенные функции могут использоваться с этой директивой. Для функции, определённой пользователем, используйте ob_start().

implicit_flush bool

false по умолчанию. Изменение значения на true указывает PHP не сохранять данные в буфер, а после каждого отправленного блока автоматически отправлять данные в выходной слой. Это эквивалентно вызову PHP-функции flush() после каждого вызова print или echo для каждого HTML-блока.

При использовании PHP в веб-среде, включение этой опции приведёт к серьёзной потере производительности, поэтому рекомендуется использовать её только для отладки. Это значение по умолчанию имеет true при работе в CLI SAPI.

Сморите также ob_implicit_flush().

url_rewriter.tags string
url_rewriter.tags определяет, какие HTML-теги будут перезаписаны значениями output_add_rewrite_var(). По умолчанию a=href,area=href,frame=src,input=src,form= form является специальным тегом. <input hidden="session_id" name="session_name"> добавляется как переменная формы.

Замечание: До PHP 7.1.0 надо было использовать url_rewriter.tags для указания session.trans_sid_tags. Начиная с PHP 7.1.0, fieldset больше не рассматривается как специальный тег.

url_rewriter.hosts string
url_rewriter.hosts указывает, какие хосты перезаписываются для включения значений output_add_rewrite_var(). По умолчанию используется $_SERVER['HTTP_HOST']. Несколько хостов можно указать перечислив их через запятую, между хостами не должно быть пробелов. То есть php.net,wiki.php.net,bugs.php.net



Типы ресурсов

Данный модуль не определяет каких-либо типов ресурсов.




Предопределённые константы

Перечисленные ниже константы всегда доступны как часть ядра PHP.

PHP_OUTPUT_HANDLER_START (int)

Служит признаком того, что буферирование вывода началось.

PHP_OUTPUT_HANDLER_WRITE (int)

Служит признаком того, что буфер вывода очищается и в нем находятся данные для вывода.

PHP_OUTPUT_HANDLER_FLUSH (int)

Обозначает, что буфер был сброшен (очищен и выведен).

PHP_OUTPUT_HANDLER_CLEAN (int)

Обозначает, что буфер был очищен.

PHP_OUTPUT_HANDLER_FINAL (int)

Обозначает, что это последняя операция буферирования.

PHP_OUTPUT_HANDLER_CONT (int)

Обозначает, что буфер был очищен, но буферирование вывода будет продолжено.

Это синоним для PHP_OUTPUT_HANDLER_WRITE.

PHP_OUTPUT_HANDLER_END (int)

Обозначает, что буферирование вывода завершено.

Это синоним для PHP_OUTPUT_HANDLER_FINAL.

PHP_OUTPUT_HANDLER_CLEANABLE (int)

Определяет может ли буфер вывода, созданный ob_start(), быть очищенным.

PHP_OUTPUT_HANDLER_FLUSHABLE (int)

Определяет может ли буфер вывода, созданный ob_start(), быть сброшен (выведен и очищен).

PHP_OUTPUT_HANDLER_REMOVABLE (int)

Определяет может ли буфер вывода, созданный ob_start(), быть удалённым до завершения скрипта.

PHP_OUTPUT_HANDLER_STDFLAGS (int)

Значение по умолчанию для флагов буфера вывода. Равняется PHP_OUTPUT_HANDLER_CLEANABLE | PHP_OUTPUT_HANDLER_FLUSHABLE | PHP_OUTPUT_HANDLER_REMOVABLE.



Примеры

Содержание


Базовое использование

Пример #1 Пример контроля вывода

<?php

ob_start
();
echo
"Привет\n";

setcookie("cookiename", "cookiedata");

ob_end_flush();

?>

В приведённом выше примере вывод из echo будет храниться в буфере вывода до вызова ob_end_flush(). В то же время вызов setcookie() успешно сохранится в cookie браузера, не вызывая ошибки (заголовки не могут быть отправлены в браузер после того, как данные уже были отправлены).



Использование перезаписи вывода

Начиная с PHP 7.1.0, output_add_rewrite_var() и output_reset_rewrite_vars() используют отдельный буфер вывода, то есть не используют буфер вывода прозрачной поддержки sid.

Пример #1 Пример перезаписи вывода

<?php
// Этот код работает с PHP 7.1.0, 7.0.10, 5.6.25 и выше.

// HTTP_HOST - целевой хост по умолчанию. Зададим сами, чтобы код примера заработал.
$_SERVER['HTTP_HOST'] = 'php.net';

// Перезаписыватель вывода перезаписывает только "form". Добавим a=href.
// Теги должны указываться как tag_name=url_attr, то есть img=src,iframe=src
// Между настройками пробелы недопустимы.
// Тег "form" - специальный тег, в который добавляется скрытый "input"
ini_set('url_rewriter.tags','a=href,form=');
var_dump(ini_get('url_rewriter.tags'));

// Это добавлено в URL и "form"
output_add_rewrite_var('test', 'value');
?>
<a href="//php.net/index.php?bug=1234">bug1234</a>
<form action="https://php.net/?bug=1234&edit=1" action="post">
<input type="text" name="title" />
</form>

Результат выполнения данного примера:

<a href="//php.net/?bug=1234&test=value">bug1234</a>
<form action="https://php.net/?bug=1234&edit=1" method="post"><input type="hidden" name="test" value="value" />
 <input type="text" name="title" />
</form>

С PHP 7.1.0, функции перезаписи вывода имеют свои собственные INI-настройки. url_rewriter.tags и url_rewriter.hosts.




Функции контроля вывода

Смотрите также

Смотрите также header() и setcookie().


flush

(PHP 4, PHP 5, PHP 7, PHP 8)

flushСброс системного буфера вывода

Описание

flush(): void

Функция очищает системный буфер вывода PHP, при этом всё содержимое буфера отправляется в браузер пользователя (с некоторыми исключениями), независимо от используемого бекенда PHP (CGI, веб-сервер и т.д.).

flush() не сможет переопределить схему буферизации вашего веб-сервера и никак не влияет на буферизацию браузера на стороне клиента. Функция также не влияет на механизм буферизации пользовательского PHP-кода. Это означает, что ob_flush() должен быть вызван перед flush(), чтобы очистить выходные буферы, если они используются.

Некоторые серверы, особенно под управлением Win32, будут по-прежнему продолжать буферизировать вывод вашего скрипта до передачи результатов в браузер.

Серверные модули для Apache, такие как mod_gzip, могут сами выполнять буферизацию, поэтому flush() не приводит к немедленной передаче данных клиенту.

Браузер может также буферизировать поступающие к нему данные перед отображением. Например, Netscape, буферизирует текст до тех пор, пока не получит конец строки или начало тега, и не будет отображать таблицы пока не будет замечен тег </table> самой внешней таблицы.

Некоторые версии Microsoft Internet Explorer начинают отображать страницу только после получения 256 байт вывода, поэтому может понадобиться отправить дополнительные пробелы перед сбросом, чтобы такие браузеры отобразили страницу.

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Функция не возвращает значения после выполнения.

Смотрите также

  • ob_flush() - Сбросить (отправить) буфер вывода
  • ob_clean() - Очистить (стереть) буфер вывода
  • ob_end_flush() - Сбросить (отправить) буфер вывод и отключить буферизацию вывода
  • ob_end_clean() - Очистить (стереть) буфер вывода и отключить буферизацию вывода



ob_clean

(PHP 4 >= 4.2.0, PHP 5, PHP 7, PHP 8)

ob_cleanОчистить (стереть) буфер вывода

Описание

ob_clean(): bool

Эта функция очищает содержимое выходного буфера, не отправляя его в браузер.

Эта функция не уничтожает буфер вывода, как это делает ob_end_clean().

Буфер вывода должен запускаться функцией ob_start() с флагом PHP_OUTPUT_HANDLER_CLEANABLE. Иначе ob_clean() не сработает.

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Возвращает true в случае успешного выполнения или false в случае возникновения ошибки.

Смотрите также

  • ob_flush() - Сбросить (отправить) буфер вывода
  • ob_end_flush() - Сбросить (отправить) буфер вывод и отключить буферизацию вывода
  • ob_end_clean() - Очистить (стереть) буфер вывода и отключить буферизацию вывода



ob_end_clean

(PHP 4, PHP 5, PHP 7, PHP 8)

ob_end_cleanОчистить (стереть) буфер вывода и отключить буферизацию вывода

Описание

ob_end_clean(): bool

Эта функция удаляет содержимое самого верхнего буфера вывода и отключает эту буферизацию. Если вы хотите использовать содержимое буфера, то вам необходимо вызвать ob_get_contents() перед ob_end_clean(), так как все содержимое буфера удаляется при вызове ob_end_clean().

Буфер вывода должен запускаться функцией ob_start() с флагами PHP_OUTPUT_HANDLER_CLEANABLE и PHP_OUTPUT_HANDLER_REMOVABLE. Иначе не сработает ob_end_clean().

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Возвращает true в случае успешного выполнения или false в случае возникновения ошибки. Основной причиной неудачного завершения работы функции является её вызов без активного буфера или если буфер не может быть удалён (специальный тип буфера).

Ошибки

Если функция завершается ошибкой, генерируется E_NOTICE.

Примеры

Следующий пример показывает простой способ избавиться от всех выходных буферов:

Пример #1 Пример использования функции ob_end_clean()

<?php
ob_start
();
echo
'Текст, который не отобразится.';
ob_end_clean();
?>

Смотрите также

  • ob_start() - Включение буферизации вывода
  • ob_get_contents() - Возвращает содержимое буфера вывода
  • ob_flush() - Сбросить (отправить) буфер вывода



ob_end_flush

(PHP 4, PHP 5, PHP 7, PHP 8)

ob_end_flushСбросить (отправить) буфер вывод и отключить буферизацию вывода

Описание

ob_end_flush(): bool

Эта функция отправит содержимое самого верхнего буфера вывода (если оно имеется) и отключит этот буфер вывода. Если вы хотите использовать содержимое буфера, то вам необходимо вызвать ob_get_contents() перед ob_end_flush(), т.к. все содержимое буфера удаляется при вызове ob_end_flush().

Буфер вывода должен запускаться функцией ob_start() с флагами PHP_OUTPUT_HANDLER_FLUSHABLE и PHP_OUTPUT_HANDLER_REMOVABLE.

Замечание: Эта функция аналогична ob_get_flush(), за исключением того, что ob_get_flush() возвращает содержимое буфера в виде строки.

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Возвращает true в случае успешного выполнения или false в случае возникновения ошибки. Основной причиной неудачного завершения работы функции является её вызов без активного буфера или если буфер не может быть удалён (специальный тип буфера).

Ошибки

Если функция завершается ошибкой, генерируется E_NOTICE.

Примеры

Пример #1 Пример использования функции ob_end_flush()

Следующий пример показывает простой способ сброса и завершения всех буферов вывода:

<?php
while (@ob_end_flush());
?>

Смотрите также

  • ob_start() - Включение буферизации вывода
  • ob_get_contents() - Возвращает содержимое буфера вывода
  • ob_get_flush() - Сбросить буфер вывода, вернуть его в виде строки и отключить буферизацию вывода
  • ob_flush() - Сбросить (отправить) буфер вывода
  • ob_end_clean() - Очистить (стереть) буфер вывода и отключить буферизацию вывода



ob_flush

(PHP 4 >= 4.2.0, PHP 5, PHP 7, PHP 8)

ob_flushСбросить (отправить) буфер вывода

Описание

ob_flush(): bool

Эта функция отправит содержимое буфера вывода (если имеется). Если необходима дальнейшая обработка буфера вывода, то следует вызвать ob_get_contents() перед ob_flush(), так как содержимое буфера будет удалено после вызова ob_flush().

Эта функция не уничтожает буфер вывода, как это делает ob_end_flush().

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Возвращает true в случае успешного выполнения или false в случае возникновения ошибки.

Смотрите также

  • ob_get_contents() - Возвращает содержимое буфера вывода
  • ob_clean() - Очистить (стереть) буфер вывода
  • ob_end_flush() - Сбросить (отправить) буфер вывод и отключить буферизацию вывода
  • ob_end_clean() - Очистить (стереть) буфер вывода и отключить буферизацию вывода



ob_get_clean

(PHP 4 >= 4.3.0, PHP 5, PHP 7, PHP 8)

ob_get_cleanПолучить содержимое текущего буфера и удалить его

Описание

ob_get_clean(): string|false

Получает содержимое текущего буфера и затем удаляет текущий буфер.

ob_get_clean() по сути выполняет ob_get_contents() и ob_end_clean().

Буфер вывода должен запускаться функцией ob_start() с флагами PHP_OUTPUT_HANDLER_CLEANABLE и PHP_OUTPUT_HANDLER_REMOVABLE. Иначе ob_get_clean() не сработает.

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Возвращает содержимое буфера вывода и заканчивает буферизацию вывода. Если буферизация вывода не активирована, то функция вернёт false.

Примеры

Пример #1 Простой пример использования функции ob_get_clean()

<?php

ob_start
();

echo
"Привет мир";

$out = ob_get_clean();
$out = strtolower($out);

var_dump($out);
?>

Результат выполнения данного примера:


string(11) "привет мир"

Смотрите также

  • ob_get_contents() - Возвращает содержимое буфера вывода
  • ob_start() - Включение буферизации вывода



ob_get_contents

(PHP 4, PHP 5, PHP 7, PHP 8)

ob_get_contentsВозвращает содержимое буфера вывода

Описание

ob_get_contents(): string|false

Получает содержимое буфера без его очистки.

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Функция вернёт содержимое буфера вывода или false, если буферизация вывода не активирована.

Примеры

Пример #1 Простой пример использования функции ob_get_contents()

<?php

ob_start
();

echo
"Привет ";

$out1 = ob_get_contents();

echo
"Мир";

$out2 = ob_get_contents();

ob_end_clean();

var_dump($out1, $out2);
?>

Результат выполнения данного примера:

string(6) "Привет "
string(11) "Привет Мир"

Смотрите также

  • ob_start() - Включение буферизации вывода
  • ob_get_length() - Возвращает размер буфера вывода



ob_get_flush

(PHP 4 >= 4.3.0, PHP 5, PHP 7, PHP 8)

ob_get_flushСбросить буфер вывода, вернуть его в виде строки и отключить буферизацию вывода

Описание

ob_get_flush(): string|false

ob_get_flush() сбрасывает буфер вывода, возвращая его содержимое в виде строки и отключает буферизацию вывода.

Буфер вывода должен запускаться функцией ob_start() с флагом PHP_OUTPUT_HANDLER_FLUSHABLE. Иначе не сработает ob_get_flush().

Замечание: Эта функция аналогична ob_end_flush() за исключением того, что эта функция также возвращает буфер в виде строки.

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Возвращает буфер вывода или false, если буферизация не активна.

Примеры

Пример #1 Пример использования функции ob_get_flush()

<?php
//Используется output_buffering=On
print_r(ob_list_handlers());

//сохранить буфер в файл
$buffer = ob_get_flush();
file_put_contents('buffer.txt', $buffer);

print_r(ob_list_handlers());
?>

Результат выполнения данного примера:

Array
(
    [0] => default output handler
)
Array
(
)

Смотрите также

  • ob_end_clean() - Очистить (стереть) буфер вывода и отключить буферизацию вывода
  • ob_end_flush() - Сбросить (отправить) буфер вывод и отключить буферизацию вывода
  • ob_list_handlers() - Список всех используемых обработчиков вывода



ob_get_length

(PHP 4 >= 4.0.2, PHP 5, PHP 7, PHP 8)

ob_get_lengthВозвращает размер буфера вывода

Описание

ob_get_length(): int|false

Вернёт размер в байтах содержимого в буфере вывода.

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Возвращает размер в байтах содержимого буфера вывода или false, если буферизация не активна.

Примеры

Пример #1 Простой пример использования функции ob_get_length()

<?php

ob_start
();

echo
"Привет ";

$len1 = ob_get_length();

echo
"Мир";

$len2 = ob_get_length();

ob_end_clean();

echo
$len1 . ", " . $len2;
?>

Результат выполнения данного примера:

13, 19

Смотрите также

  • ob_start() - Включение буферизации вывода
  • ob_get_contents() - Возвращает содержимое буфера вывода



ob_get_level

(PHP 4 >= 4.2.0, PHP 5, PHP 7, PHP 8)

ob_get_levelВозвращает уровень вложенности механизма буферизации вывода

Описание

ob_get_level(): int

Вернёт уровень вложенности механизма буферизации вывода.

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Возвращает уровень вложенности обработчиков буферизации вывода или 0, если буферизация не активна.

Смотрите также

  • ob_start() - Включение буферизации вывода
  • ob_get_contents() - Возвращает содержимое буфера вывода



ob_get_status

(PHP 4 >= 4.2.0, PHP 5, PHP 7, PHP 8)

ob_get_statusПолучить статус буфера вывода

Описание

ob_get_status(bool $full_status = false): array

ob_get_status() возвращает информацию о состоянии буфера верхнего уровня или на всех уровнях активных буферов, если full_status установлен в true.

Список параметров

full_status

Если true, то вернёт все уровни активных буферов. Если false или не установлен, то вернёт статус только самого верхнего уровня.

Возвращаемые значения

Если функция вызвана без параметра full_status или full_status = false, то возвращается простой массив из следующих элементов:

Array
(
    [level] => 2
    [type] => 0
    [status] => 0
    [name] => URL-Rewriter
    [del] => 1
)
Результаты простого вызова ob_get_status()
КлючЗначение
levelУровень вложенности вывода
typePHP_OUTPUT_HANDLER_INTERNAL (0) или PHP_OUTPUT_HANDLER_USER (1)
type0 (внутренний обработчик) или 1 (предоставленный пользователем обработчик)
nameНазвание действующего обработчика вывода или 'default output handler', если не задан
delФлаг очистки, установленный ob_start()

Если функция вызвана с full_status = true, то возвращается массив из элементов уровней активных буферов. В качестве ключа используется уровень вывода, и каждый элемент массива содержит в себе массив информации о статусе одного из активных элементов вывода.

Array
(
    [0] => Array
        (
            [chunk_size] => 0
            [size] => 40960
            [block_size] => 10240
            [type] => 1
            [status] => 0
            [name] => default output handler
            [del] => 1
        )

    [1] => Array
        (
            [chunk_size] => 0
            [size] => 40960
            [block_size] => 10240
            [type] => 0
            [buffer_size] => 0
            [status] => 0
            [name] => URL-Rewriter
            [del] => 1
        )

)

Полный вывод содержит следующие дополнительные элементы:

Полные результаты ob_get_status()
КлючЗначение
chunk_sizeРазмер порции, установленный ob_start()
size...
blocksize...

Смотрите также

  • ob_get_level() - Возвращает уровень вложенности механизма буферизации вывода
  • ob_list_handlers() - Список всех используемых обработчиков вывода



ob_gzhandler

(PHP 4 >= 4.0.4, PHP 5, PHP 7, PHP 8)

ob_gzhandlercallback-функция, используемая для gzip-сжатия буфера вывода при вызове ob_start

Описание

ob_gzhandler(string $data, int $flags): string|false

Функция ob_gzhandler() предназначена для использования в качестве callback-функции для ob_start(), чтобы облегчить отправку gz-кодированных данных браузерам, поддерживающим сжатие веб-страниц. Прежде чем ob_gzhandler() отправит сжатые данные, она определяет, какой тип кодирования содержимого сможет принять браузер ("gzip", "deflate" или вообще никакой) и вернёт его содержимое соответствующим образом. Поддерживаются все браузеры, отправляющие корректные заголовки о том, что они принимают сжатые веб-страницы. Если браузер не поддерживает сжатие страниц, эта функция вернёт false.

Список параметров

data

flags

Возвращаемые значения

Примеры

Пример #1 Пример использования функции ob_gzhandler()

<?php

ob_start
("ob_gzhandler");

?>
<html>
<body>
<p>Это должно быть сжатой страницей.</p>
</body>
</html>

Примечания

Замечание:

ob_gzhandler() требует наличие модуля zlib.

Замечание:

Вы не можете использовать одновременно ob_gzhandler() и zlib.output_compression. Также обратите внимание, что использование zlib.output_compression предпочтительнее, чем ob_gzhandler().

Смотрите также

  • ob_start() - Включение буферизации вывода
  • ob_end_flush() - Сбросить (отправить) буфер вывод и отключить буферизацию вывода



ob_implicit_flush

(PHP 4, PHP 5, PHP 7, PHP 8)

ob_implicit_flushВключение/выключение неявного сброса

Описание

ob_implicit_flush(bool $enable = true): void

ob_implicit_flush() включает или выключает неявный сброс. Неявный сброс приводит к тому, что операция сброса выполняется после каждого вывода, поэтому явные вызовы функции flush() больше не понадобятся.

Список параметров

enable

true для включения неявного сброса, false в противном случае.

Возвращаемые значения

Функция не возвращает значения после выполнения.

Список изменений

Версия Описание
8.0.0 enable теперь принимает логическое значение (bool); ранее принималось целое число (int).

Смотрите также

  • flush() - Сброс системного буфера вывода
  • ob_start() - Включение буферизации вывода
  • ob_end_flush() - Сбросить (отправить) буфер вывод и отключить буферизацию вывода



ob_list_handlers

(PHP 4 >= 4.3.0, PHP 5, PHP 7, PHP 8)

ob_list_handlersСписок всех используемых обработчиков вывода

Описание

ob_list_handlers(): array

Список всех используемых обработчиков вывода.

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Функция вернёт массив с используемыми обработчиками вывода (если имеются). Если включён output_buffering или использовалась анонимная функция вместе с ob_start(), то ob_list_handlers() вернёт "default output handler".

Примеры

Пример #1 Пример использования функции ob_list_handlers()

<?php
//используется output_buffering=On
print_r(ob_list_handlers());
ob_end_flush();

ob_start("ob_gzhandler");
print_r(ob_list_handlers());
ob_end_flush();

// анонимная функция
ob_start(function($string) { return $string; });
print_r(ob_list_handlers());
ob_end_flush();
?>

Результат выполнения данного примера:

Array
(
    [0] => default output handler
)

Array
(
    [0] => ob_gzhandler
)

Array
(
    [0] => Closure::__invoke
)

Смотрите также

  • ob_end_clean() - Очистить (стереть) буфер вывода и отключить буферизацию вывода
  • ob_end_flush() - Сбросить (отправить) буфер вывод и отключить буферизацию вывода
  • ob_get_flush() - Сбросить буфер вывода, вернуть его в виде строки и отключить буферизацию вывода
  • ob_start() - Включение буферизации вывода



ob_start

(PHP 4, PHP 5, PHP 7, PHP 8)

ob_startВключение буферизации вывода

Описание

ob_start(callable $callback = null, int $chunk_size = 0, int $flags = PHP_OUTPUT_HANDLER_STDFLAGS): bool

Эта функция включает буферизацию вывода. Если буферизация вывода активна, никакой вывод скрипта не отправляется (кроме заголовков), а сохраняется во внутреннем буфере.

Содержимое этого внутреннего буфера может быть скопировано в строковую переменную, используя ob_get_contents(). Для вывода содержимого внутреннего буфера следует использовать ob_end_flush(). В качестве альтернативы можно использовать ob_end_clean() для очистки содержимого буфера.

Внимание

Некоторые веб-серверы (например, Apache) изменяют рабочую директорию скрипта при вызове callback-функции. Вы можете вернуть её назад, используя chdir(dirname($_SERVER['SCRIPT_FILENAME'])) в callback-функции.

Буферы вывода помещаются в стек, то есть допускается вызов ob_start() после вызова другой активной ob_start(). При этом необходимо вызывать ob_end_flush() соответствующее количество раз. Если активны несколько callback-функций, вывод последовательно фильтруется для каждой из них в порядке вложения.

Если буферизация вывода всё ещё активна, когда скрипт завершает работу, PHP автоматически выводит содержимое.

Список параметров

callback

Можно задать необязательный параметр callback. Эта функция принимает строку в виде аргумента и должна также вернуть строку. Она вызывается при сбросе (отправке) или очистке (с помощью ob_flush(), ob_clean() или подобных функций) или если буфер вывода сбрасывается в браузер по окончанию запроса. При вызове функции callback, она получает содержимое буфера и, как ожидается, должна вернуть обновлённое содержимое для буфера вывода, которое будет отправлено браузеру. Если callback не является допустимой функцией, то эта функция вернёт false. Описание функции для этого параметра:

handler(string $buffer, int $phase = ?): string
buffer
Содержимое буфера вывода.
phase
Битовая маска констант PHP_OUTPUT_HANDLER_*.

Если callback вернёт false, то оригинальная информация отправится в браузер без изменений.

Параметр callback может быть игнорирован передачей значения null.

ob_end_clean(), ob_end_flush(), ob_clean(), ob_flush() и ob_start() не могут вызываться из callback-функций, так как их поведение непредсказуемо. Если вы хотите удалить содержимое буфера, то верните "" (пустую строку) из callback-функции. Вы также не можете использовать функции буферизации вывода, такие как print_r($expression, true) или highlight_file($filename, true) из callback-функции.

Замечание:

Функция ob_gzhandler() была введена для облегчения отправки gz-кодированных данных браузерам, поддерживающим сжатые веб-страницы. ob_gzhandler() определяет тип кодировки содержимого, принимаемый браузером, и возвращает вывод соответствующим образом.

chunk_size

Если передан необязательный параметр chunk_size, то буфер буден сброшен после любого вывода, превышающего или равного по размеру chunk_size. Значение по умолчанию 0 означает, что функция вывода будет вызвана, когда буфер будет закрыт.

flags

Параметр flags является битовой маской, которая управляет операциями, которые можно совершать над буфером вывода. По умолчанию она позволяет буферу вывода быть очищенным, сброшенным и удалённым, что равносильно значению PHP_OUTPUT_HANDLER_CLEANABLE | PHP_OUTPUT_HANDLER_FLUSHABLE | PHP_OUTPUT_HANDLER_REMOVABLE или PHP_OUTPUT_HANDLER_STDFLAGS как сокращение этой комбинации.

Каждый флаг управляет доступом к набору функций, как описано ниже:

Константа Функции
PHP_OUTPUT_HANDLER_CLEANABLE ob_clean(), ob_end_clean() и ob_get_clean().
PHP_OUTPUT_HANDLER_FLUSHABLE ob_end_flush(), ob_flush() и ob_get_flush().
PHP_OUTPUT_HANDLER_REMOVABLE ob_end_clean(), ob_end_flush() и ob_get_flush().

Возвращаемые значения

Возвращает true в случае успешного выполнения или false в случае возникновения ошибки.

Примеры

Пример #1 Пример callback-функции, определённой пользователем

<?php

function callback($buffer)
{
// заменить все яблоки апельсинами
return (str_replace("яблоки", "апельсины", $buffer));
}

ob_start("callback");

?>
<html>
<body>
<p>Это всё равно что сравнить яблоки и апельсины.</p>
</body>
</html>
<?php

ob_end_flush
();

?>

Результат выполнения данного примера:

<html>
<body>
<p>Это всё равно что сравнить апельсины и апельсины.</p>
</body>
</html>

Пример #2 Создание нестираемого буфера вывода

<?php

ob_start
(null, 0, PHP_OUTPUT_HANDLER_STDFLAGS ^ PHP_OUTPUT_HANDLER_REMOVABLE);

?>

Смотрите также

  • ob_get_contents() - Возвращает содержимое буфера вывода
  • ob_end_clean() - Очистить (стереть) буфер вывода и отключить буферизацию вывода
  • ob_end_flush() - Сбросить (отправить) буфер вывод и отключить буферизацию вывода
  • ob_implicit_flush() - Включение/выключение неявного сброса
  • ob_gzhandler() - callback-функция, используемая для gzip-сжатия буфера вывода при вызове ob_start
  • ob_iconv_handler() - Преобразует символы из текущей кодировки в кодировку выходного буфера
  • mb_output_handler() - Callback-функция, преобразующая кодировку символов в выходном буфере
  • ob_tidyhandler() - Функция обратного вызова ob_start для восстановление буфера



output_add_rewrite_var

(PHP 4 >= 4.3.0, PHP 5, PHP 7, PHP 8)

output_add_rewrite_varДобавить значения в обработчик URL

Описание

output_add_rewrite_var(string $name, string $value): bool

Эта функция добавляет ещё одну пару имя/значение к механизму перезаписи URL. Имя и значение будут добавлены к URL (в качестве GET-параметров) и формам (как скрытые поля ввода) так же, как и идентификатор сессии, если включена прозрачная перезапись ссылок с использованием session.use_trans_sid.

Поведение этой функции контролируется параметрами php.ini url_rewriter.tags и url_rewriter.hosts.

Обратите внимание, что функция может быть успешно вызвана не более одного раза за запрос.

Замечание: Вызов этой функции неявно запустит буферизацию вывода, если она ещё не активна.

Список параметров

name

Имя параметра.

value

Значение параметра.

Возвращаемые значения

Возвращает true в случае успешного выполнения или false в случае возникновения ошибки.

Список изменений

Версия Описание
7.1.0 До PHP 7.1.0 переменные перезаписи, установленные функцией output_add_rewrite_var(), используют тот же буфер модуля сессии "trans sid". Начиная с PHP 7.1.0, используется отдельный буфер, url_rewriter.tags используется только для функций вывода, добавлен url_rewriter.hosts.

Примеры

Пример #1 Пример использования функции output_add_rewrite_var()

<?php
output_add_rewrite_var
('var', 'value');

// несколько ссылок
echo '<a href="file.php">ссылка</a>
<a href="http://example.com">ссылка2</a>'
;

// форма
echo '<form action="script.php" method="post">
<input type="text" name="var2" />
</form>'
;

print_r(ob_list_handlers());
?>

Результат выполнения данного примера:

<a href="file.php?var=value">ссылка</a>
<a href="http://example.com">ссылка2</a>

<form action="script.php" method="post">
<input type="hidden" name="var" value="value" />
<input type="text" name="var2" />
</form>

Array
(
    [0] => URL-Rewriter
)

Смотрите также



output_reset_rewrite_vars

(PHP 4 >= 4.3.0, PHP 5, PHP 7, PHP 8)

output_reset_rewrite_varsСбросить значения обработчика URL

Описание

output_reset_rewrite_vars(): bool

Эта функция сбрасывает обработчик URL и удаляет все значения, установленные функцией output_add_rewrite_var().

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Возвращает true в случае успешного выполнения или false в случае возникновения ошибки.

Список изменений

Версия Описание
7.1.0 До PHP 7.1.0, переменные перезаписи установленные функцией output_add_rewrite_var() используют тот же буфер модуля сессии "trans sid". С PHP 7.1.0, используется отдельный буфер и output_reset_rewrite_vars() только удаляет переменные перезаписи определённые output_add_rewrite_var().

Примеры

Пример #1 Пример использования функции output_reset_rewrite_vars()

<?php
session_start
();
output_add_rewrite_var('var', 'value');

echo
'<a href="file.php">ссылка</a>';
ob_flush();

output_reset_rewrite_vars();
echo
'<a href="file.php">ссылка</a>';
?>

Результат выполнения данного примера:

<a href="file.php?PHPSESSID=xxx&var=value">ссылка</a>
<a href="file.php">ссылка</a>

Смотрите также


Содержание

  • flush — Сброс системного буфера вывода
  • ob_clean — Очистить (стереть) буфер вывода
  • ob_end_clean — Очистить (стереть) буфер вывода и отключить буферизацию вывода
  • ob_end_flush — Сбросить (отправить) буфер вывод и отключить буферизацию вывода
  • ob_flush — Сбросить (отправить) буфер вывода
  • ob_get_clean — Получить содержимое текущего буфера и удалить его
  • ob_get_contents — Возвращает содержимое буфера вывода
  • ob_get_flush — Сбросить буфер вывода, вернуть его в виде строки и отключить буферизацию вывода
  • ob_get_length — Возвращает размер буфера вывода
  • ob_get_level — Возвращает уровень вложенности механизма буферизации вывода
  • ob_get_status — Получить статус буфера вывода
  • ob_gzhandler — callback-функция, используемая для gzip-сжатия буфера вывода при вызове ob_start
  • ob_implicit_flush — Включение/выключение неявного сброса
  • ob_list_handlers — Список всех используемых обработчиков вывода
  • ob_start — Включение буферизации вывода
  • output_add_rewrite_var — Добавить значения в обработчик URL
  • output_reset_rewrite_vars — Сбросить значения обработчика URL



Опции и информация PHP


Введение

Эти функции позволяют вам получить множество информации о самом PHP, например, установки конфигурации, загруженные модули, версию и многое другое. Вы так же найдёте функции для установки параметров работы PHP. Вероятно, самую известную функцию в PHP - phpinfo() - можно найти здесь.



Установка и настройка

Содержание


Требования

Для сборки этого модуля не требуются внешние библиотеки.



Установка

Для использования этих функций не требуется проведение установки, поскольку они являются частью ядра PHP.



Настройка во время выполнения

Поведение этих функций зависит от установок в php.ini.

Настройки PHP/Параметры конфигурации информации
Имя По умолчанию Место изменения Список изменений
assert.active "1" PHP_INI_ALL  
assert.bail "0" PHP_INI_ALL  
assert.warning "1" PHP_INI_ALL  
assert.callback NULL PHP_INI_ALL  
assert.quiet_eval "0" PHP_INI_ALL Удалено в PHP 8.0.0
assert.exception "1" PHP_INI_ALL До PHP 8.0.0 значение по умолчанию было "0".
enable_dl "1" PHP_INI_SYSTEM Эта возможность устарела и будет обязательно удалена в будущем.
max_execution_time "30" PHP_INI_ALL  
max_input_time "-1" PHP_INI_PERDIR  
max_input_nesting_level "64" PHP_INI_PERDIR  
max_input_vars 1000 PHP_INI_PERDIR  
zend.enable_gc "1" PHP_INI_ALL  
Для подробного описания констант PHP_INI_*, обратитесь к разделу Где могут быть установлены параметры конфигурации.

Краткое разъяснение конфигурационных директив.

assert.active bool

Включение выполнение assert(). zend.assertions следует использовать вместо этого для управления поведением функции assert().

assert.bail bool

Завершение работы скрипта при провале проверки утверждений.

assert.warning bool

Вызов предупреждений PHP для каждой проваленной проверки утверждения.

assert.callback string

Пользовательская функция, вызываемая при провале проверки утверждений.

assert.quiet_eval bool
Внимание

Данная функциональность была УДАЛЕНА, начиная с PHP 8.0.0.

Используйте эту настройку функции error_reporting() во время выполнения проверки утверждений. При включении настройки сообщения об ошибках во время проверки утверждений показываться не будут (неявный вызов error_reporting(0)). Если настройка выключена, ошибки будут выдаваться в соответствии с настройками error_reporting()

assert.exception bool

Генерирует исключение AssertionError для неудачной проверки утверждения.

enable_dl bool

Директива позволяет включать и выключать динамическую подгрузку модулей PHP с помощью функции dl().

Главной причиной, по которой требуется выключение динамической загрузки, является безопасность. С помощью динамической загрузки можно обойти все open_basedir ограничения. По умолчанию динамическая загрузка разрешена.

max_execution_time int

Эта директива задаёт максимальное время в секундах, в течение которого скрипт должен полностью загрузиться. Если этого не происходит, парсер завершает работу скрипта. Этот механизм помогает предотвратить зависание сервера из-за плохо написанного скрипта. По умолчанию на загрузку даётся 30 секунд. Если PHP запущен из командной строки, это значение по умолчанию равно 0.

В системах, отличных от Windows, на максимальное время выполнения не влияют системные вызовы, потоковые операции и т.п. За дополнительной информацией обращайтесь к документации к функции set_time_limit().

Веб-серверы обычно имеют свои настройки времени ожидания, по превышении которого сами завершают выполнение скрипта PHP. В Apache есть директива Timeout, в IIS есть функция CGI timeout. В обоих случаях по умолчанию установлено 300 секунд. Точные значения можно узнать из документации к веб-серверу.

max_input_time int

Эта директива задаёт максимальное время в секундах, в течение которого скрипт должен разобрать все входные данные, переданные запросами вроде POST или GET. Это время измеряется от момента, когда PHP вызван на сервере до момента, когда скрипт начинает выполняться. Значение по умолчанию -1, что означает, что будет использоваться max_execution_time. Если установить равным 0, то ограничений по времени не будет.

max_input_nesting_level int

Задаёт максимальную глубину вложенности входных переменных (то есть $_GET, $_POST.)

max_input_vars int

Сколько входных переменных может быть принято в одном запросе (ограничение накладывается на каждую из глобальных переменных $_GET, $_POST и $_COOKIE отдельно). Использование этой директивы снижает вероятность сбоев в случае атак с использованием хеш-коллизий. Если входных переменных больше, чем задано директивой, выбрасывается предупреждение E_WARNING, а все последующие переменные в запросе игнорируются.

zend.enable_gc bool

Включает или отключает сборщик циклических ссылок.



Типы ресурсов

Данный модуль не определяет каких-либо типов ресурсов.




Предопределённые константы

Перечисленные ниже константы всегда доступны как часть ядра PHP.

Предопределённые константы phpcredits()
Константы Значение Описание
CREDITS_GROUP 1 Список разработчиков ядра PHP
CREDITS_GENERAL 2 Главные разработчики: Дизайн и концепции языка, авторы PHP и модуля SAPI.
CREDITS_SAPI 4 Список серверных API для PHP и их авторы.
CREDITS_MODULES 8 Список модулей для PHP и их авторы.
CREDITS_DOCS 16 Члены команды разработчиков документации.
CREDITS_FULLPAGE 32 Обычно используется в сочетании с другими флагами. Означает, что HTML- страница должна печататься вместе с дополнительной информацией (за которую отвечают другие флаги).
CREDITS_QA 64 Члены команды контроля качества.
CREDITS_ALL -1 Все разработчики, аналогично использованию: CREDITS_DOCS + CREDITS_GENERAL + CREDITS_GROUP + CREDITS_MODULES + CREDITS_QA CREDITS_FULLPAGE. Будет сгенерирована HTML-страница с соответствующими тегами. Это значение по умолчанию.
Константы phpinfo()
Константы Значение Описание
INFO_GENERAL 1 Строка конфигурации, местоположение php.ini, дата сборки, веб-сервер, система и др.
INFO_CREDITS 2 Разработчики PHP. Смотрите также phpcredits().
INFO_CONFIGURATION 4 Текущие локальные и основные значения директив PHP. Смотрите также ini_get().
INFO_MODULES 8 Загруженные модули и их настройки.
INFO_ENVIRONMENT 16 Информация о переменных среды, которая также доступна в $_ENV.
INFO_VARIABLES 32 Показывает все предопределённые переменные из EGPCS (Environment, GET, POST, Cookie, Server).
INFO_LICENSE 64 Информация о лицензии PHP. Смотрите также » FAQ по лицензии.
INFO_ALL -1 Константа по умолчанию. Показывает всю информацию описанную выше.
Константы INI
Константы Значение Описание
INI_USER 1 Не используется
INI_PERDIR 2 Не используется
INI_SYSTEM 4 Не используется
INI_ALL 7 Не используется

Константы проверки утверждений. Эти значения используются для задания настроек assert_options().

assert() константы
Константы INI настройка Описание
ASSERT_ACTIVE assert.active Включение assert() проверок.
ASSERT_CALLBACK assert.callback Обратный вызов при провале проверки утверждения.
ASSERT_BAIL assert.bail Прервать выполнение при провале проверки утверждения.
ASSERT_EXCEPTION assert.exception Выдаёт предупреждение PHP для каждого неудачного утверждения.
ASSERT_WARNING assert.warning Выдавать предупреждение PHP в случае провала проверки каждого утверждения
ASSERT_QUIET_EVAL assert.quiet_eval Отключить error_reporting во время выполнения проверки утверждения. Удалено, начиная с PHP 8.0.0

Следующие константы доступны только под Windows. Они позволяют извлечь различную информацию о версиях программного обеспечения. Все константы доступны с PHP 5.3.0.

Специфичные для Windows константы
Константы Описание
PHP_WINDOWS_VERSION_MAJOR Основной номер версии Windows, это может быть 4 (NT4/Me/98/95), 5 (XP/2003 R2/2003/2000) или 6 (Vista/2008/7/8/8.1).
PHP_WINDOWS_VERSION_MINOR Уточняющий номер версии Windows, это может быть 0 (Vista/2008/2000/NT4/95), 1 (XP), 2 (2003 R2/2003/XP x64), 10 (98) или 90 (ME).
PHP_WINDOWS_VERSION_BUILD Номер сборки Windows (например, Windows Vista SP1 имеет номер сборки 6001)
PHP_WINDOWS_VERSION_PLATFORM Платформа, на которой PHP работает на данный момент. Возможны значения 2 для Windows Vista/XP/2000/NT4, Server 2008/2003, а для Windows ME/98/95 это значение будет 1.
PHP_WINDOWS_VERSION_SP_MAJOR Основной номер версии установленного сервис-пакета. Возможно значение 0, если пакетов не установлено. Например, в Windows XP с 3м сервис паком это значение будет 3.
PHP_WINDOWS_VERSION_SP_MINOR Дополнительный номер установленного пакета обновлений. Значение 0 говорит от том, что пакетов не установлено.
PHP_WINDOWS_VERSION_SUITEMASK Битовая маска указывающая, какая дополнительная функциональность установлена в системе Windows. Ниже приведена таблица с возможными значениями битового поля.
PHP_WINDOWS_VERSION_PRODUCTTYPE Содержит значение, определяющее константы вида PHP_WINDOWS_NT_*. Этим значением может быть одна из констант PHP_WINDOWS_NT_* указывающая на тип платформы.
PHP_WINDOWS_NT_DOMAIN_CONTROLLER Контроллер домена
PHP_WINDOWS_NT_SERVER Серверная система (напр. Server 2008/2003/2000). Надо учесть, что если сервер является контроллером домена, вместо этой константы будет выдаваться PHP_WINDOWS_NT_DOMAIN_CONTROLLER.
PHP_WINDOWS_NT_WORKSTATION Система рабочей станции (напр. Vista/XP/2000/NT4)

Таблица значений битовой маски PHP_WINDOWS_VERSION_SUITEMASK.

Битовое поле функциональных возможностей Windows
Биты Описание
0x00000004 Установлены компоненты Microsoft BackOffice.
0x00000400 Установлен Windows Server 2003 Web Edition.
0x00004000 Установлен Windows Server 2003 Compute Cluster Edition.
0x00000080 Установлен Windows Server 2008 Datacenter, Windows Server 2003, Datacenter Edition или Windows 2000 Datacenter Server.
0x00000002 Установлен Windows Server 2008 Enterprise, Windows Server 2003, Enterprise Edition, Windows 2000 Advanced Server или Windows NT Server 4.0 Enterprise Edition.
0x00000040 Установлен Windows XP Embedded.
0x00000200 Установлен Windows Vista Home Premium, Windows Vista Home Basic или Windows XP Home Edition.
0x00000100 Поддерживается удалённый рабочий стол, но только в интерактивном режиме. Это значение устанавливается до тех пор, пока система не будет запущена в режиме сервера приложений.
0x00000001 Microsoft Small Business Server был установлен изначально, однако мог быть проведён апгрейд системы до другой версии Windows.
0x00000020 Microsoft Small Business Server установлен с ограниченной лицензией.
0x00002000 Установлен Windows Storage Server 2003 R2 или Windows Storage Server 2003.
0x00000010 Установлены терминальные службы. Это значение всегда установлено. Если это значение установлено, значение 0x00000100 не задано, то система работает в режиме сервера приложений.
0x00008000 Установлен Windows Home Server.


Опции PHP/информационные функции


assert_options

(PHP 4, PHP 5, PHP 7, PHP 8)

assert_optionsУстановка и получение настроек механизма проверки утверждений

Описание

assert_options(int $option, mixed $value = ?): mixed

Задание значений настроек механизма проверки утверждений assert() или получение их текущих значений.

Замечание: Использование assert_options() не рекомендуется в пользу установки и получения php.ini директив zend.assertions и assert.exception с помощью ini_set() и ini_get() соответственно.

Список параметров

option

Настройки механизма проверки утверждений
Настройка INI-параметр Значение по умолчанию Описание
ASSERT_ACTIVE assert.active 1 включение механизма проверки утверждений
ASSERT_EXCEPTION assert.exception 1 выбрасывает AssertionError для каждого неудачного утверждения
ASSERT_WARNING assert.warning 1 вывод предупреждения PHP для каждой неудачной проверки
ASSERT_BAIL assert.bail 0 завершить выполнение в случае неудачной проверки
ASSERT_QUIET_EVAL assert.quiet_eval 0 отключить error_reporting во время проверки утверждения. Удалено начиная с PHP 8.0.0.
ASSERT_CALLBACK assert.callback (null) Callback-функция, которую необходимо вызвать для провалившего проверку утверждения

value

Необязательный аргумент, новое значение настройки.

У callback-функции, установленной с помощью ASSERT_CALLBACK или assert.callback, должна быть следующая сигнатура:

assert_callback(
    string $file,
    int $line,
    ?string $assertion,
    string $description = ?
): void
file
Файл, в котором была вызвана assert().
line
Строка, в которой была вызвана assert().
assertion
До PHP 8.0.0 утверждение, которое передавалось в функцию assert(), но только если утверждение задано в виде строки. (Если утверждение является булевым условием, этот параметр будет пустой строкой). Начиная с PHP 8.0.0, этот параметр всегда null.
description
Описание, которое было передано в assert().
Передача пустой строки в value сбрасывает assert callback.

Возвращаемые значения

Возвращает исходное значение настройки.

Ошибки

Функция выбрасывает ValueError, если параметр option не является допустимой опцией.

Список изменений

Версия Описание
8.0.0 Если параметр option не является допустимой опцией, теперь выбрасывается ошибка ValueError; ранее возвращалось значение false.

Примеры

Пример #1 Пример использования assert_options()

<?php
// Наша функция обработчик
// неудавшихся проверок
function function assert_failure($file, $line, $assertion, $message)
{
echo
"Проверка $assertion в $file на строке $line провалена: $message";
}

// Тестовая функция
function test_assert($parameter)
{
assert(is_bool($parameter));
}

// настройки проверки
assert_options(ASSERT_ACTIVE, true);
assert_options(ASSERT_BAIL, true);
assert_options(ASSERT_WARNING, false);
assert_options(ASSERT_CALLBACK, 'assert_failure');

// заведомо ошибочное утверждение
test_assert(1);

// Этот код не будет выполняться, пока ASSERT_BAIL
// равен true
echo 'Никогда не будет выведено';
?>

Смотрите также

  • assert() - Проверяет утверждение



assert

(PHP 4, PHP 5, PHP 7, PHP 8)

assertПроверяет утверждение

Описание

assert(mixed $assertion, Throwable|string|null $description = null): bool

assert() - это не функция, а языковая конструкция. Позволяет определять ожидания: утверждения, которые вступают в силу в средах разработки и тестирования, но оптимизированы так, что в производственной среде имеют нулевую стоимость.

Утверждения следует использовать только в качестве отладочной функции. Один из вариантов их использования - проверка на вменяемость предварительных условий, которые всегда должны быть true и если они не выполняются, это указывает на ошибки программирования. Другой случай использования - убедиться в наличии определённых возможностей, например, функций модуля или определённых ограничений и возможностей системы.

Поскольку утверждения могут быть настроены на отказ от них, их не следует использовать для обычных операций во время выполнения, таких как проверка входных параметров. Как правило, код должен вести себя так, как ожидается, даже если проверка утверждений отключена.

assert() проверяет, что ожидание, заданное в параметре assertion, выполняется. Если нет, и результат будет значение false, то будет предпринято соответствующее действие в зависимости от того, как была настроена конструкция assert().

Поведение конструкции assert() определяется следующими настройками INI:

Опции настройки конструкции assert
Имя По умолчанию Описание Список изменений
zend.assertions 1
  • 1: генерирует и выполняет код (режим разработки)
  • 0: генерирует код, но перепрыгивает через него во время выполнения
  • -1: не генерирует код (рабочий режим)
 
assert.active true Если false, assert() не проверяет ожидание и возвращает true, безоговорочно.  
assert.callback null Определяемая пользователем функция, вызываемая в случае неудачной проверки утверждения. Её сигнатура должна быть следующей:
assert_callback(
    string $file,
    int $line,
    null $assertion,
    string $description = ?
): void
До PHP 8.0.0 сигнатура callback-функции должна быть:
assert_callback(
    string $file,
    int $line,
    string $assertion,
    string $description = ?
): void
assert.exception true Если true, будет выброшена ошибка AssertionError в случае неудачной проверки утверждения.  
assert.bail false Если true, выполнение PHP-скрипта прервётся в случае неудачной проверки утверждении.  
assert.warning true Если true, будет выдана ошибка уровня E_WARNING в случае неудачной проверки утверждения. Эта INI-настройка неэффективна, если включена assert.exception.  
Опции, начинающиеся с assert., могут быть настроены с помощью функции assert_options(). Однако это не рекомендуется.

Список параметров

assertion

Любое выражение, возвращающее значение, которое будет выполнено, а результат используется для указания того, удалась или не удалась проверка утверждения.

Внимание

До версии PHP 8.0.0, если параметр assertion представлял собой строку (string), он интерпретировался как PHP-код и выполнялся с помощью функции eval(). Эта строка передавалась в callback-функцию в качестве третьего аргумента. Это поведение УСТАРЕЛО в PHP 7.2.0 и УДАЛЕНО в PHP 8.0.0.

description

Если параметр description является экземпляром класса Throwable, он будет выброшен только в том случае, если проверка утверждения assertion не удастся.

Замечание:

Начиная с PHP 8.0.0, это делается до вызова потенциально определённой callback-функции утверждения.

Замечание:

Начиная с PHP 8.0.0, объект (object) будет выброшен независимо от конфигурации параметра assert.exception.

Замечание:

Начиная с PHP 8.0.0, параметр assert.bail не имеет никакого эффекта в этом случае.

Если параметр description является строкой (string), это сообщение будет использоваться в случае выбрасывания исключения или предупреждения. Необязательное описание, которое будет включено в сообщение, если проверка утверждения assertion не удастся.

Если параметр description опущен. Во время компиляции создаётся описание по умолчанию, равное исходному коду для вызова assert().

Возвращаемые значения

Возвращает false, если проверка провалена, true в противном случае.

Список изменений

Версия Описание
8.0.0 assert() больше не будет оценивать строковые аргументы, вместо этого они будут рассматриваться как любой другой аргумент. Вместо assert($a == $b) следует использовать assert('$a == $b'). Директива assert.quiet_eval php.ini и константа ASSERT_QUIET_EVAL также были удалены, поскольку они больше не будут иметь никакого эффекта.
8.0.0 Если параметр description является экземпляром класса Throwable, объект выбрасывается в случае неудачной проверки утверждения, независимо от значения assert.exception.
8.0.0 Если параметр description является экземпляром класса Throwable, пользовательская callback-функция не вызывается, даже если она установлена.
8.0.0 Объявление функции с именем assert() внутри пространства имён больше не допускается и выдаёт ошибку уровня E_COMPILE_ERROR.
7.3.0 Объявление функции assert() внутри пространства имён устарело. Такое объявление теперь выдаёт ошибку уровня E_DEPRECATED.
7.2.0 Использование строки (string) в качестве assertion устарело. Теперь оно выдаёт ошибку уровня E_DEPRECATED, когда значение и assert.active и zend.assertions равно 1.

Примеры

Ожидания

<?php
assert
(true == false);
echo
'Привет!';
?>

Если zend.assertions установить значение 0, то приведённый выше пример выведет:

Привет!

Если zend.assertions установить значение 1, а assert.exception установить значение 0, то приведённый выше пример выведет:

Warning: assert(): assert(true == false) failed in - on line 2
Привет!

Если zend.assertions установить значение 1, а assert.exception установить значение 1, то приведённый выше пример выведет:

Fatal error: Uncaught AssertionError: assert(true == false) in -:2
Stack trace:
#0 -(2): assert(false, 'assert(true == ...')
#1 {main}
  thrown in - on line 2

Пример #1 Ожидания при использовании пользовательского исключения

<?php
class CustomError extends AssertionError {}

assert(true == false, new CustomError('True не является false!'));
echo
'Привет!';
?>

Если zend.assertions установить значение 0, то приведённый выше пример выведет:

Привет!

Если zend.assertions установить значение 1, а assert.exception установить значение 0, то приведённый выше пример выведет:

Warning: assert(): CustomError: True не является false! in -:4
Stack trace:
#0 {main} failed in - on line 4
Привет!

Если zend.assertions установить значение 1, а assert.exception установить значение 1, то приведённый выше пример выведет:

Fatal error: Uncaught CustomError: True не является false! in -:4
Stack trace:
#0 {main}
  thrown in - on line 4

Оцениваемые утверждения кода (только для PHP 7)

При использовании оцениваемых утверждений callback-функции assert() могут быть особенно полезны, поскольку код, использованный для утверждения, передаётся callback-функции вместе с информацией о том, где было выполнено утверждение.

Пример #2 Обработка неудачной проверки утверждения с помощью пользовательского обработчика

<?php
// Активируйте утверждение и отключите error_reporting
assert_options(ASSERT_ACTIVE, 1);
assert_options(ASSERT_WARNING, 0);
assert_options(ASSERT_QUIET_EVAL, 1);

// Создайте функцию-обработчик
function my_assert_handler($file, $line, $code)
{
echo
"<hr>Утверждение не выполнено:
Файл '
$file'<br />
Строка '
$line'<br />
Код '
$code'<br /><hr />";
}

// Настройте callback-функцию
assert_options(ASSERT_CALLBACK, 'my_assert_handler');

// Создайте утверждение, которое должно потерпеть неудачу
$array = [];
assert('count($array);');
?>

Результат выполнения данного примера в PHP 7.2:

Deprecated: assert(): Calling assert() with a string argument is deprecated in test.php on line 21
<hr>Утверждение не выполнено:
        Файл 'test.php'<br />
        Строка '21'<br />
        Код 'count($array);'<br /><hr />

Результат выполнения данного примера в PHP 7.1:

<hr>Утверждение не выполнено:
        Файл 'test.php'<br />
        Строка '21'<br />
        Код 'count($array);'<br /><hr />

Пример #3 Использование пользовательского обработчика для вывода описания

<?php
// Активируйте утверждение и отключите error_reporting
assert_options(ASSERT_ACTIVE, 1);
assert_options(ASSERT_WARNING, 0);
assert_options(ASSERT_QUIET_EVAL, 1);

// Создайте функцию-обработчик
function my_assert_handler($file, $line, $code, $desc = null)
{
echo
"Утверждение не выполнено в $file:$line: $code";
if (
$desc) {
echo
": $desc";
}
echo
"\n";
}

// Настройте callback-функцию
assert_options(ASSERT_CALLBACK, 'my_assert_handler');

// Создайте утверждение, которое должно потерпеть неудачу
assert('2 < 1');
assert('2 < 1', 'Два меньше, чем один');
?>

Результат выполнения данного примера в PHP 7.2:

Deprecated: assert(): Calling assert() with a string argument is deprecated in test.php on line 21
Утверждение не выполнено в test.php:21: 2 < 1

Deprecated: assert(): Calling assert() with a string argument is deprecated in test.php on line 22
Утверждение не выполнено в test.php:22: 2 < 1: Два меньше, чем один

Результат выполнения данного примера в PHP 7.1:

Утверждение не выполнено в test.php:21: 2 < 1
Утверждение не выполнено в test.php:22: 2 < 1: Два меньше, чем один

Смотрите также

  • assert_options() - Установка и получение настроек механизма проверки утверждений



cli_get_process_title

(PHP 5 >= 5.5.0, PHP 7, PHP 8)

cli_get_process_titleВозвращает заголовок текущего процесса

Описание

cli_get_process_title(): ?string

Возвращает заголовок текущего процесса, установленный cli_set_process_title(). Обратите внимание, что в зависимости от вашей операционной системы, это имя может не совпадать с тем, что покажут утилиты ps и top.

Эта функция доступна только в режиме CLI.

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Возвратит строку с заголовком процесса или null в случае возникновения ошибки.

Ошибки

Если команда не поддерживается вашей операционной системой, то будет вызвана ошибка уровня E_WARNING.

Примеры

Пример #1 Пример использования cli_get_process_title()

<?php
echo "Заголовок процесса: " . cli_get_process_title() . "\n";
?>

Смотрите также



cli_set_process_title

(PHP 5 >= 5.5.0, PHP 7, PHP 8)

cli_set_process_titleУстанавливает заголовок процесса

Описание

cli_set_process_title(string $title): bool

Устанавливает заголовок процесса, видимое утилитами top и ps. Эта функция доступна только в режиме CLI.

Список параметров

title

Новое имя.

Возвращаемые значения

Возвращает true в случае успешного выполнения или false в случае возникновения ошибки.

Ошибки

Если команда не поддерживается вашей операционной системой, то будет вызвана ошибка уровня E_WARNING.

Примеры

Пример #1 Пример использования cli_set_process_title()

<?php
$title
= "Мой потрясающий PHP-скрипт";
$pid = getmypid(); // вы можете использовать это, чтобы увидеть заголовок процесса в ps

if (!cli_set_process_title($title)) {
echo
"Не удалось установить заголовок процесса для PID $pid...\n";
exit(
1);
} else {
echo
"Заголовок процесса '$title' для PID $pid был установлен!\n";
sleep(5);
}
?>

Смотрите также

  • cli_get_process_title() - Возвращает заголовок текущего процесса
  • setproctitle()



dl

(PHP 4, PHP 5, PHP 7, PHP 8)

dlЗагружает модуль PHP во время выполнения

Описание

dl(string $extension_filename): bool

Загружает модуль PHP, заданный аргументом extension_filename.

Чтобы проверить, что заданный модуль уже загружен, используйте функцию extension_loaded(). Функция работает как для встроенных модулей, так и для динамически загруженных (т.е. загруженных как через php.ini, так и через dl()).

Внимание

Функция доступна только для CLI и встроенного SAPI, а также для CGI SAPI при запуске из командной строки.

Список параметров

extension_filename

Аргумент содержит только имя файла модуля, который требуется загрузить. Это имя зависит от платформы. Например, модуль sockets (если скомпилирован, как загружаемый модуль, а не модуль по умолчанию!) будет называться sockets.so на Unix-платформах, и php_sockets.dll в среде Windows.

Директория, из которой модуль должен быть загружен, также зависит от платформы:

Windows - Если явно не задано в php.ini, модуль будет грузиться из C:\php5\ по умолчанию.

Unix - Если явно не задано в php.ini, директория по умолчанию зависит от

  • PHP собран с настройкой --enable-debug или без неё
  • PHP собран с поддержкой ZTS (Zend Thread Safety) или нет
  • текущий внутренний номер ZEND_MODULE_API_NO (номер внутреннего модуля Zend API, который, как правило, является датой основного изменения API модуля, например 20010901)
Принимая во внимание вышесказанное, получаем следующие значения по умолчанию для директории модуля <install-dir>/lib/php/extensions/ <debug-or-not>-<zts-or-not>-ZEND_MODULE_API_NO, например, /usr/local/php/lib/php/extensions/debug-non-zts-20010901 или /usr/local/php/lib/php/extensions/no-debug-zts-20010901.

Возвращаемые значения

Возвращает true в случае успешного выполнения или false в случае возникновения ошибки. Если механизм загрузки модулей недоступен или отключён (значение off настройки enable_dl в php.ini), будет выдана ошибка E_ERROR и выполнение прекращается. Если dl() не сможет загрузить заданную библиотеку, то в дополнение к false будет выдано сообщение E_WARNING.

Примеры

Пример #1 Примеры использования dl()

<?php
// Пример загрузки модуля, основываясь на ОС
if (!extension_loaded('sqlite')) {
if (
strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
dl('php_sqlite.dll');
} else {
dl('sqlite.so');
}
}

// Или на константе PHP_SHLIB_SUFFIX
if (!extension_loaded('sqlite')) {
$prefix = (PHP_SHLIB_SUFFIX === 'dll') ? 'php_' : '';
dl($prefix . 'sqlite.' . PHP_SHLIB_SUFFIX);
}
?>

Примечания

Замечание:

dl() чувствительна к регистру на Unix-платформах.

Смотрите также



extension_loaded

(PHP 4, PHP 5, PHP 7, PHP 8)

extension_loadedОпределяет, загружен ли модуль

Описание

extension_loaded(string $extension): bool

Определяет, загружен ли указанный модуль.

Список параметров

extension

Имя модуля. Этот параметр регистронезависимый.

Чтобы посмотреть все имена модулей, воспользуйтесь функцией phpinfo(). Если вы работаете с CGI- или CLI-версией PHP, используйте параметр -m для отображения списка доступных модулей:

$ php -m
[PHP Modules]
xml
tokenizer
standard
sockets
session
posix
pcre
overload
mysql
mbstring
ctype

[Zend Modules]

Возвращаемые значения

Возвращает true, если модуль с заданным именем extension загружен или false в противном случае.

Примеры

Пример #1 Пример использования extension_loaded()

<?php
if (!extension_loaded('gd')) {
if (!
dl('gd.so')) {
exit;
}
}
?>

Смотрите также

  • get_loaded_extensions() - Возвращает массив имён всех скомпилированных и загруженных модулей
  • get_extension_funcs() - Возвращает массив имён функций модуля
  • phpinfo() - Выводит информацию о текущей конфигурации PHP
  • dl() - Загружает модуль PHP во время выполнения
  • function_exists() - Возвращает true, если указанная функция определена



gc_collect_cycles

(PHP 5 >= 5.3.0, PHP 7, PHP 8)

gc_collect_cycles Принудительный запуск сборщика мусора

Описание

gc_collect_cycles(): int

Явным образом запускает механизм поиска циклических ссылок.

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Возвращает число найденных ссылок.

Смотрите также



gc_disable

(PHP 5 >= 5.3.0, PHP 7, PHP 8)

gc_disableОтключает сборщик циклических ссылок

Описание

gc_disable(): void

Отключает сборщик циклических ссылок, путём установки значения zend.enable_gc в 0.

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Функция не возвращает значения после выполнения.

Смотрите также



gc_enable

(PHP 5 >= 5.3.0, PHP 7, PHP 8)

gc_enable Включает сборщик циклических ссылок

Описание

gc_enable(): void

Включает сборщик циклических ссылок, устанавливая zend.enable_gc в 1.

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Функция не возвращает значения после выполнения.

Смотрите также



gc_enabled

(PHP 5 >= 5.3.0, PHP 7, PHP 8)

gc_enabled Возвращает текущее состояние сборщика циклических ссылок

Описание

gc_enabled(): bool

Возвращает текущее состояние сборщика циклических ссылок.

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Возвращает true, если сборщик мусора включён или false в противном случае.

Примеры

Пример #1 Пример использования gc_enabled()

<?php
if(gc_enabled()) gc_collect_cycles();
?>

Смотрите также



gc_mem_caches

(PHP 7, PHP 8)

gc_mem_caches Освобождает память, используемую менеджером памяти Zend Engine

Описание

gc_mem_caches(): int

Освобождает память, используемую менеджером памяти Zend Engine.

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Возвращает количество освобождённых байт.

Смотрите также



gc_status

(PHP 7 >= 7.3.0, PHP 8)

gc_statusВозвращает информацию о текущем статусе сборщика мусора

Описание

gc_status(): array

Возвращает информацию о текущем статусе сборщика мусора.

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Возвращает ассоциативный массив со следующими элементами:

  • "runs"
  • "collected"
  • "threshold"
  • "roots"

Примеры

Пример #1 Использование gc_status()

<?php

// создадим дерево объектов, для которых понадобится собирать мусор
$a = new stdClass();
$a->b = [];
for (
$i = 0; $i < 100000; $i++) {
$b = new stdClass();
$b->a = $a;
$a->b[] = $b;
}
unset(
$a);
unset(
$b);
gc_collect_cycles();

var_dump(gc_status());

Результатом выполнения данного примера будет что-то подобное:

array(4) {
  ["runs"]=>
  int(5)
  ["collected"]=>
  int(100002)
  ["threshold"]=>
  int(50001)
  ["roots"]=>
  int(0)
}

Смотрите также



get_cfg_var

(PHP 4, PHP 5, PHP 7, PHP 8)

get_cfg_var Извлекает значение настройки конфигурации PHP

Описание

get_cfg_var(string $option): string|array|false

Извлекает значение настройки конфигурации PHP option.

Функция не вернёт никакой информации, заданной при сборке PHP или указанной в конфигурационном файле Apache.

Чтобы проверить, что система использует файл конфигурации, попробуйте получить значение настройки конфигурации cfg_file_path. Если эта настройка доступна, значит используется файл конфигурации.

Список параметров

option

Имя настройки конфигурации.

Возвращаемые значения

Возвращает текущее значение настройки конфигурации PHP option или false в случае возникновения ошибки.

Смотрите также

  • ini_get() - Получает значение настройки конфигурации
  • ini_get_all() - Получает все настройки конфигурации



get_current_user

(PHP 4, PHP 5, PHP 7, PHP 8)

get_current_user Получает имя владельца текущего скрипта PHP

Описание

get_current_user(): string

Возвращает имя владельца текущего PHP-скрипта.

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Возвращает имя пользователя в виде строки.

Примеры

Пример #1 Пример использования get_current_user()

<?php
echo 'Текущий владелец скрипта: ' . get_current_user();
?>

Результатом выполнения данного примера будет что-то подобное:

Текущий владелец скрипта: SYSTEM

Смотрите также

  • getmyuid() - Получение UID владельца скрипта PHP
  • getmygid() - Получить GID владельца скрипта PHP
  • getmypid() - Получение ID процесса PHP
  • getmyinode() - Получает значение inode текущего скрипта
  • getlastmod() - Получает время последней модификации страницы



get_defined_constants

(PHP 4 >= 4.1.0, PHP 5, PHP 7, PHP 8)

get_defined_constants Возвращает ассоциативный массив с именами всех констант и их значений

Описание

get_defined_constants(bool $categorize = false): array

Возвращает ассоциативный массив с именами и значениями всех определённых в настоящее время констант. Массив будет включать в себя константы, определённые модулями, а также созданные функцией define().

Список параметров

categorize

Использование этого аргумента даёт возможность получить многомерный массив, в котором в первом измерении будут содержаться категории констант, а во втором соответствующие имена и значения.

<?php
define
("MY_CONSTANT", 1);
print_r(get_defined_constants(true));
?>

Результатом выполнения данного примера будет что-то подобное:

Array
(
    [Core] => Array
        (
            [E_ERROR] => 1
            [E_WARNING] => 2
            [E_PARSE] => 4
            [E_NOTICE] => 8
            [E_CORE_ERROR] => 16
            [E_CORE_WARNING] => 32
            [E_COMPILE_ERROR] => 64
            [E_COMPILE_WARNING] => 128
            [E_USER_ERROR] => 256
            [E_USER_WARNING] => 512
            [E_USER_NOTICE] => 1024
            [E_ALL] => 2047
            [TRUE] => 1
        )

    [pcre] => Array
        (
            [PREG_PATTERN_ORDER] => 1
            [PREG_SET_ORDER] => 2
            [PREG_OFFSET_CAPTURE] => 256
            [PREG_SPLIT_NO_EMPTY] => 1
            [PREG_SPLIT_DELIM_CAPTURE] => 2
            [PREG_SPLIT_OFFSET_CAPTURE] => 4
            [PREG_GREP_INVERT] => 1
        )

    [user] => Array
        (
            [MY_CONSTANT] => 1
        )

)

Возвращаемые значения

Возвращает массив вида "имя константы" => "значение константы", с возможностью сгруппировать его по имени модуля, зарегистрировавшего константу.

Примеры

Пример #1 Пример использования get_defined_constants()

<?php
print_r
(get_defined_constants());
?>

Результатом выполнения данного примера будет что-то подобное:

Array
(
    [E_ERROR] => 1
    [E_WARNING] => 2
    [E_PARSE] => 4
    [E_NOTICE] => 8
    [E_CORE_ERROR] => 16
    [E_CORE_WARNING] => 32
    [E_COMPILE_ERROR] => 64
    [E_COMPILE_WARNING] => 128
    [E_USER_ERROR] => 256
    [E_USER_WARNING] => 512
    [E_USER_NOTICE] => 1024
    [E_ALL] => 2047
    [TRUE] => 1
)

Смотрите также

  • defined() - Проверяет существование указанной именованной константы
  • constant() - Возвращает значение константы
  • get_loaded_extensions() - Возвращает массив имён всех скомпилированных и загруженных модулей
  • get_defined_functions() - Возвращает массив всех определённых функций
  • get_defined_vars() - Возвращает массив всех определённых переменных



get_extension_funcs

(PHP 4, PHP 5, PHP 7, PHP 8)

get_extension_funcs Возвращает массив имён функций модуля

Описание

get_extension_funcs(string $extension): array|false

Функция возвращает имена всех функций, определённых в модуле с именем extension.

Список параметров

extension

Имя модуля.

Замечание:

Значение этого аргумента должно задаваться в нижнем регистре.

Возвращаемые значения

Возвращает массив имён функций или false, если extension не является допустимым модулем.

Примеры

Пример #1 Выводит функции XML

<?php
print_r
(get_extension_funcs("xml"));
?>

Результатом выполнения данного примера будет что-то подобное:

Array
(
    [0] => xml_parser_create
    [1] => xml_parser_create_ns
    [2] => xml_set_object
    [3] => xml_set_element_handler
    [4] => xml_set_character_data_handler
    [5] => xml_set_processing_instruction_handler
    [6] => xml_set_default_handler
    [7] => xml_set_unparsed_entity_decl_handler
    [8] => xml_set_notation_decl_handler
    [9] => xml_set_external_entity_ref_handler
    [10] => xml_set_start_namespace_decl_handler
    [11] => xml_set_end_namespace_decl_handler
    [12] => xml_parse
    [13] => xml_parse_into_struct
    [14] => xml_get_error_code
    [15] => xml_error_string
    [16] => xml_get_current_line_number
    [17] => xml_get_current_column_number
    [18] => xml_get_current_byte_index
    [19] => xml_parser_free
    [20] => xml_parser_set_option
    [21] => xml_parser_get_option
)

Смотрите также



get_include_path

(PHP 4 >= 4.3.0, PHP 5, PHP 7, PHP 8)

get_include_path Получение текущего значения настройки конфигурации include_path

Описание

get_include_path(): string|false

Получает значение настройки конфигурации include_path.

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Возвращает путь к файлу в виде строки или false в случае возникновения ошибки.

Примеры

Пример #1 Пример использования get_include_path()

<?php
echo get_include_path();

// или используя ini_get()
echo ini_get('include_path');
?>

Смотрите также

  • ini_get() - Получает значение настройки конфигурации
  • restore_include_path() - Восстанавливает изначальное значение настройки конфигурации include_path
  • set_include_path() - Устанавливает значение настройки конфигурации include_path
  • include - include



get_included_files

(PHP 4, PHP 5, PHP 7, PHP 8)

get_included_filesВозвращает массив имён включённых в скрипт файлов

Описание

get_included_files(): array

Получает имена всех файлов, которые были включены в скрипт с использованием include, include_once, require или require_once.

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Возвращает массив, содержащий имена всех файлов.

Скрипт, который был загружен изначально, рассматривается как "включённый файл", поэтому он также попадёт в список файлов включённых функцией include или другими.

Файлы, добавляемые в скрипт неоднократно, попадут в массив только в одном экземпляре.

Примеры

Пример #1 Пример использования get_included_files()

<?php
// Этот скрипт расположен в файле abc.php

include 'test1.php';
include_once
'test2.php';
require
'test3.php';
require_once
'test4.php';

$included_files = get_included_files();

foreach (
$included_files as $filename) {
echo
"$filename\n";
}

?>

Результат выполнения данного примера:

/path/to/abc.php
/path/to/test1.php
/path/to/test2.php
/path/to/test3.php
/path/to/test4.php

Смотрите также



get_loaded_extensions

(PHP 4, PHP 5, PHP 7, PHP 8)

get_loaded_extensions Возвращает массив имён всех скомпилированных и загруженных модулей

Описание

get_loaded_extensions(bool $zend_extensions = false): array

Функция возвращает массив имён всех скомпилированных и загруженных в интерпретаторе PHP модулей.

Список параметров

zend_extensions

Возвращать только модули Zend или обычные модули, такие как mysqli. По умолчанию false (возврат обычных модулей).

Возвращаемые значения

Возвращает индексированный массив имён всех модулей.

Примеры

Пример #1 Пример использования get_loaded_extensions()

<?php
print_r
(get_loaded_extensions());
?>

Результатом выполнения данного примера будет что-то подобное:

Array
(
    [0] => Core
    [1] => date
    [2] => libxml
    [3] => pcre
    [4] => sqlite3
    [5] => zlib
    [6] => ctype
    [7] => dom
    [8] => fileinfo
    [9] => filter
    [10] => hash
    [11] => json
    [12] => mbstring
    [13] => SPL
    [14] => PDO
    [15] => session
    [16] => posix
    [17] => Reflection
    [18] => standard
    [19] => SimpleXML
    [20] => pdo_sqlite
    [21] => Phar
    [22] => tokenizer
    [23] => xml
    [24] => xmlreader
    [25] => xmlwriter
    [26] => gmp
    [27] => iconv
    [28] => intl
    [29] => bcmath
    [30] => sodium
    [31] => Zend OPcache
)

Смотрите также

  • get_extension_funcs() - Возвращает массив имён функций модуля
  • extension_loaded() - Определяет, загружен ли модуль
  • dl() - Загружает модуль PHP во время выполнения
  • phpinfo() - Выводит информацию о текущей конфигурации PHP



get_magic_quotes_gpc

(PHP 4, PHP 5, PHP 7)

get_magic_quotes_gpc Получение текущего значения настройки конфигурации magic_quotes_gpc

Внимание

Эта функция УСТАРЕЛА, начиная с PHP 7.4.0 и была УДАЛЕНА, начиная с PHP 8.0.0. Использовать эту функцию крайне не рекомендуется.

Описание

get_magic_quotes_gpc(): false

Всегда возвращает false.

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Всегда возвращает false.

Список изменений

Версия Описание
7.4.0 Функция объявлена устаревшей.

Смотрите также

  • addslashes() - Экранирует строку с помощью слешей
  • stripslashes() - Удаляет экранирование символов
  • get_magic_quotes_runtime() - Получение текущего значения настройки конфигурации magic_quotes_runtime
  • ini_get() - Получает значение настройки конфигурации



get_magic_quotes_runtime

(PHP 4, PHP 5, PHP 7)

get_magic_quotes_runtime Получение текущего значения настройки конфигурации magic_quotes_runtime

Внимание

Эта функция УСТАРЕЛА, начиная с PHP 7.4.0 и была УДАЛЕНА, начиная с PHP 8.0.0. Использовать эту функцию крайне не рекомендуется.

Описание

get_magic_quotes_runtime(): false

Всегда возвращает false.

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Всегда возвращает false.

Список изменений

Версия Описание
7.4.0 Функция объявлена устаревшей.

Смотрите также

  • get_magic_quotes_gpc() - Получение текущего значения настройки конфигурации magic_quotes_gpc



get_required_files

(PHP 4, PHP 5, PHP 7, PHP 8)

get_required_filesПсевдоним get_included_files()

Описание

Функция является псевдонимом: get_included_files().



get_resources

(PHP 7, PHP 8)

get_resourcesВозвращает активные ресурсы

Описание

get_resources(?string $type = null): array

Возвращает массив всех текущих активных ресурсов (resource), опционально отфильтрованный по типу ресурса.

Замечание: Функция предназначена для отладки и тестирования. Функцию не следует использовать в рабочем окружении, особенно для доступа или даже управления ресурсами, которые обычно недоступны (например, базовый ресурс потока экземпляров SplFileObject).

Список параметров

type

Если задано, то get_resources() вернёт только ресурсы указанного типа. Список доступных типов ресурсов.

Если в качестве типа задана строка Unknown, то будут возвращены только ресурсы неизвестного типа.

Если не задано, то будут возвращены все ресурсы.

Возвращаемые значения

Возвращает массив текущих активных ресурсов, проиндексированных по номеру ресурса.

Список изменений

Версия Описание
8.0.0 type теперь допускает значение null.

Примеры

Пример #1 Пример использования get_resources()

<?php
$fp
= tmpfile();
var_dump(get_resources());
?>

Результатом выполнения данного примера будет что-то подобное:

array(1) {
  [1]=>
  resource(1) of type (stream)
}

Пример #2 Пример использования get_resources() с фильтрацией

<?php
$fp
= tmpfile();
var_dump(get_resources('stream'));
var_dump(get_resources('curl'));
?>

Результатом выполнения данного примера будет что-то подобное:

array(1) {
  [1]=>
  resource(1) of type (stream)
}
array(0) {
}

Смотрите также

  • get_loaded_extensions() - Возвращает массив имён всех скомпилированных и загруженных модулей
  • get_defined_constants() - Возвращает ассоциативный массив с именами всех констант и их значений
  • get_defined_functions() - Возвращает массив всех определённых функций
  • get_defined_vars() - Возвращает массив всех определённых переменных



getenv

(PHP 4, PHP 5, PHP 7, PHP 8)

getenvПолучает значение одной или всех переменных окружения

Описание

getenv(?string $name = null, bool $local_only = false): string|array|false

Получает значение одной или всех переменных окружения.

Список всех переменных окружения можно посмотреть с помощью функции phpinfo(). Многие из этих переменных есть в документе » RFC 3875, по большей части в разделе 4.1, "Request Meta-Variables".

Список параметров

name

Имя переменной в виде строки (string) или null.

local_only

Если установлено значение true, возвращаются только локальные переменные окружения, установленные операционной системой или командой putenv. Это имеет значение только в том случае, если параметр name является строкой (string).

Возвращаемые значения

Возвращает значение переменной окружения name или false, если переменная окружения name не существует. Если name равно null, возвращаются все переменные окружения в виде ассоциативного массива (array).

Список изменений

Версия Описание
8.0.0 Параметр name теперь допускает значение null.
7.1.0 Параметр name теперь может быть опущен для получения ассоциативного массива (array) всех переменных окружения.
7.0.9 Был добавлен параметр local_only.

Примеры

Пример #1 Пример использования getenv()

<?php
// Пример использования getenv()
$ip = getenv('REMOTE_ADDR');

// Можно ещё воспользоваться суперглобальной переменной ($_SERVER или $_ENV)
$ip = $_SERVER['REMOTE_ADDR'];

// Гарантированно получаем значение переменной окружения, не обращая внимания,
// была ли она переопределена SAPI или изменена с помощью putenv
$ip = getenv('REMOTE_ADDR', true) ?: getenv('REMOTE_ADDR');
?>

Примечания

Внимание

Если PHP запущен в SAPI, например как Fast CGI, эта функция будет возвращать значения переменных окружения установленных SAPI, даже если вы использовали putenv() для установки локальной переменной с таким же именем. Используйте параметр local_only для получения установленных локально переменных.

Смотрите также



getlastmod

(PHP 4, PHP 5, PHP 7, PHP 8)

getlastmod Получает время последней модификации страницы

Описание

getlastmod(): int|false

Получает время последней модификации запущенного скрипта.

Если требуется получить время модификации произвольного файла, используйте функцию filemtime().

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Возвращает время последней модификации текущей страницы. Значение является меткой времени Unix, подходящая для функции date(). Функция вернёт false в случае возникновения ошибки.

Примеры

Пример #1 Пример использования getlastmod()

<?php
// Выводит нечто вроде 'Последнее изменение: March 04 1998 20:43:59.'
echo "Последнее изменение: " . date ("F d Y H:i:s.", getlastmod());
?>

Смотрите также

  • date() - Форматирует временную метку Unix
  • getmyuid() - Получение UID владельца скрипта PHP
  • getmygid() - Получить GID владельца скрипта PHP
  • get_current_user() - Получает имя владельца текущего скрипта PHP
  • getmyinode() - Получает значение inode текущего скрипта
  • getmypid() - Получение ID процесса PHP
  • filemtime() - Возвращает время последнего изменения файла



getmygid

(PHP 4 >= 4.1.0, PHP 5, PHP 7, PHP 8)

getmygid Получить GID владельца скрипта PHP

Описание

getmygid(): int|false

Получает идентификатор группы текущего скрипта.

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Возвращает групповой идентификатор текущего скрипта или false в случае возникновения ошибки.

Смотрите также

  • getmyuid() - Получение UID владельца скрипта PHP
  • getmypid() - Получение ID процесса PHP
  • get_current_user() - Получает имя владельца текущего скрипта PHP
  • getmyinode() - Получает значение inode текущего скрипта
  • getlastmod() - Получает время последней модификации страницы



getmyinode

(PHP 4, PHP 5, PHP 7, PHP 8)

getmyinode Получает значение inode текущего скрипта

Описание

getmyinode(): int|false

Получает inode текущего скрипта.

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Возвращает inode текущего скрипта в виде целого числа или false в случае ошибки.

Смотрите также

  • getmygid() - Получить GID владельца скрипта PHP
  • getmyuid() - Получение UID владельца скрипта PHP
  • getmypid() - Получение ID процесса PHP
  • get_current_user() - Получает имя владельца текущего скрипта PHP
  • getlastmod() - Получает время последней модификации страницы



getmypid

(PHP 4, PHP 5, PHP 7, PHP 8)

getmypid Получение ID процесса PHP

Описание

getmypid(): int|false

Получает идентификатор процесса PHP.

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Возвращает идентификатор процесса PHP или false в случае возникновения ошибки.

Примечания

Внимание

Идентификаторы процессов в системе не уникальны, поэтому являются слабым источником энтропии. Мы не рекомендуем полагаться на pid в контекстах, влияющих на безопасность.

Смотрите также

  • getmygid() - Получить GID владельца скрипта PHP
  • getmyuid() - Получение UID владельца скрипта PHP
  • get_current_user() - Получает имя владельца текущего скрипта PHP
  • getmyinode() - Получает значение inode текущего скрипта
  • getlastmod() - Получает время последней модификации страницы



getmyuid

(PHP 4, PHP 5, PHP 7, PHP 8)

getmyuid Получение UID владельца скрипта PHP

Описание

getmyuid(): int|false

Получает идентификатор пользователя текущего скрипта.

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Возвращает идентификатор пользователя текущего скрипта или false в случае ошибки.

Смотрите также

  • getmygid() - Получить GID владельца скрипта PHP
  • getmypid() - Получение ID процесса PHP
  • get_current_user() - Получает имя владельца текущего скрипта PHP
  • getmyinode() - Получает значение inode текущего скрипта
  • getlastmod() - Получает время последней модификации страницы



getopt

(PHP 4 >= 4.3.0, PHP 5, PHP 7, PHP 8)

getopt Получает параметры из списка аргументов командной строки

Описание

getopt(string $short_options, array $long_options = [], int &$rest_index = null): array|false

Анализирует параметры переданные в скрипт.

Список параметров

short_options
Каждый символ в этой строке будет рассматриваться как параметр и сравниваться с символами, переданными в скрипт, перед которыми будет стоять дефис (-). Например, строка параметров "x" распознается, как параметр -x. Допускаются только символы a-z, A-Z и 0-9.
long_options
Массив параметров. Каждый элемент массива будет использоваться как строковый параметр и сравниваться с параметрами, переданными в скрипт, перед которыми будет стоять двойной дефис (--). Например, элемент longopts "opt" будет расшифровываться как --opt.
rest_index
Если задан параметр rest_index, то индекс, на котором остановился разбор, будет записан в него.

Аргумент short_options может содержать следующие элементы:

  • Отдельные символы (не имеющие значений)
  • Символы, за которыми следует двоеточие (параметр требует значения)
  • Символы, за которыми следует два двоеточия (необязательное значение)
Значения параметров идут сразу за строкой параметра (символом). Если требуется значение, то нет разницы, есть между ними пробел или нет.

Замечание: Необязательные значения нельзя отделять от других пробелом " ".

Значения массива long_options могут содержать:

  • Строка (параметр не принимает никаких значений)
  • Строка, за которой следует двоеточие (параметр требует значения)
  • Строка, за которой следует два двоеточия (необязательное значение)

Замечание:

Форматы short_options и long_options практически совпадают. Различие состоит только в том, что long_options принимает массив параметров (в котором каждый элемент является параметром) в то время, как short_options принимает строку (где параметром является каждый символ).

Возвращаемые значения

Функция вернёт массив пар параметров / аргументов или false в случае возникновения ошибки.

Замечание:

Как только встретится первый символ, не являющийся параметром, разбор строки команды будет завершён, а оставшаяся часть строки будет проигнорирована.

Список изменений

Версия Описание
7.1.0 Добавлен параметр rest_index.

Примеры

Пример #1 Пример использования getopt(): основы

<?php
// Скрипт example.php
$options = getopt("f:hp:");
var_dump($options);
?>
shell> php example.php -fvalue -h

Результат выполнения данного примера:

array(2) {
  ["f"]=>
  string(5) "value"
  ["h"]=>
  bool(false)
}

Пример #2 Пример использования getopt(): добавление длинных опций

<?php
// Скрипт example.php
$shortopts = "";
$shortopts .= "f:"; // Обязательное значение
$shortopts .= "v::"; // Необязательное значение
$shortopts .= "abc"; // Эти параметры не принимают никаких значений

$longopts = array(
"required:", // Обязательное значение
"optional::", // Необязательное значение
"option", // Нет значения
"opt", // Нет значения
);
$options = getopt($shortopts, $longopts);
var_dump($options);
?>
shell> php example.php -f "value for f" -v -a --required value --optional="optional value" --option

Результат выполнения данного примера:

array(6) {
  ["f"]=>
  string(11) "value for f"
  ["v"]=>
  bool(false)
  ["a"]=>
  bool(false)
  ["required"]=>
  string(5) "value"
  ["optional"]=>
  string(14) "optional value"
  ["option"]=>
  bool(false)
}

Пример #3 Пример использования getopt(): Передача нескольких параметров как одного

<?php
// Скрипт example.php
$options = getopt("abc");
var_dump($options);
?>
shell> php example.php -aaac

Результат выполнения данного примера:

array(2) {
  ["a"]=>
  array(3) {
    [0]=>
    bool(false)
    [1]=>
    bool(false)
    [2]=>
    bool(false)
  }
  ["c"]=>
  bool(false)
}

Пример #4 Пример getopt() с параметром rest_index

<?php
// Скрипт example.php
$rest_index = null;
$opts = getopt('a:b:', [], $rest_index);
$pos_args = array_slice($argv, $rest_index);
var_dump($pos_args);
shell> php example.php -a 1 -b 2 -- test

Результат выполнения данного примера:

array(1) {
  [0]=>
  string(4) "test"
}

Смотрите также



getrusage

(PHP 4, PHP 5, PHP 7, PHP 8)

getrusage Получает информацию об использовании текущего ресурса

Описание

getrusage(int $mode = 0): array|false

Это интерфейс к getrusage(2). Функция получает данные, возвращаемые из системного вызова.

Список параметров

mode

Если аргумент mode равен 1, getrusage будет вызвана с RUSAGE_CHILDREN.

Возвращаемые значения

Возвращает ассоциативный массив, содержащий данные возвращённые из системного вызова. Имена элементов соответствуют документированным именам полей. Возвращает false в случае возникновения ошибки.

Список изменений

Версия Описание
7.0.0 Добавлен поддержка этой функции в Windows.

Примеры

Пример #1 Пример использования getrusage()

<?php
$dat
= getrusage();
echo
$dat["ru_oublock"]; // количество операций вывода блока
echo $dat["ru_inblock"]; // количество операций приёма блока
echo $dat["ru_msgsnd"]; // количество отправленных сообщений IPC
echo $dat["ru_msgrcv"]; // количество принятых сообщений IPC
echo $dat["ru_maxrss"]; // наибольший размер установленной резидентной памяти
echo $dat["ru_ixrss"]; // суммарное значение размера разделяемой памяти
echo $dat["ru_idrss"]; // суммарное значение размера неразделяемых данных
echo $dat["ru_minflt"]; // количество исправленных страниц (лёгкая ошибка страницы)
echo $dat["ru_majflt"]; // количество ошибочных страниц (тяжёлая ошибка страницы)
echo $dat["ru_nsignals"]; // количество полученных сигналов
echo $dat["ru_nvcsw"]; // количество согласованных переключений контекста
echo $dat["ru_nivcsw"]; // количество несогласованных переключений контекста
echo $dat["ru_nswap"]; // количество свопов
echo $dat["ru_utime.tv_usec"]; // время на задачи пользователя (user time) (микросекунды)
echo $dat["ru_utime.tv_sec"]; // время на задачи пользователя (user time) (секунды)
echo $dat["ru_stime.tv_usec"]; // время на системные задачи (system time) (микросекунды)
echo $dat["ru_stime.tv_sec"]; // время на системные задачи (system time) (секунды)
?>

Примечания

Замечание:

В Windows getrusage() возвращает только следующее:

  • "ru_stime.tv_sec"
  • "ru_stime.tv_usec"
  • "ru_utime.tv_sec"
  • "ru_utime.tv_usec"
  • "ru_majflt" (только если mode - RUSAGE_SELF)
  • "ru_maxrss" (только если mode - RUSAGE_SELF)

Если getrusage() вызвана с mode равным 1 (RUSAGE_CHILDREN), то будет собираться информация по использованию ресурсов потоками (что означает, что внутри функция будет вызываться с RUSAGE_THREAD).

Замечание:

В BeOS 2000, возвращается только следующее:

  • "ru_stime.tv_sec"
  • "ru_stime.tv_usec"
  • "ru_utime.tv_sec"
  • "ru_utime.tv_usec"

Смотрите также

  • Страница системной документации getrusage(2)



ini_alter

(PHP 4, PHP 5, PHP 7, PHP 8)

ini_alterПсевдоним ini_set()

Описание

Функция является псевдонимом: ini_set().



ini_get_all

(PHP 4 >= 4.2.0, PHP 5, PHP 7, PHP 8)

ini_get_allПолучает все настройки конфигурации

Описание

ini_get_all(?string $extension = null, bool $details = true): array|false

Возвращает все зарегистрированные настройки конфигурации.

Список параметров

extension

Необязательное имя модуля. Если не null и не строка (string) core, функция возвращает только параметры.

details

Выводить детальные сведения о настройках или только текущие значения. По умолчанию true (выводить детальные сведения).

Возвращаемые значения

Возвращает ассоциативный массив с именами директив в качестве ключей. Возвращает false и вызывает ошибку уровня E_WARNING, если extension не существует.

Если details равен true (по умолчанию), в массиве будут содержаться global_value (значение настройки php.ini), local_value (например, заданное с помощью ini_set() или .htaccess) и access (уровень доступа).

Если details равен false, значением массива будет соответствующее текущее значение настройки.

Смотрите соответствующий раздел руководства, в котором приводится описание уровней доступа.

Замечание:

Директива может иметь несколько уровней доступа, в этом случае access будет содержать соответствующую битовую маску.

Примеры

Пример #1 Примеры использования ini_get_all()

<?php
print_r
(ini_get_all("pcre"));
print_r(ini_get_all());
?>

Результатом выполнения данного примера будет что-то подобное:

Array
(
    [pcre.backtrack_limit] => Array
        (
            [global_value] => 100000
            [local_value] => 100000
            [access] => 7
        )

    [pcre.recursion_limit] => Array
        (
            [global_value] => 100000
            [local_value] => 100000
            [access] => 7
        )

)
Array
(
    [allow_call_time_pass_reference] => Array
        (
            [global_value] => 0
            [local_value] => 0
            [access] => 6
        )

    [allow_url_fopen] => Array
        (
            [global_value] => 1
            [local_value] => 1
            [access] => 4
        )

    ...

)

Пример #2 Отключение details

<?php
print_r
(ini_get_all("pcre", false)); // Добавлено в PHP 5.3.0
print_r(ini_get_all(null, false)); // Добавлено в PHP 5.3.0
?>

Результатом выполнения данного примера будет что-то подобное:

Array
(
    [pcre.backtrack_limit] => 100000
    [pcre.recursion_limit] => 100000
)
Array
(
    [allow_call_time_pass_reference] => 0
    [allow_url_fopen] => 1
    ...
)

Примечания

Замечание:

ini_get_all() игнорирует опции типа "массив" такие как pdo.dsn.*.

Смотрите также



ini_get

(PHP 4, PHP 5, PHP 7, PHP 8)

ini_getПолучает значение настройки конфигурации

Описание

ini_get(string $option): string|false

В случае успешного выполнения возвращает значение настройки конфигурации.

Список параметров

option

Имя настройки конфигурации.

Возвращаемые значения

Возвращает значение настройки конфигурации в виде строки. Для значений null будет возвращаться пустая строка. Функция вернёт false, если указанная настройка не существует.

Примеры

Пример #1 Несколько примеров использования ini_get()

<?php
/*
Наш файл php.ini содержит следующие настройки:

display_errors = On
register_globals = Off
post_max_size = 8M
*/

echo 'display_errors = ' . ini_get('display_errors') . "\n";
echo
'register_globals = ' . ini_get('register_globals') . "\n";
echo
'post_max_size = ' . ini_get('post_max_size') . "\n";
echo
'post_max_size+1 = ' . (ini_get('post_max_size')+1) . "\n";
echo
'post_max_size in bytes = ' . return_bytes(ini_get('post_max_size'));

function
return_bytes($val) {
$val = trim($val);
$last = strtolower($val[strlen($val)-1]);
switch(
$last) {
// Модификатор 'G' доступен
case 'g':
$val *= 1024;
case
'm':
$val *= 1024;
case
'k':
$val *= 1024;
}

return
$val;
}

?>

Результатом выполнения данного примера будет что-то подобное:


display_errors = 1
register_globals = 0
post_max_size = 8M
post_max_size+1 = 9
post_max_size in bytes = 8388608

Примечания

Замечание: Возвращаемые логические значения

Boolean-значение ini-настройки off будет возвращено в виде пустой строки или строки "0", в то время как значению on будет соответствовать строка "1". Функция также может возвращать буквенные значения INI-настройки.

Замечание: Возвращаемые значения количества памяти

Многие ini-настройки, значения которых измеряются количеством памяти, такие как upload_max_filesize, сохраняются в php.ini в сокращённом виде. ini_get() вернёт именно то, что записано в файле php.ini, а НЕ целочисленный (int) эквивалент этой величины. Попытка использования полученной величины в арифметических операциях не даст желаемого результата. В приведённом выше примере продемонстрировано, как можно перевести сокращённую запись в число байт.

Замечание:

ini_get() не может прочесть опции типа "массив", такие как pdo.dsn.*, и возвращает false таких случаях.

Смотрите также

  • get_cfg_var() - Извлекает значение настройки конфигурации PHP
  • ini_get_all() - Получает все настройки конфигурации
  • ini_restore() - Восстанавливает значение настройки конфигурации
  • ini_set() - Устанавливает значение настройки конфигурации



ini_parse_quantity

(PHP 8 >= 8.2.0)

ini_parse_quantityGet interpreted size from ini shorthand syntax

Описание

ini_parse_quantity(string $shorthand): int

В случае успешного выполнения возвращает интерпретируемый размер в байтах из сокращений байтовых значений.

Список параметров

shorthand

Сокращение байтовых значений для разбора, должно быть числом, за которым следует необязательный множитель. Поддерживаются следующие множители: k/K (1024), m/M (1048576), g/G (1073741824). Число может быть десятичным, шестнадцатеричным (с префиксом 0x или 0X), восьмеричным (с префиксом 0o, 0O или 0) или двоичным (с префиксом 0b или 0B).

Возвращаемые значения

Возвращает интерпретируемый размер в байтах в виде целого числа (int).

Ошибки

Если значение не может быть разобрано или используется недопустимый множитель, то выдаётся ошибка уровня E_WARNING.

Примеры

Пример #1 Пример использования ini_parse_quantity()

<?php

var_dump
(ini_parse_quantity('1024'));
var_dump(ini_parse_quantity('1024M'));
var_dump(ini_parse_quantity('512K'));
var_dump(ini_parse_quantity('0xFFk'));
var_dump(ini_parse_quantity('0b1010k'));
var_dump(ini_parse_quantity('0o1024'));
var_dump(ini_parse_quantity('01024'));
var_dump(ini_parse_quantity('Foobar'));
var_dump(ini_parse_quantity('10F'));

?>

Результатом выполнения данного примера будет что-то подобное:


int(1024)
int(1073741824)
int(524288)
int(261120)
int(10240)
int(532)
int(532)

Warning: Invalid quantity "Foobar": no valid leading digits, interpreting as "0" for backwards compatibility
int(0)

Warning: Invalid quantity "10F": unknown multiplier "F", interpreting as "10" for backwards compatibility
int(10)

Смотрите также

  • ini_get() - Получает значение настройки конфигурации


ini_restore

(PHP 4, PHP 5, PHP 7, PHP 8)

ini_restore Восстанавливает значение настройки конфигурации

Описание

ini_restore(string $option): void

Восстанавливает исходное значение настройки конфигурации.

Список параметров

option

Имя настройки.

Возвращаемые значения

Функция не возвращает значения после выполнения.

Примеры

Пример #1 Пример использования ini_restore()

<?php
$setting
= 'html_errors';

echo
'Текущее значение настройки \'' . $setting . '\': ' . ini_get($setting), PHP_EOL;

ini_set($setting, ini_get($setting) ? 0 : 1);
echo
'Новое значение настройки \'' . $setting . '\': ' . ini_get($setting), PHP_EOL;

ini_restore($setting);
echo
'Исходное значение настройки \'' . $setting . '\': ' . ini_get($setting), PHP_EOL;
?>

Результат выполнения данного примера:

Текущее значение настройки 'html_errors': 1
Новое значение настройки 'html_errors': 0
Исходное значение настройки 'html_errors': 1

Смотрите также

  • ini_get() - Получает значение настройки конфигурации
  • ini_get_all() - Получает все настройки конфигурации
  • ini_set() - Устанавливает значение настройки конфигурации



ini_set

(PHP 4, PHP 5, PHP 7, PHP 8)

ini_set Устанавливает значение настройки конфигурации

Описание

ini_set(string $option, string|int|float|bool|null $value): string|false

Устанавливает значение заданной настройки конфигурации. Настройка будет хранить установленное значение пока выполняется скрипт. После завершения работы скрипта значение настройки вернётся к исходному.

Список параметров

option

Не все доступные настройки можно изменять функцией ini_set(). Список доступных настроек приведён в приложении.

value

Новое значение настройки.

Возвращаемые значения

В случае успешного выполнения возвращает старое значение или false в случае возникновения ошибки.

Список изменений

Версия Описание
8.1.0 Параметр value теперь принимает любой скалярный тип (включая null). Ранее допускались только строковые (string) значения.

Примеры

Пример #1 Установка значения ini-настройки

<?php
echo ini_get('display_errors');

if (!
ini_get('display_errors')) {
ini_set('display_errors', '1');
}

echo
ini_get('display_errors');
?>

Смотрите также



memory_get_peak_usage

(PHP 5 >= 5.2.0, PHP 7, PHP 8)

memory_get_peak_usage Возвращает пиковое значение объёма памяти, выделенное PHP

Описание

memory_get_peak_usage(bool $real_usage = false): int

Возвращает максимальный объем памяти в байтах, который был выделен PHP-скрипту.

Список параметров

real_usage

Передача true в качестве этого аргумента позволяет получить реальный объем памяти, выделенный системой. Если аргумент не задан или равен false, возвращаются сведения только о памяти, выделенной функцией emalloc().

Возвращаемые значения

Возвращает максимальный объем памяти в байтах.

Смотрите также



memory_get_usage

(PHP 4 >= 4.3.2, PHP 5, PHP 7, PHP 8)

memory_get_usageВозвращает количество памяти, выделенное для PHP

Описание

memory_get_usage(bool $real_usage = false): int

Возвращает количество памяти в байтах, которое было выделено PHP-скрипту на данный момент.

Список параметров

real_usage

Передача true позволяет узнать реальное количество памяти, выделенной PHP скрипту системой, включая неиспользуемые страницы. Если аргумент не задан или равен false, будет возвращено только количество используемой памяти.

Замечание:

PHP не отслеживает память, которая выделялась не emalloc()

Возвращаемые значения

Возвращает количество памяти в байтах.

Примеры

Пример #1 Пример использования memory_get_usage()

<?php
// Это просто пример, цифры ниже будут
// отличаться в зависимости от вашей системы

echo memory_get_usage() . "\n"; // 36640

$a = str_repeat("Hello", 4242);

echo
memory_get_usage() . "\n"; // 57960

unset($a);

echo
memory_get_usage() . "\n"; // 36744

?>

Смотрите также



memory_reset_peak_usage

(PHP 8 >= 8.2.0)

memory_reset_peak_usageСбрасывает пиковое использование памяти

Описание

memory_reset_peak_usage(): void

Сбрасывает пиковое использование памяти, возвращаемое функцией memory_get_peak_usage().

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Функция не возвращает значения после выполнения.

Примеры

Пример #1 Пример использования memory_reset_peak_usage()

<?php

var_dump
(memory_get_peak_usage());

$a = str_repeat("Hello", 424242);
var_dump(memory_get_peak_usage());

unset(
$a);
memory_reset_peak_usage();

$a = str_repeat("Hello", 2424);
var_dump(memory_get_peak_usage());

?>

Результатом выполнения данного примера будет что-то подобное:

int(422440)
int(2508672)
int(399208)

Смотрите также

  • memory_get_peak_usage() - Возвращает пиковое значение объёма памяти, выделенное PHP



php_ini_loaded_file

(PHP 5 >= 5.2.4, PHP 7, PHP 8)

php_ini_loaded_file Получить путь к загруженному файлу php.ini

Описание

php_ini_loaded_file(): string|false

Проверяет, загружен ли файл php.ini, и возвращает его путь.

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Путь к загруженному файлу php.ini или false, если файл не загружен.

Примеры

Пример #1 Пример использования php_ini_loaded_file()

<?php
$inipath
= php_ini_loaded_file();

if (
$inipath) {
echo
'Загруженный php.ini: ' . $inipath;
} else {
echo
'Файл php.ini не загружен';
}
?>

Результатом выполнения данного примера будет что-то подобное:

Loaded php.ini: /usr/local/php/php.ini

Смотрите также



php_ini_scanned_files

(PHP 4 >= 4.3.0, PHP 5, PHP 7, PHP 8)

php_ini_scanned_files Возвращает список .ini-файлов, найденных в дополнительной ini-директории

Описание

php_ini_scanned_files(): string|false

php_ini_scanned_files() возвращает список разделённых запятыми конфигурационных файлов, проанализированных после php.ini. Директории, в которых производится поиск, задаются при компиляции и, опционально, переменной окружения во время исполнения. Больше информации можно найти в инструкции по установке.

Возвращаемые имена файлов включают полный путь.

Список параметров

У этой функции нет параметров.

Возвращаемые значения

При успехе возвращает строку с разделёнными запятыми именами .ini-файлов. За каждой запятой следует новая строка. Если директива --with-config-file-scan-dir не задана и переменная окружения PHP_INI_SCAN_DIR тоже не задана, функция вернёт false. Если директива задана и она пуста, будет возвращена пустая строка. Если файл не удаётся распознать, он всё же будет включён в список, но при этом PHP сообщит об ошибке. Эта ошибка будет возникать как при компиляции, так и во время работы php_ini_scanned_files().

Примеры

Пример #1 Простой пример вывода списка ini-файлов

<?php
if ($filelist = php_ini_scanned_files()) {
if (
strlen($filelist) > 0) {
$files = explode(',', $filelist);

foreach (
$files as $file) {
echo
"<li>" . trim($file) . "</li>\n";
}
}
}
?>

Смотрите также

  • ini_set() - Устанавливает значение настройки конфигурации
  • phpinfo() - Выводит информацию о текущей конфигурации PHP
  • php_ini_loaded_file() - Получить путь к загруженному файлу php.ini



php_sapi_name

(PHP 4 >= 4.0.1, PHP 5, PHP 7, PHP 8)

php_sapi_name Возвращает тип интерфейса между веб-сервером и PHP

Описание

php_sapi_name(): string|false

Возвращает строку в нижнем регистре, содержащую описание типа интерфейса (Server API, SAPI), который использует PHP. Например, в CLI PHP эта строка будет "cli", в то время как с Apache может быть несколько разных значений в зависимости от конкретного SAPI. Возможные значение приведены ниже.

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Возвращает тип интерфейса в виде строки в нижнем регистре или false в случае возникновения ошибки.

Возможные возвращаемые значения (список может быть неполным): apache, apache2handler, cgi (до PHP 5.3), cgi-fcgi, cli, cli-server, embed, fpm-fcgi, litespeed, phpdbg.

Примеры

Пример #1 Пример использования php_sapi_name()

В этом примере проверяется подстрока cgi, так как это также может быть cgi-fcgi.

<?php
$sapi_type
= php_sapi_name();
if (
substr($sapi_type, 0, 3) == 'cgi') {
echo
"Вы используете CGI PHP\n";
} else {
echo
"Вы используете не CGI PHP\n";
}
?>

Примечания

Замечание: Альтернативный вариант

Константа PHP PHP_SAPI хранит то же значение, что и php_sapi_name().

Подсказка

Важный аспект

Имя SAPI может определиться неточно, так как, например, в случае с apache интерфейс может быть определён как apache2handler.

Смотрите также



php_uname

(PHP 4 >= 4.0.2, PHP 5, PHP 7, PHP 8)

php_uname Возвращает информацию об операционной системе, на которой запущен PHP

Описание

php_uname(string $mode = "a"): string

php_uname() возвращает описание операционной системы, на которой запущен PHP. Это та же строка, с которой начинается вывод phpinfo(). Для вывода названия операционной системы также можно использовать константу PHP_OS, но имейте в виду, что эта константа содержит название операционной системы, на которой PHP был собран (built).

На некоторых старых UNIX-платформах получить информацию о текущей ОС может оказаться невозможным. В таких случаях функция выдаст название ОС, на которой PHP был собран. Такое случается, когда библиотека, которой пользуется uname(), недоступна или работает некорректно.

Список параметров

mode

mode - одиночный символ, определяющий, какая информация будет выводиться:

  • 'a': По умолчанию. Содержит все режимы в следующей последовательности "s n r v m".
  • 's': Название операционной системы, например, FreeBSD.
  • 'n': Имя хоста, например, localhost.example.com.
  • 'r': Номер релиза, например, 5.1.2-RELEASE.
  • 'v': Информация о версии. Может сильно различаться в разных ОС.
  • 'm': Архитектура процессора, например, i386.

Возвращаемые значения

Возвращает описание ОС в виде строки.

Примеры

Пример #1 Несколько примеров использования php_uname()

<?php
echo php_uname();
echo
PHP_OS;

/* Разные варианты:
Linux localhost 2.4.21-0.13mdk #1 Fri Mar 14 15:08:06 EST 2003 i686
Linux

FreeBSD localhost 3.2-RELEASE #15: Mon Dec 17 08:46:02 GMT 2001
FreeBSD

Windows NT XN1 5.1 build 2600
WINNT
*/

if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
echo
'Сервер работает под управлением Windows!';
} else {
echo
'Сервер работает под управлением ОС, отличной от Windows!';
}

?>

Ниже приведено несколько Предопределённых PHP-констант, которые могут оказаться полезными:

Пример #2 Некоторые константы OS

<?php
// *nix
echo DIRECTORY_SEPARATOR; // /
echo PHP_SHLIB_SUFFIX; // so
echo PATH_SEPARATOR; // :

// Win*
echo DIRECTORY_SEPARATOR; // \
echo PHP_SHLIB_SUFFIX; // dll
echo PATH_SEPARATOR; // ;
?>

Смотрите также

  • phpversion() - Получает текущую версию PHP
  • php_sapi_name() - Возвращает тип интерфейса между веб-сервером и PHP
  • phpinfo() - Выводит информацию о текущей конфигурации PHP



phpcredits

(PHP 4, PHP 5, PHP 7, PHP 8)

phpcredits Выводит список разработчиков PHP

Описание

phpcredits(int $flags = CREDITS_ALL): true

Эта функция выводит список разработчиков PHP, модулей и т.д. Она генерирует соответствующий HTML-код для вставки на страницу.

Список параметров

flags

Использование аргумента flags позволяет произвольно компоновать информацию об отдельных группах разработчиков.

Предопределённые флаги phpcredits()
Имя Описание
CREDITS_ALL Все разработчики, эквивалентно использованию: CREDITS_DOCS + CREDITS_GENERAL + CREDITS_GROUP + CREDITS_MODULES + CREDITS_FULLPAGE. В этом случае будет сгенерирована полностью независимая HTML-страница с соответствующими тэгами.
CREDITS_DOCS Участники команды документирования
CREDITS_FULLPAGE Обычно используется в комбинации с другими флагами. Указывает на то, что независимая HTML страница должна содержать информацию других флагов.
CREDITS_GENERAL Главные разработчики: Концепция и дизайн языка, авторы PHP и модуля SAPI.
CREDITS_GROUP Список разработчиков ядра языка
CREDITS_MODULES Список модулей для PHP и их авторов
CREDITS_SAPI Список модулей серверных API и их авторов

Возвращаемые значения

Функция всегда возвращает true.

Примеры

Пример #1 Выводит основных разработчиков

<?php
phpcredits
(CREDITS_GENERAL);
?>

Пример #2 Выводит разработчиков ядра и участников команды документирования

<?php
phpcredits
(CREDITS_GROUP | CREDITS_DOCS | CREDITS_FULLPAGE);
?>

Пример #3 Вывод всех разработчиков

<html>
<head>
<title>Сведения об авторах</title>
</head>
<body>
<?php
// какой-то код
phpcredits(CREDITS_ALL - CREDITS_FULLPAGE);
// ещё код
?>
</body>
</html>

Примечания

Замечание:

В режиме работы из командной строки (CLI) phpcredits() выводит обычный текст вместо HTML.

Смотрите также

  • phpversion() - Получает текущую версию PHP
  • phpinfo() - Выводит информацию о текущей конфигурации PHP



phpinfo

(PHP 4, PHP 5, PHP 7, PHP 8)

phpinfo Выводит информацию о текущей конфигурации PHP

Описание

phpinfo(int $flags = INFO_ALL): true

Выводит большое количество информации о текущем состоянии PHP. Сюда входит информация о настройках компиляции PHP, о модулях, о версии, информация о сервере и среде выполнения (если PHP компилировался как модуль), окружении PHP, версии ОС, о путях, об основных и локальных значениях настроек конфигурации, о HTTP-заголовках и лицензии PHP.

Так как каждая система имеет свои особенности, phpinfo() используется в основном для проверки настроек конфигурации и для просмотра доступных предопределённых констант в данной системе.

phpinfo() также используется в целях отладки, так как содержит все данные EGPCS (Environment, GET, POST, Cookie, Server).

Список параметров

flags

Вывод функции можно настраивать, передавая битовую маску из одной или более приведённых ниже констант (constants). Эта маска передаётся в качестве необязательного аргумента flags. Отдельные константы или битовые значения можно комбинировать с помощью побитового оператора ИЛИ.

Настройки phpinfo()
Имя (константа) Значение Описание
INFO_GENERAL 1 Строка конфигурации, расположение php.ini, дата сборки, сервер, система и др.
INFO_CREDITS 2 Разработчики PHP. Смотрите также phpcredits().
INFO_CONFIGURATION 4 Текущие значение основных и локальных PHP директив. Смотрите также ini_get().
INFO_MODULES 8 Загруженные модули и их настройки. Смотрите также get_loaded_extensions().
INFO_ENVIRONMENT 16 Информация о переменных окружения, которая также доступна в $_ENV.
INFO_VARIABLES 32 Выводит все предопределённые переменные из EGPCS (Environment, GET, POST, Cookie, Server).
INFO_LICENSE 64 Информация о лицензии PHP. Смотрите также » license FAQ.
INFO_ALL -1 Выводит все приведённое выше.

Возвращаемые значения

Функция всегда возвращает true.

Примеры

Пример #1 Пример использования phpinfo()

<?php

// Показывать всю информацию, по умолчанию INFO_ALL
phpinfo();

// Показывать информацию только о загруженных модулях.
// phpinfo(8) выдаёт тот же результат.
phpinfo(INFO_MODULES);

?>

Примечания

Замечание:

В версиях PHP до 5.5, часть информации не выводится, если настройка expose_php установлена в off. Это PHP и Zend логотипы и информация о разработчиках.

Замечание:

В режиме CLI phpinfo() выводит обычный текст вместо HTML.

Смотрите также



phpversion

(PHP 4, PHP 5, PHP 7, PHP 8)

phpversionПолучает текущую версию PHP

Описание

phpversion(?string $extension = null): string|false

Возвращает строку с номером версии текущего PHP-интерпретатора или модуля.

Список параметров

extension

Необязательное имя модуля.

Возвращаемые значения

Возвращает текущую версию PHP в виде строки (string). Если в параметре extension указано строковое значение (string), phpversion() вернёт версию этого модуля или false, если информации о версии нет или модуль в данный момент не включён.

Список изменений

Версия Описание
8.0.0 extension теперь допускает значение null.

Примеры

Пример #1 Пример использования phpversion()

<?php
// Выводит строку типа 'Текущая версия PHP: 4.1.1'
echo 'Текущая версия PHP: ' . phpversion();

// Выводит строку типа '2.0' или ничего, если модуль не включён
echo phpversion('tidy');
?>

Пример #2 Пример использования PHP_VERSION_ID

<?php
// PHP_VERSION_ID доступна в версиях PHP 5.2.7 и выше. Если
// наша версия ниже, можно её сэмулировать
if (!defined('PHP_VERSION_ID')) {
$version = explode('.', PHP_VERSION);

define('PHP_VERSION_ID', ($version[0] * 10000 + $version[1] * 100 + $version[2]));
}

// PHP_VERSION_ID определена как число. Чем больше число, тем новее
// PHP. Эта константа задаётся по той же схеме, что приведена выше:
//
// $version_id = $major_version * 10000 + $minor_version * 100 + $release_version;
//
// Теперь с PHP_VERSION_ID можно проверять, какая функциональность есть в
// текущей версии PHP. Не обязательно пользоваться version_compare()
// каждый раз, когда требуется проверить, поддерживает ли PHP нужную
// нам функцию.
//
// Например, мы можем задать значения констант PHP_VERSION_*,
// которые недоступны в версиях ранее 5.2.7

if (PHP_VERSION_ID < 50207) {
define('PHP_MAJOR_VERSION', $version[0]);
define('PHP_MINOR_VERSION', $version[1]);
define('PHP_RELEASE_VERSION', $version[2]);

// и так далее ...
}
?>

Примечания

Замечание:

Эта информация также доступна через предопределённую константу PHP_VERSION. Более детальную информацию можно получить с помощью констант PHP_VERSION_*.

Замечание:

Некоторые модули могут определять свой собственный номер версии. Однако большинство модулей, входящих в комплект поставки, в качестве номера версии используют версию PHP.

Смотрите также



putenv

(PHP 4, PHP 5, PHP 7, PHP 8)

putenvУстанавливает значение переменной среды

Описание

putenv(string $assignment): bool

Добавляет assignment в переменные окружения сервера. Переменная будет существовать только на время выполнения текущего запроса. По его завершении переменная вернётся в изначальное состояние.

Список параметров

assignment

Установка вида "FOO=BAR"

Возвращаемые значения

Возвращает true в случае успешного выполнения или false в случае возникновения ошибки.

Примеры

Пример #1 Установка значения переменной среды

<?php
putenv
("UNIQID=$uniqid");
?>

Смотрите также

  • getenv() - Получает значение одной или всех переменных окружения
  • apache_setenv() - Устанавливает переменную subprocess_env Apache



restore_include_path

(PHP 4 >= 4.3.0, PHP 5, PHP 7)

restore_include_path Восстанавливает изначальное значение настройки конфигурации include_path

Внимание

Эта функция УСТАРЕЛА, начиная с PHP 7.4.0 и была УДАЛЕНА, начиная с PHP 8.0.0. Использовать эту функцию крайне не рекомендуется.

Описание

restore_include_path(): void

Восстанавливает исходное значение настройки конфигурации include_path, которое записано в php.ini

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Функция не возвращает значения после выполнения.

Примеры

Пример #1 Пример использования restore_include_path()

<?php

echo get_include_path(); // .:/usr/local/lib/php

set_include_path('/inc');

echo
get_include_path(); // /inc

restore_include_path();

// или так
ini_restore('include_path');

echo
get_include_path(); // .:/usr/local/lib/php

?>

Смотрите также

  • ini_restore() - Восстанавливает значение настройки конфигурации
  • get_include_path() - Получение текущего значения настройки конфигурации include_path
  • set_include_path() - Устанавливает значение настройки конфигурации include_path
  • include - include



set_include_path

(PHP 4 >= 4.3.0, PHP 5, PHP 7, PHP 8)

set_include_path Устанавливает значение настройки конфигурации include_path

Описание

set_include_path(string $include_path): string|false

Задаёт значение настройки конфигурации include_path на время выполнения скрипта.

Список параметров

include_path

Новое значение настройки include_path

Возвращаемые значения

Возвращает старое значение include_path в случае успешного выполнения или false в случае возникновения ошибки.

Примеры

Пример #1 Пример использования set_include_path()

<?php
set_include_path
('/usr/lib/pear');

// Или так
ini_set('include_path', '/usr/lib/pear');
?>

Пример #2 Составление более длинного пути include path

Используя константу PATH_SEPARATOR, можно добавить к пути вложенные директории независимо от операционной системы.

В этом примере мы добавим /usr/lib/pear в конец существующего пути include_path.

<?php
$path
= '/usr/lib/pear';
set_include_path(get_include_path() . PATH_SEPARATOR . $path);
?>

Смотрите также

  • ini_set() - Устанавливает значение настройки конфигурации
  • get_include_path() - Получение текущего значения настройки конфигурации include_path
  • restore_include_path() - Восстанавливает изначальное значение настройки конфигурации include_path
  • include - include



set_time_limit

(PHP 4, PHP 5, PHP 7, PHP 8)

set_time_limitОграничение времени выполнения скрипта

Описание

set_time_limit(int $seconds): bool

Задаёт время в секундах, в течение которого скрипт должен завершить работу. Если скрипт не успевает, вызывается фатальная ошибка. По умолчанию даётся 30 секунд, либо время, записанное в настройке max_execution_time в php.ini (если такая настройка установлена).

При вызове set_time_limit() перезапускает счётчик с нуля. Другими словами, если время ожидания изначально было 30 секунд, и через 25 секунд после запуска скрипта будет вызвана функция set_time_limit(20), то скрипт будет работать максимум 45 секунд.

Список параметров

seconds

Максимальное время выполнения в секундах. Если задан ноль, время выполнения неограниченно.

Возвращаемые значения

Возвращает true в случае успешного выполнения, иначе false.

Примечания

Замечание:

Функция set_time_limit() и директива max_execution_time влияют на время выполнения только самого скрипта. Время, затраченное на различные действия вне скрипта, такие как системные вызовы функции system(), потоковые операции, запросы к базам данных и т.п. не включаются в расчёт времени выполнения скрипта. Это не относится к системам Windows, где рассчитывается абсолютное время выполнения.

Смотрите также



sys_get_temp_dir

(PHP 5 >= 5.2.1, PHP 7, PHP 8)

sys_get_temp_dir Возвращает путь к директории временных файлов

Описание

sys_get_temp_dir(): string

Возвращает путь к директории, где PHP по умолчанию хранит временные файлы.

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Возвращает путь к директории временных файлов.

Примеры

Пример #1 Пример использования sys_get_temp_dir()

<?php
// Создание временного файла в директории
// временных файлов, используя sys_get_temp_dir()
$temp_file = tempnam(sys_get_temp_dir(), 'Tux');

echo
$temp_file;
?>

Результатом выполнения данного примера будет что-то подобное:

C:\Windows\Temp\TuxA318.tmp

Смотрите также

  • tmpfile() - Создаёт временный файл
  • tempnam() - Создаёт файл с уникальным именем



version_compare

(PHP 4 >= 4.1.0, PHP 5, PHP 7, PHP 8)

version_compare Сравнивает две "стандартизованные" строки с номером версии PHP

Описание

version_compare(string $version1, string $version2, ?string $operator = null): int|bool

version_compare() сравнивает две "PHP-стандартизованные" строки с номерами версий.

Функция сначала заменяет _, - и + на точку . в строках версий, а также добавляет точки . перед и после каждого символа, не являющегося числом. Например, '4.3.2RC1' преобразуется в '4.3.2.RC.1'. После этого сравнивает части строк слева направо. Если часть строки содержит специальные символы версий, они обрабатываются следующим образом: любая строка, не найденная в этом списке < dev < alpha = a < beta = b < RC = rc < # < pl = p. Таким образом можно сравнивать не только версии разных уровней, вроде '4.1' и '4.1.2', но и специфичные версии, включающие статус разработки.

Список параметров

version1

Номер первой версии.

version2

Номер второй версии.

operator

Необязательный параметр operator. Возможные значения: <, lt, <=, le, >, gt, >=, ge, ==, =, eq, !=, <>, ne.

Аргумент чувствителен к регистру, поэтому значения должны быть в нижнем регистре.

Возвращаемые значения

По умолчанию функция version_compare() возвращает -1, если первая версия меньше второй; 0, когда они равны; 1, если вторая меньше первой.

При использовании аргумента operator функция вернёт true, если выражение в соответствии с оператором верно, и false в противном случае.

Примеры

В примере ниже используется константа PHP_VERSION, она содержит номер версии PHP, который выполняет код.

Пример #1 Пример использования version_compare()

<?php
if (version_compare(PHP_VERSION, '7.0.0') >= 0) {
echo
'Я использую PHP версии не ниже 7.0.0, моя версия: ' . PHP_VERSION . "\n";
}

if (
version_compare(PHP_VERSION, '5.3.0') >= 0) {
echo
'Я использую PHP версии не ниже 5.3.0, моя версия: ' . PHP_VERSION . "\n";
}

if (
version_compare(PHP_VERSION, '5.0.0', '>=')) {
echo
'Я использую PHP 5.0.0 или выше, моя версия: ' . PHP_VERSION . "\n";
}

if (
version_compare(PHP_VERSION, '5.0.0', '<')) {
echo
'Я до сих пор использую PHP 4, моя версия: ' . PHP_VERSION . "\n";
}
?>

Примечания

Замечание:

Константа PHP_VERSION хранит номер текущей версии PHP.

Замечание:

Заметьте, что дорелизные версии, такие как 5.3.0-dev, считаются меньше, чем финальные (вида 5.3.0).

Замечание:

Специальные слова вроде alpha и beta чувствительны к регистру. Строки версий, не придерживающиеся PHP-стандарта, нужно приводить к нижнему регистру функцией strtolower() до вызова version_compare().

Смотрите также

  • phpversion() - Получает текущую версию PHP
  • php_uname() - Возвращает информацию об операционной системе, на которой запущен PHP
  • function_exists() - Возвращает true, если указанная функция определена



zend_thread_id

(PHP 5, PHP 7, PHP 8)

zend_thread_id Возвращает уникальный идентификатор текущего потока выполнения

Описание

zend_thread_id(): int

Эта функция возвращает уникальный идентификатор текущего потока выполнения.

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Возвращает идентификатор потока выполнения в виде целого числа.

Примеры

Пример #1 Пример использования zend_thread_id()

<?php
$thread_id
= zend_thread_id();

echo
'Идентификатор текущего потока выполнения: ' . $thread_id;
?>

Результатом выполнения данного примера будет что-то подобное:

Идентификатор текущего потока выполнения: 7864

Примечания

Замечание:

Эта функция доступна, только если PHP собран с поддержкой ZTS (Zend Thread Safety) и работает в режиме отладки (--enable-debug).



zend_version

(PHP 4, PHP 5, PHP 7, PHP 8)

zend_version Получает версию движка Zend

Описание

zend_version(): string

Возвращает строку с номером версии работающего в данный момент ядра Zend Engine.

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Возвращает номер версии Zend Engine в виде строки.

Примеры

Пример #1 Пример использования zend_version()

<?php
echo "Версия движка Zend: " . zend_version();
?>

Результатом выполнения данного примера будет что-то подобное:

Версия движка Zend: 2.2.0

Смотрите также

  • phpinfo() - Выводит информацию о текущей конфигурации PHP
  • phpcredits() - Выводит список разработчиков PHP
  • phpversion() - Получает текущую версию PHP


Содержание

  • assert_options — Установка и получение настроек механизма проверки утверждений
  • assert — Проверяет утверждение
  • cli_get_process_title — Возвращает заголовок текущего процесса
  • cli_set_process_title — Устанавливает заголовок процесса
  • dl — Загружает модуль PHP во время выполнения
  • extension_loaded — Определяет, загружен ли модуль
  • gc_collect_cycles — Принудительный запуск сборщика мусора
  • gc_disable — Отключает сборщик циклических ссылок
  • gc_enable — Включает сборщик циклических ссылок
  • gc_enabled — Возвращает текущее состояние сборщика циклических ссылок
  • gc_mem_caches — Освобождает память, используемую менеджером памяти Zend Engine
  • gc_status — Возвращает информацию о текущем статусе сборщика мусора
  • get_cfg_var — Извлекает значение настройки конфигурации PHP
  • get_current_user — Получает имя владельца текущего скрипта PHP
  • get_defined_constants — Возвращает ассоциативный массив с именами всех констант и их значений
  • get_extension_funcs — Возвращает массив имён функций модуля
  • get_include_path — Получение текущего значения настройки конфигурации include_path
  • get_included_files — Возвращает массив имён включённых в скрипт файлов
  • get_loaded_extensions — Возвращает массив имён всех скомпилированных и загруженных модулей
  • get_magic_quotes_gpc — Получение текущего значения настройки конфигурации magic_quotes_gpc
  • get_magic_quotes_runtime — Получение текущего значения настройки конфигурации magic_quotes_runtime
  • get_required_files — Псевдоним get_included_files
  • get_resources — Возвращает активные ресурсы
  • getenv — Получает значение одной или всех переменных окружения
  • getlastmod — Получает время последней модификации страницы
  • getmygid — Получить GID владельца скрипта PHP
  • getmyinode — Получает значение inode текущего скрипта
  • getmypid — Получение ID процесса PHP
  • getmyuid — Получение UID владельца скрипта PHP
  • getopt — Получает параметры из списка аргументов командной строки
  • getrusage — Получает информацию об использовании текущего ресурса
  • ini_alter — Псевдоним ini_set
  • ini_get_all — Получает все настройки конфигурации
  • ini_get — Получает значение настройки конфигурации
  • ini_parse_quantity — Get interpreted size from ini shorthand syntax
  • ini_restore — Восстанавливает значение настройки конфигурации
  • ini_set — Устанавливает значение настройки конфигурации
  • memory_get_peak_usage — Возвращает пиковое значение объёма памяти, выделенное PHP
  • memory_get_usage — Возвращает количество памяти, выделенное для PHP
  • memory_reset_peak_usage — Сбрасывает пиковое использование памяти
  • php_ini_loaded_file — Получить путь к загруженному файлу php.ini
  • php_ini_scanned_files — Возвращает список .ini-файлов, найденных в дополнительной ini-директории
  • php_sapi_name — Возвращает тип интерфейса между веб-сервером и PHP
  • php_uname — Возвращает информацию об операционной системе, на которой запущен PHP
  • phpcredits — Выводит список разработчиков PHP
  • phpinfo — Выводит информацию о текущей конфигурации PHP
  • phpversion — Получает текущую версию PHP
  • putenv — Устанавливает значение переменной среды
  • restore_include_path — Восстанавливает изначальное значение настройки конфигурации include_path
  • set_include_path — Устанавливает значение настройки конфигурации include_path
  • set_time_limit — Ограничение времени выполнения скрипта
  • sys_get_temp_dir — Возвращает путь к директории временных файлов
  • version_compare — Сравнивает две "стандартизованные" строки с номером версии PHP
  • zend_thread_id — Возвращает уникальный идентификатор текущего потока выполнения
  • zend_version — Получает версию движка Zend

  • Введение
  • Установка и настройка
  • Предопределённые константы
  • Опции PHP/информационные функции
    • assert_options — Установка и получение настроек механизма проверки утверждений
    • assert — Проверяет утверждение
    • cli_get_process_title — Возвращает заголовок текущего процесса
    • cli_set_process_title — Устанавливает заголовок процесса
    • dl — Загружает модуль PHP во время выполнения
    • extension_loaded — Определяет, загружен ли модуль
    • gc_collect_cycles — Принудительный запуск сборщика мусора
    • gc_disable — Отключает сборщик циклических ссылок
    • gc_enable — Включает сборщик циклических ссылок
    • gc_enabled — Возвращает текущее состояние сборщика циклических ссылок
    • gc_mem_caches — Освобождает память, используемую менеджером памяти Zend Engine
    • gc_status — Возвращает информацию о текущем статусе сборщика мусора
    • get_cfg_var — Извлекает значение настройки конфигурации PHP
    • get_current_user — Получает имя владельца текущего скрипта PHP
    • get_defined_constants — Возвращает ассоциативный массив с именами всех констант и их значений
    • get_extension_funcs — Возвращает массив имён функций модуля
    • get_include_path — Получение текущего значения настройки конфигурации include_path
    • get_included_files — Возвращает массив имён включённых в скрипт файлов
    • get_loaded_extensions — Возвращает массив имён всех скомпилированных и загруженных модулей
    • get_magic_quotes_gpc — Получение текущего значения настройки конфигурации magic_quotes_gpc
    • get_magic_quotes_runtime — Получение текущего значения настройки конфигурации magic_quotes_runtime
    • get_required_files — Псевдоним get_included_files
    • get_resources — Возвращает активные ресурсы
    • getenv — Получает значение одной или всех переменных окружения
    • getlastmod — Получает время последней модификации страницы
    • getmygid — Получить GID владельца скрипта PHP
    • getmyinode — Получает значение inode текущего скрипта
    • getmypid — Получение ID процесса PHP
    • getmyuid — Получение UID владельца скрипта PHP
    • getopt — Получает параметры из списка аргументов командной строки
    • getrusage — Получает информацию об использовании текущего ресурса
    • ini_alter — Псевдоним ini_set
    • ini_get_all — Получает все настройки конфигурации
    • ini_get — Получает значение настройки конфигурации
    • ini_parse_quantity — Get interpreted size from ini shorthand syntax
    • ini_restore — Восстанавливает значение настройки конфигурации
    • ini_set — Устанавливает значение настройки конфигурации
    • memory_get_peak_usage — Возвращает пиковое значение объёма памяти, выделенное PHP
    • memory_get_usage — Возвращает количество памяти, выделенное для PHP
    • memory_reset_peak_usage — Сбрасывает пиковое использование памяти
    • php_ini_loaded_file — Получить путь к загруженному файлу php.ini
    • php_ini_scanned_files — Возвращает список .ini-файлов, найденных в дополнительной ini-директории
    • php_sapi_name — Возвращает тип интерфейса между веб-сервером и PHP
    • php_uname — Возвращает информацию об операционной системе, на которой запущен PHP
    • phpcredits — Выводит список разработчиков PHP
    • phpinfo — Выводит информацию о текущей конфигурации PHP
    • phpversion — Получает текущую версию PHP
    • putenv — Устанавливает значение переменной среды
    • restore_include_path — Восстанавливает изначальное значение настройки конфигурации include_path
    • set_include_path — Устанавливает значение настройки конфигурации include_path
    • set_time_limit — Ограничение времени выполнения скрипта
    • sys_get_temp_dir — Возвращает путь к директории временных файлов
    • version_compare — Сравнивает две "стандартизованные" строки с номером версии PHP
    • zend_thread_id — Возвращает уникальный идентификатор текущего потока выполнения
    • zend_version — Получает версию движка Zend


Интерактивный отладчик PHP


Введение

Поскольку phpdbg реализован в виде модуля SAPI, то он может полностью контролировать окружение без воздействия на функциональность и скорость выполнения вашего кода.

Phpdbg претендует на то, чтобы считаться легковесным, мощным и простым в использовании отладчиком для PHP. Он предоставляет следующие возможности:

  • Пошаговая отладка
  • Гибкие точки прерывания (метод класса, функция, строка файла, адрес, опкод)
  • Лёгкий доступ к PHP с помощью встроенной функции eval()
  • Пользовательское API
  • Независимость от SAPI - легко интегрируется
  • Поддержка конфигурационных файлов PHP
  • Определение собственных суперглобальных переменных JIT
  • Опциональная поддержка ввода с клавиатуры - удобная работа через терминал
  • Лёгок в использовании - читайте документацию :)

Опции командной строки
Опция Пример аргумента Описание
-c -c/my/php.ini Указывает php.ini, который надо загрузить
-d -dmemory_limit=4G Установка соответствующей директивы php.ini
-n   Запрет использования стандартного php.ini
-q   Не показывать приветственный баннер
-v   Разрешить вывод oplog
-b   Запретить использование цветов
-i -imy.init Задать файл .phpdbginit
-I   Игнорировать стандартный .phpdbginit
-O -Omy.oplog Задать файл для записи oplog
-r   Запустить контекст исполнения
-rr   Запустить контекст исполнения и выйти после запуска (не обращать внимание на точки останова)
-e   Генерировать расширенную информацию для отладчика/профилировщика
-E   Разрешить пошаговый eval. Будьте осторожны!
-s -s=, -s=foo Прочитать код для исполнения из стандартного потока ввода с опциональным разделителем
-S -Scli Переопределить имя SAPI. Будьте осторожны!
   

-l -l4000 Задать порт удалённой консоли
-a -a192.168.0.3 Задать адрес удалённой консоли
-x   Включить вывод в формате xml (вместо стандартного текстового)
-p -p, -p=func, -p* Вывести опкоды и выйти
-h   Вывести справочный раздел
-V   Напечатать номер версии
-- -- arg1 arg2 Используется для разделения аргументов phpdbg и php $argv; любые $argv добавляйте после него



Установка и настройка

Содержание


Настройка во время выполнения

Поведение этих функций зависит от установок в php.ini.

phpdbg Опции настройки
Имя По умолчанию Место изменения Список изменений
phpdbg.eol 2 PHP_INI_ALL Удалено, начиная с PHP 8.1.0
phpdbg.path   6 Удалено, начиная с PHP 8.1.0

Краткое разъяснение конфигурационных директив.

phpdbg.eol mixed

Тип окончания строки, используемый для вывода. Для установки значения необходимо использовать один из псевдонимов строк.

int Значение string Псевдоним
0 CRLF, crlf, DOS, dos
1 LF, lf, UNIX, unix
2 CR, cr, MAC, mac

phpdbg.path string




Предопределённые константы

Перечисленные ниже константы определены данным модулем и могут быть доступны только в том случае, если PHP был собран с поддержкой этого модуля или же в том случае, если данный модуль был динамически загружен во время выполнения.

PHPDBG_VERSION (string)
PHPDBG_FILE (int)
Удалено в PHP 7.3.0.
PHPDBG_METHOD (int)
Удалено в PHP 7.3.0.
PHPDBG_LINENO (int)
Удалено в PHP 7.3.0.
PHPDBG_FUNC (int)
Удалено в PHP 7.3.0.
PHPDBG_COLOR_PROMPT (int)
PHPDBG_COLOR_NOTICE (int)
PHPDBG_COLOR_ERROR (int)



Функции phpdbg


phpdbg_break_file

(PHP 5 >= 5.6.3, PHP 7, PHP 8)

phpdbg_break_fileДобавить точку прерывания на конкретную строку файла

Описание

phpdbg_break_file(string $file, int $line): void

Добавляет точку прерывания на строку line файла file.

Список параметров

file

Имя файла.

line

Номер строки.

Возвращаемые значения

Функция не возвращает значения после выполнения.

Смотрите также

  • phpdbg_break_function() - Добавить точку прерывания на вызов функции
  • phpdbg_break_method() - Добавить точку прерывания на вызов метода класса
  • phpdbg_break_next() - Добавить точку прерывания на следующий опкод
  • phpdbg_clear() - Убрать все точки прерывания


phpdbg_break_function

(PHP 5 >= 5.6.3, PHP 7, PHP 8)

phpdbg_break_functionДобавить точку прерывания на вызов функции

Описание

phpdbg_break_function(string $function): void

Добавляет точку прерывания на вызов функции function.

Список параметров

function

Имя функции.

Возвращаемые значения

Функция не возвращает значения после выполнения.

Смотрите также

  • phpdbg_break_file() - Добавить точку прерывания на конкретную строку файла
  • phpdbg_break_method() - Добавить точку прерывания на вызов метода класса
  • phpdbg_break_next() - Добавить точку прерывания на следующий опкод
  • phpdbg_clear() - Убрать все точки прерывания


phpdbg_break_method

(PHP 5 >= 5.6.3, PHP 7, PHP 8)

phpdbg_break_methodДобавить точку прерывания на вызов метода класса

Описание

phpdbg_break_method(string $class, string $method): void

Добавляет точку прерывания на вызов метода method класса class.

Список параметров

class

Имя класса.

method

Имя метода.

Возвращаемые значения

Функция не возвращает значения после выполнения.

Смотрите также

  • phpdbg_break_file() - Добавить точку прерывания на конкретную строку файла
  • phpdbg_break_function() - Добавить точку прерывания на вызов функции
  • phpdbg_break_next() - Добавить точку прерывания на следующий опкод
  • phpdbg_clear() - Убрать все точки прерывания


phpdbg_break_next

(PHP 5 >= 5.6.3, PHP 7, PHP 8)

phpdbg_break_nextДобавить точку прерывания на следующий опкод

Описание

phpdbg_break_next(): void

Добавляет точку прерывания на следующий опкод.

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Функция не возвращает значения после выполнения.

Смотрите также

  • phpdbg_break_file() - Добавить точку прерывания на конкретную строку файла
  • phpdbg_break_function() - Добавить точку прерывания на вызов функции
  • phpdbg_break_method() - Добавить точку прерывания на вызов метода класса
  • phpdbg_clear() - Убрать все точки прерывания


phpdbg_clear

(PHP 5 >= 5.6.0, PHP 7, PHP 8)

phpdbg_clearУбрать все точки прерывания

Описание

phpdbg_clear(): void

Удаляет все заданные ранее точки прерывания. Работает как для заданных с помощью функций phpdbg_break_*(), так и для добавленных вручную через консоль.

Внимание

К настоящему времени эта функция ещё не была документирована; для ознакомления доступен только список аргументов.

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Функция не возвращает значения после выполнения.

Смотрите также

  • phpdbg_break_file() - Добавить точку прерывания на конкретную строку файла
  • phpdbg_break_function() - Добавить точку прерывания на вызов функции
  • phpdbg_break_method() - Добавить точку прерывания на вызов метода класса
  • phpdbg_break_next() - Добавить точку прерывания на следующий опкод


phpdbg_color

(PHP 5 >= 5.6.0, PHP 7, PHP 8)

phpdbg_colorЗадать цвет для элемента

Описание

phpdbg_color(int $element, string $color): void

Устанавливает цвет color для элемента element.

Список параметров

element

Одна из констант PHPDBG_COLOR_*.

color

Имя цвета. Одно из: white, red, green, yellow, blue, purple, cyan или black. Опционально можно использовать суффиксы -bold или -underline. К примеру white-bold или green-underline.

Возвращаемые значения

Функция не возвращает значения после выполнения.

Смотрите также

  • phpdbg_prompt() - Установить приглашение командной строки


phpdbg_end_oplog

(PHP 7, PHP 8)

phpdbg_end_oplog

Описание

phpdbg_end_oplog(array $options = []): ?array

Внимание

К настоящему времени эта функция ещё не была документирована; для ознакомления доступен только список аргументов.

Список параметров

options

Возвращаемые значения



phpdbg_exec

(PHP 5 >= 5.6.0, PHP 7, PHP 8)

phpdbg_execПопытаться задать контекст исполнения

Описание

phpdbg_exec(string $context): string|bool

Внимание

К настоящему времени эта функция ещё не была документирована; для ознакомления доступен только список аргументов.

Список параметров

context

Возвращаемые значения

Предыдущий контекст исполнения, если он был задан. true, если контекст исполнения ранее не был задан. Если запрос на установку контекста завершится с ошибкой, то будет возвращено false и вызвана ошибка уровня E_WARNING.



phpdbg_get_executable

(PHP 7, PHP 8)

phpdbg_get_executable

Описание

phpdbg_get_executable(array $options = []): array

Внимание

К настоящему времени эта функция ещё не была документирована; для ознакомления доступен только список аргументов.

Список параметров

options

Возвращаемые значения



phpdbg_prompt

(PHP 5 >= 5.6.0, PHP 7, PHP 8)

phpdbg_promptУстановить приглашение командной строки

Описание

phpdbg_prompt(string $string): void

Устанавливает приглашение командной строки как задано в string.

Список параметров

string

Строка, которая будет использована как приглашение.

Возвращаемые значения

Функция не возвращает значения после выполнения.

Смотрите также



phpdbg_start_oplog

(PHP 7, PHP 8)

phpdbg_start_oplog

Описание

phpdbg_start_oplog(): void

Внимание

К настоящему времени эта функция ещё не была документирована; для ознакомления доступен только список аргументов.

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Функция не возвращает значения после выполнения.


Содержание




runkit7


Введение

Модуль runkit7 предоставляет средства для изменения констант, пользовательских функций и пользовательских классов. Также предусмотрены пользовательские суперглобальные переменные.

Этот пакет является форком пакета » runkit, обеспечивающего поддержку PHP 7.



Установка и настройка

Содержание


Требования

Изменение констант, функций, классов и методов так же как и Пользовательские суперглобальные переменные работает со всеми выпусками PHP 7. Никаких особых требований не требуется.



Установка

Этот модуль » PECL не поставляется вместе с PHP.

Информация по установке этого модуля PECL может быть найдена в главе руководства Установка PECL модулей. Дополнительная информация, такая как новые версии, скачивание, исходные файлы, информация о разработчике и CHANGELOG, может быть найдена здесь: » https://pecl.php.net/package/runkit7.

Бинарные файлы Windows (файлы DLL) для этого модуля PECL доступны на сайте PECL.



Настройка во время выполнения

Поведение этих функций зависит от установок в php.ini.

Параметры конфигурации Runkit
Имя По умолчанию Место изменения Список изменений
runkit.superglobal "" PHP_INI_PERDIR  
runkit.internal_override "0" PHP_INI_SYSTEM  
Для подробного описания констант PHP_INI_*, обратитесь к разделу Где могут быть установлены параметры конфигурации.

Краткое разъяснение конфигурационных директив.

runkit.superglobal string
Разделённый запятыми список имён переменных, которые будут рассматриваться как суперглобальные. Это значение должно быть установлено в общесистемном файле php.ini, но может работать в контекстах конфигурации perdir в зависимости от вашего SAPI.

Пример #1 Пользовательские суперглобальные файлы с runkit.superglobal=_FOO,_BAR в php.ini

<?php
function show_values() {
echo
"Foo is $_FOO\n";
echo
"Bar is $_BAR\n";
echo
"Baz is $_BAZ\n";
}

$_FOO = 'foo';
$_BAR = 'bar';
$_BAZ = 'baz';

/* Отобразит foo и bar, но не baz */
show_values();
?>
runkit.internal_override bool
Позволяет изменять/переименовывать/удалять внутренние функции.



Типы ресурсов

Данный модуль не определяет каких-либо типов ресурсов.




Предопределённые константы

Перечисленные ниже константы определены данным модулем и могут быть доступны только в том случае, если PHP был собран с поддержкой этого модуля или же в том случае, если данный модуль был динамически загружен во время выполнения.

RUNKIT7_IMPORT_FUNCTIONS (int)
runkit7_import() флаг, указывающий, что нормальные функции должны быть импортированы из указанного файла.
RUNKIT7_IMPORT_CLASS_METHODS (int)
runkit7_import() флаг, указывающий, что методы класса должны быть импортированы из указанного файла.
RUNKIT7_IMPORT_CLASS_CONSTS (int)
runkit7_import() флаг, указывающий, что константы класса должны быть импортированы из указанного файла.
RUNKIT7_IMPORT_CLASS_PROPS (int)
runkit7_import() флаг, указывающий, что стандартные свойства класса должны быть импортированы из указанного файла.
RUNKIT7_IMPORT_CLASS_STATIC_PROPS (int)
runkit7_import() флаг, указывающий, что статические свойства класса должны быть импортированы из указанного файла. Доступно с Runkit 1.0.1.
RUNKIT7_IMPORT_CLASSES (int)
runkit7_import() флаг, представляющий побитовое значение ИЛИ константы RUNKIT7_IMPORT_CLASS_*.
RUNKIT7_IMPORT_OVERRIDE (int)
runkit7_import() флаг, указывающий, что если какие-либо импортированные функции, методы, константы или свойства уже существуют, они должны быть заменены новыми определениями. Если этот флаг не установлен, то любые импортированные определения, которые уже существуют, будут отброшены.
RUNKIT7_ACC_RETURN_REFERENCE (int)
Включите этот флаг, чтобы создаваемая или повторно объявленная функция или метод возвращали ссылку.
RUNKIT7_ACC_PUBLIC (int)
Флаг для runkit7_method_add() и runkit7_method_redefine(), чтобы сделать метод публичным.
RUNKIT7_ACC_PROTECTED (int)
Флаг для runkit7_method_add() and runkit7_method_redefine(), чтобы сделать метод защищённым.
RUNKIT7_ACC_PRIVATE (int)
Флаг для runkit7_method_add() and runkit7_method_redefine(), чтобы сделать метод приватным.
RUNKIT7_ACC_STATIC (int)
Флаг для runkit7_method_add() and runkit7_method_redefine(), чтобы сделать метод статичным.
RUNKIT7_FEATURE_MANIPULATION (int)
Равен 1, если включена манипуляция во время выполнения и 0 в противном случае.
RUNKIT7_FEATURE_SUPERGLOBALS (int)
Равен 1, если пользовательские суперглобальные переменные включены и 0 в противном случае.
RUNKIT7_FEATURE_SANDBOX (int)
Всегда 0, нереально реализовать функцию песочницы в php 7.



Функции runkit7


runkit7_constant_add

(PECL runkit7 >= Unknown)

runkit7_constant_addАналогичен define(), но также позволяет определить константу класса

Описание

runkit7_constant_add(string $constant_name, mixed $value, int $newVisibility = ?): bool

Список параметров

constant_name

Имя объявляемой константы. Либо строка для обозначения глобальной константы, либо classname::constname для определения константы класса.

value

Значение константы (NULL, Bool, Long, Double, String, Array или Resource).

newVisibility

Видимость константы для констант класса. По умолчанию общедоступный. Одна из констант RUNKIT7_ACC_*.

Возвращаемые значения

Возвращает true в случае успешного выполнения или false в случае возникновения ошибки.

Смотрите также



runkit7_constant_redefine

(PECL runkit7 >= Unknown)

runkit7_constant_redefineПереопределяет уже определённую константу

Описание

runkit7_constant_redefine(string $constant_name, mixed $value, int $new_visibility = ?): bool

Список параметров

constant_name

Константа, которую необходимо переопределить. Либо имя глобальной константы, либо classname::constname для переопределения константы класса.

value

Значение, присваиваемое константе.

new_visibility

Новая видимость константы для констант класса. По умолчанию без изменений. Одна из констант RUNKIT7_ACC_*.

Возвращаемые значения

Возвращает true в случае успешного выполнения или false в случае возникновения ошибки.

Смотрите также

  • runkit7_constant_add() - Аналогичен define(), но также позволяет определить константу класса
  • runkit7_constant_remove() - Удаляет уже определённую константу



runkit7_constant_remove

(PECL runkit7 >= Unknown)

runkit7_constant_removeУдаляет уже определённую константу

Описание

runkit7_constant_remove(string $constant_name): bool

Список параметров

constant_name

Константа, которую необходимо удалить. Либо имя глобальной константы, либо classname::constname для удаления константы класса.

Возвращаемые значения

Возвращает true в случае успешного выполнения или false в случае возникновения ошибки.

Смотрите также

  • define() - Определяет именованную константу
  • runkit7_constant_add() - Аналогичен define(), но также позволяет определить константу класса
  • runkit7_constant_redefine() - Переопределяет уже определённую константу



runkit7_function_add

(PECL runkit7 >= Unknown)

runkit7_function_addДобавляет новую функцию, функция аналогична create_function()

Описание

runkit7_function_add(
    string $function_name,
    string $argument_list,
    string $code,
    bool $return_by_reference = null,
    string $doc_comment = null,
    string $return_type = ?,
    bool $is_strict = ?
): bool
runkit7_function_add(
    string $function_name,
    Closure $closure,
    string $doc_comment = null,
    string $return_type = ?,
    bool $is_strict = ?
): bool

Список параметров

function_name

Имя создаваемой функции.

argument_list

Список аргументов, разделённых запятыми.

code

Код, составляющий функцию.

closure

Замыкание (closure), определяющее функцию.

return_by_reference

Определяет, должна ли функция возвращаться по ссылке.

doc_comment

Документальный комментарий функции.

return_type

Тип возвращаемого значения функции.

is_strict

Определяет, должна ли функция вести себя так, как если бы она была объявлена в файле с strict_types=1.

Возвращаемые значения

Возвращает true в случае успешного выполнения или false в случае возникновения ошибки.

Примеры

Пример #1 Пример использования runkit7_function_add()

<?php
runkit7_function_add
('testme','$a,$b','echo "Значение A - $a\n"; echo "Значение B - $b\n";');
testme(1,2);
?>

Результат выполнения данного примера:

Значение A - 1
Значение B - 2

Смотрите также



runkit7_function_copy

(PECL runkit7 >= Unknown)

runkit7_function_copyКопирует функцию в новое имя функции

Описание

runkit7_function_copy(string $source_name, string $target_name): bool

Список параметров

source_name

Имя существующей функции.

target_name

Имя новой функции, в которую нужно скопировать определение.

Возвращаемые значения

Возвращает true в случае успешного выполнения или false в случае возникновения ошибки.

Примеры

Пример #1 Пример использования runkit7_function_copy()

<?php
function original() {
echo
"В функции\n";
}
runkit7_function_copy('original','duplicate');
original();
duplicate();
?>

Результат выполнения данного примера:

В функции
В функции

Смотрите также



runkit7_function_redefine

(PECL runkit7 >= Unknown)

runkit7_function_redefineЗаменяет определение функции новой реализацией

Описание

runkit7_function_redefine(
    string $function_name,
    string $argument_list,
    string $code,
    bool $return_by_reference = null,
    string $doc_comment = null,
    string $return_type = ?,
    bool $is_strict = ?
): bool
runkit7_function_redefine(
    string $function_name,
    Closure $closure,
    string $doc_comment = null,
    string $return_type = ?,
    bool $is_strict = ?
): bool

Замечание: По умолчанию, только пользовательские функции могут быть удалены, переименованы или изменены. Для перекрытия внутренних функций, необходимо включить в php.ini опцию runkit.internal_override.

Список параметров

function_name

Имя функции для переопределения.

argument_list

Новый список аргументов, принимаемых функцией.

code

Реализация нового кода.

closure

Замыкание (closure), определяющее функцию.

return_by_reference

Определяет, должна ли функция возвращаться по ссылке.

doc_comment

Документальный комментарий функции.

return_type

Тип возвращаемого значения функции.

is_strict

Определяет, должна ли функция вести себя так, как если бы она была объявлена в файле с strict_types=1.

Возвращаемые значения

Возвращает true в случае успешного выполнения или false в случае возникновения ошибки.

Примеры

Пример #1 Пример использования runkit7_function_redefine()

<?php
function testme() {
echo
"Оригинальная реализация Testme\n";
}
testme();
runkit7_function_redefine('testme','','echo "Новая реализация Testme\n";');
testme();
?>

Результат выполнения данного примера:

Оригинальная реализация Testme
Новая реализация Testme

Смотрите также



runkit7_function_remove

(PECL runkit7 >= Unknown)

runkit7_function_removeУдаляет определение функции

Описание

runkit7_function_remove(string $function_name): bool

Замечание: По умолчанию, только пользовательские функции могут быть удалены, переименованы или изменены. Для перекрытия внутренних функций, необходимо включить в php.ini опцию runkit.internal_override.

Список параметров

function_name

Имя удаляемой функции.

Возвращаемые значения

Возвращает true в случае успешного выполнения или false в случае возникновения ошибки.

Смотрите также



runkit7_function_rename

(PECL runkit7 >= Unknown)

runkit7_function_renameИзменяет имя функции

Описание

runkit7_function_rename(string $source_name, string $target_name): bool

Замечание: По умолчанию, только пользовательские функции могут быть удалены, переименованы или изменены. Для перекрытия внутренних функций, необходимо включить в php.ini опцию runkit.internal_override.

Список параметров

source_name

Текущее имя функции.

target_name

Новое имя функции.

Возвращаемые значения

Возвращает true в случае успешного выполнения или false в случае возникновения ошибки.

Смотрите также



runkit7_import

(PECL runkit7 >= Unknown)

runkit7_importОбрабатывает функцию импорта файла PHP и определения классов, при необходимости перезаписывая

Внимание

Функционал был удалён в PECL runkit7 4.0.0.

Описание

runkit7_import(string $filename, int $flags = ?): bool

Функция подобна include. Однако любой код, находящийся за пределами функции или класса, просто игнорируется. Кроме того, в зависимости от значения flags, любые функции или классы, которые уже существуют в текущей запущенной среде, могут быть автоматически перезаписаны их новыми определениями.

Список параметров

filename

Имя файла для импорта определений функций и классов.

flags

Побитовое ИЛИ констант RUNKIT7_IMPORT_*.

Возвращаемые значения

Возвращает true в случае успешного выполнения или false в случае возникновения ошибки.



runkit7_method_add

(PECL runkit7 >= Unknown)

runkit7_method_addДинамически добавляет новый метод в заданный класс

Описание

runkit7_method_add(
    string $class_name,
    string $method_name,
    string $argument_list,
    string $code,
    int $flags = RUNKIT7_ACC_PUBLIC,
    string $doc_comment = null,
    string $return_type = ?,
    bool $is_strict = ?
): bool
runkit7_method_add(
    string $class_name,
    string $method_name,
    Closure $closure,
    int $flags = RUNKIT7_ACC_PUBLIC,
    string $doc_comment = null,
    string $return_type = ?,
    bool $is_strict = ?
): bool

Список параметров

class_name

Класс, в котором нужно добавить метод.

method_name

Имя метода, который нужно добавить.

argument_list

Разделённый запятыми список аргументов для нового метода.

code

Код, который будет выполняться при вызове method_name.

closure

Замыкание (closure), определяющее метод.

flags

Метод может быть RUNKIT7_ACC_PUBLIC, RUNKIT7_ACC_PROTECTED или RUNKIT7_ACC_PRIVATE, и, при необходимости, объединён с помощью побитового ИЛИ с RUNKIT7_ACC_STATIC.

doc_comment

Документальный комментарий метода.

return_type

Тип возвращаемого значения метода.

is_strict

Определяет, будет ли метод вести себя так, как если бы он был объявлен в файле с strict_types=1.

Возвращаемые значения

Возвращает true в случае успешного выполнения или false в случае возникновения ошибки.

Примеры

Пример #1 Пример использования runkit7_method_add()

<?php
class Example {
function
foo() {
echo
"foo!\n";
}
}

// создание объекта Example
$e = new Example();

// добавление нового общедоступного метода
runkit7_method_add(
'Example',
'add',
'$num1, $num2',
'return $num1 + $num2;',
RUNKIT7_ACC_PUBLIC
);

// добавление 12 + 4
echo $e->add(12, 4);
?>

Результат выполнения данного примера:

16

Смотрите также



runkit7_method_copy

(PECL runkit7 >= Unknown)

runkit7_method_copyКопирует метод из одного класса в другой

Описание

runkit7_method_copy(
    string $destination_class,
    string $destination_method_name,
    string $source_class,
    string $source_method_name = ?
): bool

Список параметров

destination_class

Целевой класс для скопированного метода.

destination_method_name

Название метода назначения.

source_class

Исходный класс скопированного метода.

source_method_name

Имя метода для копирования из исходного класса. Если этот параметр опущен, предполагается значение destination_method_name.

Возвращаемые значения

Примеры

Пример #1 Пример использования runkit7_method_copy()

<?php
class Foo {
function
example() {
return
"foo!\n";
}
}

class
Bar {
// изначально никаких методов
}

// копирование метода example() из класса Foo в класс Bar как baz()
runkit7_method_copy('Bar', 'baz', 'Foo', 'example');

// функция вывода скопирована
echo Bar::baz();
?>

Результат выполнения данного примера:

foo!

Смотрите также



runkit7_method_redefine

(PECL runkit7 >= Unknown)

runkit7_method_redefineДинамически изменяет код заданного метода

Описание

runkit7_method_redefine(
    string $class_name,
    string $method_name,
    string $argument_list,
    string $code,
    int $flags = RUNKIT7_ACC_PUBLIC,
    string $doc_comment = null,
    string $return_type = ?,
    bool $is_strict = ?
): bool
runkit7_method_redefine(
    string $class_name,
    string $method_name,
    Closure $closure,
    int $flags = RUNKIT7_ACC_PUBLIC,
    string $doc_comment = null,
    string $return_type = ?,
    bool $is_strict = ?
): bool

Список параметров

class_name

Класс, в котором нужно переопределить метод.

method_name

Имя метода, который нужно переопределить.

argument_list

Разделённый запятыми список аргументов для переопределённого метода.

code

Новый код, который будет выполняться при вызове method_name.

closure

Замыкание (closure), определяющее метод.

flags

Переопределённый метод может быть RUNKIT7_ACC_PUBLIC, RUNKIT7_ACC_PROTECTED или RUNKIT7_ACC_PRIVATE, и, при необходимости, объединён с помощью побитового ИЛИ с RUNKIT7_ACC_STATIC.

doc_comment

Документальный комментарий метода.

return_type

Тип возвращаемого значения метода.

is_strict

Определяет, будет ли метод вести себя так, как если бы он был объявлен в файле с strict_types=1.

Возвращаемые значения

Возвращает true в случае успешного выполнения или false в случае возникновения ошибки.

Примеры

Пример #1 Пример использования runkit7_method_redefine()

<?php
class Example {
function
foo() {
return
"foo!\n";
}
}

// создание объекта Example
$e = new Example();

// вывод Example::foo() (до переопределения)
echo "До: " . $e->foo();

// Переопределение метода 'foo'
runkit7_method_redefine(
'Example',
'foo',
'',
'return "bar!\n";',
RUNKIT7_ACC_PUBLIC
);

// вывод Example::foo() (после переопределения)
echo "После: " . $e->foo();
?>

Результат выполнения данного примера:

До: foo!
После: bar!

Смотрите также



runkit7_method_remove

(PECL runkit7 >= Unknown)

runkit7_method_removeДинамически удаляет заданный метод

Описание

runkit7_method_remove(string $class_name, string $method_name): bool

Замечание: Эта функция не может быть использована для влияния на работающие в данный момент (или цепные) методы.

Список параметров

class_name

Класс, в котором нужно удалить метод.

method_name

Имя удаляемого метода.

Возвращаемые значения

Возвращает true в случае успешного выполнения или false в случае возникновения ошибки.

Примеры

Пример #1 Пример использования runkit7_method_remove()

<?php
class Example {
function
foo() {
return
"foo!\n";
}

function
bar() {
return
"bar!\n";
}
}

// Remove the 'foo' method
runkit7_method_remove(
'Example',
'foo'
);

echo
implode(' ', get_class_methods('Example'));

?>

Результат выполнения данного примера:

bar

Смотрите также



runkit7_method_rename

(PECL runkit7 >= Unknown)

runkit7_method_renameДинамически изменяет имя заданного метода

Описание

runkit7_method_rename(string $class_name, string $source_method_name, string $target_method_name): bool

Замечание: Эта функция не может быть использована для влияния на работающие в данный момент (или цепные) методы.

Список параметров

class_name

Класс, в котором нужно переименовать метод.

source_method_name

Метод, который нужно переименовать.

target_method_name

Новое имя метода.

Возвращаемые значения

Возвращает true в случае успешного выполнения или false в случае возникновения ошибки.

Примеры

Пример #1 Пример использования runkit7_method_rename()

<?php
class Example {
function
foo() {
return
"foo!\n";
}
}

// Переименование метода 'foo' в 'bar'
runkit7_method_rename(
'Example',
'foo',
'bar'
);

// Вывод переименованной функции
echo (new Example)->bar();
?>

Результат выполнения данного примера:

foo!

Смотрите также



runkit7_object_id

(PECL runkit7 >= Unknown)

runkit7_object_idВозвращает дескриптор целочисленного объекта для данного объекта

Описание

runkit7_object_id(object $obj): int

Функция эквивалентна spl_object_id().

Функция возвращает уникальный идентификатор объекта. Идентификатор объекта уникален на протяжении всего времени существования объекта. После уничтожения объекта его идентификатор может быть повторно использован для других объектов. Поведение похоже на spl_object_hash().

Список параметров

obj

Любой объект.

Возвращаемые значения

Целочисленный идентификатор, уникальный для каждого существующего в данный момент объекта и всегда одинаковый для каждого объекта.

Примечания

Замечание:

Когда объект уничтожен, его идентификатор может быть повторно использован для других объектов.

Смотрите также

  • spl_object_id() - Получить целочисленный идентификатор объекта



runkit7_superglobals

(PECL runkit7 >= Unknown)

runkit7_superglobalsВозвращает числовой индексированный массив зарегистрированных суперглобальных переменных

Описание

runkit7_superglobals(): array

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Возвращает числовой индексированный массив зарегистрированных суперглобальных переменных. Например: _GET, _POST, _REQUEST, _COOKIE, _SESSION, _SERVER, _ENV, _FILES.



runkit7_zval_inspect

(PECL runkit7 >= Unknown)

runkit7_zval_inspectВозвращает информацию о переданном значении с типами данных, количеством ссылок и так далее

Описание

runkit7_zval_inspect(string $value): array

Список параметров

value

Значение, чтобы вернуть представление.

Возвращаемые значения

Массив, возвращаемый этой функцией, содержит следующие элементы:

  • address
  • refcount (необязательный)
  • is_ref (необязательный)
  • type

Примеры

Пример #1 Пример использования runkit7_zval_inspect()

<?php

$var
= new DateTime();
var_dump(runkit7_zval_inspect($var));

$var = 1;
var_dump(runkit7_zval_inspect($var));
?>

Результат выполнения данного примера:

array(4) {
  ["address"]=>
  string(14) "0x7f45ab21b1e0"
  ["refcount"]=>
  int(2)
  ["is_ref"]=>
  bool(false)
  ["type"]=>
  int(8)
}

array(2) {
  ["address"]=>
  string(14) "0x7f45ab21b1e0"
  ["type"]=>
  int(4)
}


Содержание

  • runkit7_constant_add — Аналогичен define(), но также позволяет определить константу класса
  • runkit7_constant_redefine — Переопределяет уже определённую константу
  • runkit7_constant_remove — Удаляет уже определённую константу
  • runkit7_function_add — Добавляет новую функцию, функция аналогична create_function
  • runkit7_function_copy — Копирует функцию в новое имя функции
  • runkit7_function_redefine — Заменяет определение функции новой реализацией
  • runkit7_function_remove — Удаляет определение функции
  • runkit7_function_rename — Изменяет имя функции
  • runkit7_import — Обрабатывает функцию импорта файла PHP и определения классов, при необходимости перезаписывая
  • runkit7_method_add — Динамически добавляет новый метод в заданный класс
  • runkit7_method_copy — Копирует метод из одного класса в другой
  • runkit7_method_redefine — Динамически изменяет код заданного метода
  • runkit7_method_remove — Динамически удаляет заданный метод
  • runkit7_method_rename — Динамически изменяет имя заданного метода
  • runkit7_object_id — Возвращает дескриптор целочисленного объекта для данного объекта
  • runkit7_superglobals — Возвращает числовой индексированный массив зарегистрированных суперглобальных переменных
  • runkit7_zval_inspect — Возвращает информацию о переданном значении с типами данных, количеством ссылок и так далее



User Operations для Zend


Введение

Модуль uopz (User Operations for Zend) предоставляет функциональность Zend Engine, обычно используемую во время компиляции и выполнении, чтобы разрешить модификацию внутренних структур, представляющих PHP-код, и для взаимодействия пользовательского кода с виртуальной машиной.

uopz поддерживает следующие действия:

  • Перегрузка некоторых опкодов, включая ZEND_EXIT и ZEND_NEW
  • Функции и методы резервного копирования и восстановления
  • Переименование функций и методов
  • Копирование функций и методов
  • Удаление функций и методов
  • Переопределение глобальных и классовых констант
  • Удаление глобальных и классовых констант
  • Создание и модификация классов во время выполнения

Замечание:

Все поддерживаемые действия совместимы с opcache

Предостережение

PECL uopz 6.1.1 несовместим с Xdebug >= 2.9.4. Более поздние версии uopz несовместимы с Xdebug < 2.9.4.



Установка и настройка

Содержание


Требования

Для uopz 5.0 требуется PHP 7.0. Начиная с uopz 5.1 требуется PHP 7.1+.



Установка

Релизы uopz распространяются через PECL, а исходный код находится на » github, самый простой путь к установке - через PECL: » https://pecl.php.net/package/uopz.

Пользователи Windows могут загрузить готовый исполняемый релиз с сайта » PECL.

Начиная с 5.0.0, модуль должен загружаться как обычный модуль PHP (extension). Ранее его надо было загружать как zend_extension.



Настройка во время выполнения

Поведение этих функций зависит от установок в php.ini.

uopz Опции настройки
Имя По умолчанию Место изменения Список изменений
uopz.disable "0" PHP_INI_SYSTEM Доступно начиная с uopz 5.0.2
uopz.exit "0" PHP_INI_SYSTEM Доступно начиная с uopz 6.0.1
uopz.overloads "1" PHP_INI_SYSTEM Доступно начиная с uopz 2.0.2. Удалено начиная с uopz 5.0.0.
Для подробного описания констант PHP_INI_*, обратитесь к разделу Где могут быть установлены параметры конфигурации.

Краткое разъяснение конфигурационных директив.

uopz.disable bool

Если включено, uopz перестанет влиять на работу PHP.

uopz.exit bool

Позволять ли модулю исполнять опкод exit(выход). Эта настройка может быть переопределена во время исполнения с помощью функции uopz_allow_exit().

uopz.overloads bool

Даёт возможность использовать uopz_overload().

Замечание: При работе с включённым OPcache может потребоваться отключить все оптимизации OPcache (opcache.optimization_level=0).



Типы ресурсов

Данный модуль не определяет каких-либо типов ресурсов.




Предопределённые константы

Перечисленные ниже константы определены данным модулем и могут быть доступны только в том случае, если PHP был собран с поддержкой этого модуля или же в том случае, если данный модуль был динамически загружен во время выполнения.

Следующие опкоды определяются как константы с помощью uopz до версии 5.0.0:

ZEND_EXIT (int)
Вызывается с помощью exit() and die(), не принимает аргументов. Возвращает логический true для выхода, false для продолжения
ZEND_NEW (int)
Вызывается конструкцией объекта, получает класс создаваемого объекта в качестве единственного аргумента
ZEND_THROW (int)
Вызывается конструкцией throw, получает класс выбрасываемого исключения в качестве единственного аргумента
ZEND_FETCH_CLASS (int)
Вызывается во время композиции, получает имя получаемого в качестве единственного аргумента
ZEND_ADD_TRAIT (int)
Вызывается во время композиции, получает класс добавляемого трейта первым аргументом, и имя трейта в качестве второго аргумента
ZEND_ADD_INTERFACE (int)
Вызывается во время композиции, получает класс добавляемого интерфейса первым аргументом, и имя интерфейса в качестве второго аргумента
ZEND_INSTANCEOF (int)
Вызывается оператором instanceof, получает проверяемый объект первым аргументом и имя класса, который должен быть в объекте в качестве второго аргумента

Следующие константы управляют поведением виртуальной машины после вызова обработчика пользователя, будьте предельно осторожны! Эти константы удалены с uopz версии 5.0.0.

ZEND_USER_OPCODE_CONTINUE (int)
Продвинуть 1 опкод и продолжить
ZEND_USER_OPCODE_ENTER (int)
Ввести новый new op_array без рекурсии
ZEND_USER_OPCODE_LEAVE (int)
Вернуть вызывающий op_array внутри того же исполнителя
ZEND_USER_OPCODE_DISPATCH (int)
Отправить в исходный обработчик опкода
ZEND_USER_OPCODE_DISPATCH_TO (int)
Отправить на конкретный обработчик (посредством бинарного OR с константой опкода ZEND)
ZEND_USER_OPCODE_RETURN (int)
Выйти из исполнителя (возврат из функции)

Следующие модификаторы регистрируются как константы uopz

ZEND_ACC_PUBLIC (int)
Отметить функцию как общедоступную, по умолчанию
ZEND_ACC_PROTECTED (int)
Отметить функцию как защищённую
ZEND_ACC_PRIVATE (int)
Отметить функцию как закрытую
ZEND_ACC_STATIC (int)
Отметить функцию как статическую
ZEND_ACC_FINAL (int)
Отметить функцию как окончательную
ZEND_ACC_ABSTRACT (int)
Отметить функцию как абстрактную
ZEND_ACC_CLASS (int)
Фиктивная регистрация для согласованности, запись класса по умолчанию. Удалено в uopz 5.0.0.
ZEND_ACC_INTERFACE (int)
Отметить класс как интерфейс. Удалено в uopz 5.0.0.
ZEND_ACC_TRAIT (int)
Отметить класс как трейт. Удалено в uopz 5.0.0.
ZEND_ACC_FETCH (int)
Используется только для получения флагов. Удалено в uopz 5.0.0.



Функции Uopz


uopz_add_function

(PECL uopz 5, PECL uopz 6, PECL uopz 7)

uopz_add_functionДобавляет несуществующую функцию или метод

Описание

uopz_add_function(string $function, Closure $handler, int &$flags = ZEND_ACC_PUBLIC): bool
uopz_add_function(
    string $class,
    string $function,
    Closure $handler,
    int &$flags = ZEND_ACC_PUBLIC,
    int &$all = true
): bool

Добавляет несуществующую функцию или метод.

Список параметров

class

Имя класса.

function

Имя функции или метода.

handler

Объект Closure, который определяет новую функцию или метод.

flags

Флаги для установки новой функции или метода.

all

Будут ли затронуты все классы, которые происходят от класса (class).

Возвращаемые значения

Возвращает true в случае успешного выполнения или false в случае возникновения ошибки.

Ошибки

uopz_add_function() выбрасывает RuntimeException, если добавляемая функция или метод уже существует.

Примеры

Пример #1 Простое использование uopz_add_function()

<?php
uopz_add_function
('foo', function () {echo 'bar';});
foo();
?>

Результат выполнения данного примера:

bar

Смотрите также

  • uopz_del_function() - Удаляет ранее добавленную функцию или метод
  • uopz_set_return() - Предоставить возвращаемое значение для существующей функции


uopz_allow_exit

(PECL uopz 5, PECL uopz 6, PECL uopz 7)

uopz_allow_exitПозволяет управлять отключённым опкодом exit

Описание

uopz_allow_exit(bool $allow): void

По умолчанию uopz отключает опкод exit, поэтому вызовы exit() практически игнорируются. uopz_allow_exit() позволяет контролировать это поведение.

Список параметров

allow

Разрешить выполнение опкодов exit или нет.

Возвращаемые значения

Функция не возвращает значения после выполнения.

Примеры

Пример #1 Пример использования uopz_allow_exit()

<?php
exit(1);
echo
1;
uopz_allow_exit(true);
exit(
2);
echo
2;
?>

Результат выполнения данного примера:

1

Примечания

Предостережение

OPcache оптимизирует мёртвый код после безусловного завершения.

Смотрите также

  • uopz_get_exit_status() - Получить последний установленный статус выхода


uopz_backup

(PECL uopz 1 >= 1.0.3, PECL uopz 2)

uopz_backupРезервирует функцию

Внимание

Эта функция была УДАЛЕНА в PECL uopz 5.0.0.

Описание

uopz_backup(string $function): void
uopz_backup(string $class, string $function): void

Резервирует функцию во время выполнения, которая будет восстановлена при завершении работы скрипта

Список параметров

class

Имя класса, содержащего функцию для резервирования

function

Имя функции

Возвращаемые значения

Примеры

Пример #1 Пример использования uopz_backup()

<?php
uopz_backup
("fgets");
uopz_function("fgets", function(){
return
true;
});
var_dump(fgets());
?>

Результат выполнения данного примера:

bool(true)


uopz_compose

(PECL uopz 1, PECL uopz 2)

uopz_composeСоставить класс

Внимание

Эта функция была УДАЛЕНА в PECL uopz 5.0.0.

Описание

uopz_compose(
    string $name,
    array $classes,
    array $methods = ?,
    array $properties = ?,
    int $flags = ?
): void

Создаёт класс заданного имени, который реализует, наследует или использует все предоставленные классы

Список параметров

name

Корректное имя класса

classes

Массив имён классов, интерфейсов и трейтов

methods

Ассоциативный массив методов, где значения либо замыкания, либо представлены структурой [модификаторы => замыкание]

properties

Ассоциативный массив свойств, где ключи - имена, а значения - модификаторы

flags

Тип записи, по умолчанию ZEND_ACC_CLASS

Возвращаемые значения

Примеры

Пример #1 Пример использования uopz_compose()

<?php
class myClass {}
trait
myTrait {}
interface
myInterface {}

uopz_compose(
Composed::class, [
myClass::class,
myTrait::class,
myInterface::class
], [
"__construct" => function() {
/* ... */
}
]);

var_dump(
class_uses(Composed::class),
class_parents(Composed::class),
class_implements(Composed::class));
?>

Результат выполнения данного примера:

array(1) {
  ["myTrait"]=>
  string(7) "myTrait"
}
array(1) {
  ["myClass"]=>
  string(7) "myClass"
}
array(1) {
  ["myInterface"]=>
  string(11) "myInterface"
}


uopz_copy

(PECL uopz 1 >= 1.0.4, PECL uopz 2)

uopz_copyСкопировать функцию

Внимание

Эта функция была УДАЛЕНА в PECL uopz 5.0.0.

Описание

uopz_copy(string $function): Closure
uopz_copy(string $class, string $function): Closure

Скопировать функцию по имени

Список параметров

class

Имя класса, содержащего функцию для копирования

function

Имя функции

Возвращаемые значения

Объект Closure для определённой функции

Примеры

Пример #1 Пример использования uopz_copy()

<?php
$strtotime
= uopz_copy('strtotime');

uopz_function("strtotime", function($arg1, $arg2) use($strtotime) {
/* зесь можно вызвать оригинальную функцию strtotime */
var_dump($arg1);
});

var_dump(strtotime('dummy'));
?>

Результат выполнения данного примера:

string(5) "dummy"


uopz_del_function

(PECL uopz 5, PECL uopz 6, PECL uopz 7)

uopz_del_functionУдаляет ранее добавленную функцию или метод

Описание

uopz_del_function(string $function): bool
uopz_del_function(string $class, string $function, int &$all = true): bool

Удаляет ранее добавленную функцию или метод.

Список параметров

class

Имя класса.

function

Имя функции или метода.

all

Будут ли затронуты все классы, которые происходят от класса (class).

Возвращаемые значения

Возвращает true в случае успешного выполнения или false в случае возникновения ошибки.

Ошибки

uopz_del_function() выбрасывает RuntimeException, если удаляемые функция или метод не были добавлены с помощью uopz_add_function().

Примеры

Пример #1 Простое использование uopz_del_function()

<?php
uopz_add_function
('foo', function () {echo 'bar';});
var_dump(function_exists('foo'));
uopz_del_function('foo');
var_dump(function_exists('foo'));
?>

Результат выполнения данного примера:

bool(true)
bool(false)

Смотрите также

  • uopz_add_function() - Добавляет несуществующую функцию или метод
  • uopz_unset_return() - Отменяет ранее установленное возвращаемое значение для функции


uopz_delete

(PECL uopz 1, PECL uopz 2)

uopz_deleteУдалить функцию

Внимание

Эта функция была УДАЛЕНА в PECL uopz 5.0.0.

Описание

uopz_delete(string $function): void
uopz_delete(string $class, string $function): void

Удаляет функцию или метод

Список параметров

class

function

Возвращаемые значения

Примеры

Пример #1 Пример использования uopz_delete()

<?php
uopz_delete
("strlen");

echo
strlen("Hello World");
?>

Результатом выполнения данного примера будет что-то подобное:

PHP Fatal error: Call to undefined function strlen() in /path/to/script.php on line 4

Пример #2 Пример использования uopz_delete() с классом

<?php
class My {
public static function
strlen($arg) {
return
strlen($arg);
}
}

uopz_delete(My::class, "strlen");

echo
My::strlen("Hello World");
?>

Результатом выполнения данного примера будет что-то подобное:

PHP Fatal error: Call to undefined method My::strlen() in /path/to/script.php on line 10


uopz_extend

(PECL uopz 1, PECL uopz 2, PECL uopz 5, PECL uopz 6, PECL uopz 7 < 7.1.0)

uopz_extendРасширить класс во время выполнения

Описание

uopz_extend(string $class, string $parent): bool

Расширяет текущий класс class родительским parent

Список параметров

class

Название класса для расширения

parent

Название класса для наследования

Возвращаемые значения

Возвращает true в случае успешного выполнения или false в случае возникновения ошибки.

Ошибки

Начиная с PHP 7.4.0, uopz_extends() выбрасывает RuntimeException, если OPcache включён и запись класса либо class, либо parent (если это признак) неизменны.

Примеры

Пример #1 Пример использования uopz_extend()

<?php
class A {}
class
B {}

uopz_extend(A::class, B::class);

var_dump(class_parents(A::class));
?>

Результат выполнения данного примера:

array(1) {
  ["B"]=>
  string(1) "B"
}


uopz_flags

(PECL uopz 2 >= 2.0.2, PECL uopz 5, PECL uopz 6, PECL uopz 7)

uopz_flagsПолучить или установить флаги для функции или класса

Описание

uopz_flags(string $function, int $flags = PHP_INT_MAX): int
uopz_flags(string $class, string $function, int $flags = PHP_INT_MAX): int

Получить или установить флаги для записи функции или класса во время выполнения

Список параметров

class

Имя класса

function

Имя функции. Если задан class и пустая строка передана как function, uopz_flags() получает или устанавливает флаги записи класса.

flags

Корректный набор флагов ZEND_ACC_. Если не заданы, uopz_flags() используется как геттер.

Возвращаемые значения

При установке новых флагов, возвращает старые флаги, иначе возвращает текущие флаги

Ошибки

Начиная с PHP 7.4.0, если передан параметр flags, uopz_extends() выбрасывает RuntimeException, если OPcache включён и запись класса либо class, либо parent (если это признак) неизменны.

Список изменений

Версия Описание
PECL uopz 5.0.0 Параметр flags теперь необязательный. Ранее ZEND_ACC_FETCH должен был передаваться, чтобы uopz_flags() использовался как геттер.

Примеры

Пример #1 Пример использования uopz_flags()

<?php
class Test {
public function
method() {
return
__CLASS__;
}
}

$flags = uopz_flags("Test", "method");

var_dump((bool) (uopz_flags("Test", "method") & ZEND_ACC_PRIVATE));
var_dump((bool) (uopz_flags("Test", "method") & ZEND_ACC_STATIC));

var_dump(uopz_flags("Test", "method", $flags|ZEND_ACC_STATIC|ZEND_ACC_PRIVATE));

var_dump((bool) (uopz_flags("Test", "method") & ZEND_ACC_PRIVATE));
var_dump((bool) (uopz_flags("Test", "method") & ZEND_ACC_STATIC));
?>

Результат выполнения данного примера:

bool(false)
bool(false)
int(1234567890)
bool(true)
bool(true)

Пример #2 "Отменить final" класса

<?php
final class MyClass
{
}

$flags = uopz_flags(MyClass::class, '');
uopz_flags(MyClass::class, '', $flags & ~ZEND_ACC_FINAL);
var_dump((new ReflectionClass(MyClass::class))->isFinal());
?>

Результат выполнения данного примера:

bool(false)


uopz_function

(PECL uopz 1, PECL uopz 2)

uopz_functionСоздаёт функцию во время выполнения

Внимание

Эта функция была УДАЛЕНА в PECL uopz 5.0.0.

Описание

uopz_function(string $function, Closure $handler, int $modifiers = ?): void
uopz_function(
    string $class,
    string $function,
    Closure $handler,
    int $modifiers = ?
): void

Создаёт функцию во время выполнения

Список параметров

class

Имя класса для получения новой функции

function

Имя функции

handler

Замыкание для функции

modifiers

Модификаторы для функции, по умолчанию скопированы или ZEND_ACC_PUBLIC

Возвращаемые значения

Примеры

Пример #1 Пример использования uopz_function()

<?php
uopz_function
("my_strlen", function($arg) {
return
strlen($arg);
});
echo
my_strlen("Привет, Мир");
?>

Результат выполнения данного примера:

11

Пример #2 Пример использования uopz_function() с классом

<?php
class My {}

uopz_function(My::class, "strlen", function($arg) {
return
strlen($arg);
},
ZEND_ACC_STATIC);

echo
My::strlen("Привет, Мир");
?>

Результат выполнения данного примера:

11


uopz_get_exit_status

(PECL uopz 5, PECL uopz , PECL uopz 7)

uopz_get_exit_statusПолучить последний установленный статус выхода

Описание

uopz_get_exit_status(): mixed

Получает последний установленный статус выхода, то есть значение, переданное в exit().

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Эта функция возвращает последний статус выхода или null, если exit() не был вызван.

Примеры

Пример #1 Пример использования uopz_get_exit_status()

<?php
exit(123);
echo
uopz_get_exit_status();?>

Результат выполнения данного примера:

123

Примечания

Предостережение

OPcache оптимизирует мёртвый код после безусловного завершения.

Смотрите также

  • uopz_allow_exit() - Позволяет управлять отключённым опкодом exit


uopz_get_hook

(PECL uopz 5, PECL uopz 6, PECL uopz 7)

uopz_get_hookПолучает ранее установленный обработчик на функцию или метод

Описание

uopz_get_hook(string $function): Closure
uopz_get_hook(string $class, string $function): Closure

Получает ранее установленный обработчик на функцию или метод.

Список параметров

class

Имя класса.

function

Имя функции или метода.

Возвращаемые значения

Возвращает ранее установленный обработчик на функцию или метод, либо null, если обработчик не был установлен.

Примеры

Пример #1 Простое использование uopz_get_hook()

<?php
function foo() {
echo
'foo';
}
uopz_set_hook('foo', function () {echo 'bar';});
var_dump(uopz_get_hook('foo'));
?>

Результатом выполнения данного примера будет что-то подобное:

object(Closure)#2 (0) {
}

Смотрите также

  • uopz_set_hook() - Устанавливает обработчик для выполнения при вызове функции или метода
  • uopz_unset_hook() - Удаляет ранее установленную функцию или метод


uopz_get_mock

(PECL uopz 5, PECL uopz 6, PECL uopz 7)

uopz_get_mockПолучить текущий имитатор (mock) для класса

Описание

uopz_get_mock(string $class): mixed

Возвращает текущий имитатор class.

Список параметров

class

Название имитированного класса

Возвращаемые значения

Либо строка, содержащая название имитатора, либо объект, либо null, если имитатор не задан.

Примеры

Пример #1 Пример использования uopz_get_mock()

<?php
class A {
public static function
who() {
echo
"A";
}
}

class
mockA {
public static function
who() {
echo
"mockA";
}
}

uopz_set_mock(A::class, mockA::class);
echo
uopz_get_mock(A::class);
?>

Результат выполнения данного примера:

mockA

Смотрите также

  • uopz_set_mock() - Использовать имитатор вместо класса для новых объектов
  • uopz_unset_mock() - Удалить ранее установленный имитатор


uopz_get_property

(PECL uopz 5, PECL uopz 6, PECL uopz 7)

uopz_get_propertyПолучает значение класса или свойство экземпляра

Описание

uopz_get_property(string $class, string $property): mixed
uopz_get_property(object $instance, string $property): mixed

Устанавливает значение существующего статического свойства класса, если указан класс (class), либо значение существующего свойства экземпляра, если передан экземпляр (instance).

Список параметров

class

Имя класса.

instance

Экземпляр объекта.

property

Имя свойства.

Возвращаемые значения

Возвращает значение класса или свойство экземпляра, либо null, если свойство не определено.

Примеры

Пример #1 Простое использование uopz_get_property()

<?php
class Foo {
private static
$staticBar = 10;
private
$bar = 100;
}
$foo = new Foo;
var_dump(uopz_get_property('Foo', 'staticBar'));
var_dump(uopz_get_property($foo, 'bar'));
?>

Результатом выполнения данного примера будет что-то подобное:

int(10)
int(100)

Смотрите также

  • uopz_set_property() - Устанавливает значение существующего свойства класса или экземпляра


uopz_get_return

(PECL uopz 5, PECL uopz 6, PECL uopz 7)

uopz_get_returnПолучает предыдущее установленное возвращаемое значение для функции

Описание

uopz_get_return(string $function): mixed
uopz_get_return(string $class, string $function): mixed

Получает возвращаемое значение function, ранее установленное с помощью uopz_set_return().

Список параметров

class

Имя класса, содержащего функцию

function

Имя функции

Возвращаемые значения

Ранее установленное возвращаемое значение или объект Closure.

Примеры

Пример #1 Пример использования uopz_get_return()

<?php
uopz_set_return
("strlen", 42);
echo
uopz_get_return("strlen");
?>

Результат выполнения данного примера:

42


uopz_get_static

(PECL uopz 5, PECL uopz 6, PECL uopz 7)

uopz_get_staticВозвращает статические переменные из области видимости функции или метода

Описание

uopz_get_static(string $class, string $function): array
uopz_get_static(string $function): array

Возвращает статические переменные из области видимости функции или метода.

Список параметров

class

Имя класса.

function

Имя функции или метода.

Возвращаемые значения

Возвращает ассоциативный массив (array) имён переменных, сопоставленный с их текущим значениям в случае успешного выполнения, либо null, если функция или метод не существуют.

Примеры

Пример #1 Простое использование uopz_get_static()

<?php
function foo() {
static
$bar = 'baz';
}
var_dump(uopz_get_static('foo'));
?>

Результат выполнения данного примера:

array(1) {
  ["bar"]=>
  string(3) "baz"
}

Смотрите также

  • uopz_set_static() - Устанавливает статические переменные в области видимости функции или метода


uopz_implement

(PECL uopz 1, PECL uopz 2, PECL uopz 5, PECL uopz 6, PECL uopz 7 < 7.1.0)

uopz_implementРеализует интерфейс во время выполнения

Описание

uopz_implement(string $class, string $interface): bool

Делает class, реализующий interface

Список параметров

class

interface

Возвращаемые значения

Возвращает true в случае успешного выполнения или false в случае возникновения ошибки.

Ошибки

Начиная с PHP 7.4.0, uopz_implements() выбрасывает RuntimeException, если OPcache включён и запись класса class неизменна.

Примеры

Пример #1 Пример использования uopz_implement()

<?php
interface myInterface {}

class
myClass {}

uopz_implement(myClass::class, myInterface::class);

var_dump(class_implements(myClass::class));
?>

Результат выполнения данного примера:

array(1) {
  ["myInterface"]=>
  string(11) "myInterface"
}


uopz_overload

(PECL uopz 1, PECL uopz 2)

uopz_overloadПерегрузить опкод VM

Внимание

Эта функция была УДАЛЕНА в PECL uopz 5.0.0.

Описание

uopz_overload(int $opcode, Callable $callable): void

Перегружает определённый opcode с помощью пользовательской функции

Список параметров

opcode

Корректный опкод, смотрите константы для получения поддерживаемых опкодов

callable

Возвращаемые значения

Примеры

Пример #1 Пример использования uopz_overload()

<?php
uopz_overload
(ZEND_EXIT, function(){});

exit();
echo
"Привет, Мир";
?>

Результат выполнения данного примера:

Привет, Мир


uopz_redefine

(PECL uopz 1, PECL uopz 2, PECL uopz 5, PECL uopz 6, PECL uopz 7)

uopz_redefineПереопределить константу

Описание

uopz_redefine(string $constant, mixed $value): bool
uopz_redefine(string $class, string $constant, mixed $value): bool

Переопределяет заданную константу constant на значение value

Список параметров

class

Имя класса, содержащего константу

constant

Имя константы

value

Новое значение константы, должно быть корректным типом для постоянной переменной

Возвращаемые значения

Возвращает true в случае успешного выполнения или false в случае возникновения ошибки.

Примеры

Пример #1 Пример использования uopz_redefine()

<?php
define
("MY", 100);

uopz_redefine("MY", 1000);

echo
MY;
?>

Результат выполнения данного примера:

1000


uopz_rename

(PECL uopz 1, PECL uopz 2)

uopz_renameПереименовать функцию во время выполнения

Внимание

Эта функция была УДАЛЕНА в PECL uopz 5.0.0.

Описание

uopz_rename(string $function, string $rename): void
uopz_rename(string $class, string $function, string $rename): void

Переименовывает функцию function на rename

Замечание:

Если обе функции существуют, эта функция по сути поменяет имена

Список параметров

class

Имя класса, содержащего функцию

function

Имя существующей функции

rename

Новое имя функции

Возвращаемые значения

Примеры

Пример #1 Пример использования uopz_rename()

<?php
uopz_rename
("strlen", "original_strlen");

echo
original_strlen("Hello World");
?>

Результатом выполнения данного примера будет что-то подобное:

11

Пример #2 Пример использования uopz_rename() с классом

<?php
class My {
public function
strlen($arg) {
return
strlen($arg);
}
}

uopz_rename(My::class, "strlen", "original_strlen");

echo
My::original_strlen("Hello World");
?>

Результат выполнения данного примера:

11


uopz_restore

(PECL uopz 1 >= 1.0.3, PECL uopz 2)

uopz_restoreВосстановить ранее зарезервированную функцию

Внимание

Эта функция была УДАЛЕНА в PECL uopz 5.0.0.

Описание

uopz_restore(string $function): void
uopz_restore(string $class, string $function): void

Восстановить ранее зарезервированную функцию

Список параметров

class

Имя класса, содержащего функцию для восстановления

function

Имя функции

Возвращаемые значения

Примеры

Пример #1 Пример использования uopz_restore()

<?php
uopz_backup
("fgets");
uopz_function("fgets", function(){
return
true;
});
var_dump(fgets());
uopz_restore('fgets');
fgets();
?>

Результатом выполнения данного примера будет что-то подобное:

Warning: fgets() expects at least 1 parameter, 0 given in /path/to/script.php on line 8


uopz_set_hook

(PECL uopz 5, PECL uopz 6, PECL uopz 7)

uopz_set_hookУстанавливает обработчик для выполнения при вызове функции или метода

Описание

uopz_set_hook(string $function, Closure $hook): bool
uopz_set_hook(string $class, string $function, Closure $hook): bool

Устанавливает обработчик для выполнения при вызове функции или метода.

Список параметров

class

Имя класса.

function

Имя функции или метода.

hook

Замыкание, выполняемое при вызове функции или метода.

Возвращаемые значения

Возвращает true в случае успешного выполнения или false в случае возникновения ошибки.

Примеры

Пример #1 Простое использование uopz_set_hook()

<?php
function foo() {
echo
'foo';
}
uopz_set_hook('foo', function () {echo 'bar';});
foo();
?>

Результат выполнения данного примера:

barfoo

Смотрите также

  • uopz_get_hook() - Получает ранее установленный обработчик на функцию или метод
  • uopz_unset_hook() - Удаляет ранее установленную функцию или метод


uopz_set_mock

(PECL uopz 5, PECL uopz 6, PECL uopz 7)

uopz_set_mockИспользовать имитатор вместо класса для новых объектов

Описание

uopz_set_mock(string $class, mixed $mock): void

Если mock - это строка, содержащая имя класса, тогда он будет создан вместо class. mock также может быть объектом.

Замечание:

Только динамический доступ к свойствам и методам будет использовать объект mock. Статический доступ будет использовать оригинальный class. Смотрите пример ниже.

Список параметров

class

Имя класса, который будет имитирован.

mock

Имитатор в виде строки, содержащей имя используемого класса, либо объект. Если передана строка, она должна быть содержать абсолютное имя класса. В этом случае рекомендуется использовать магическую константу ::class.

Возвращаемые значения

Функция не возвращает значения после выполнения.

Список изменений

Версия Описание
uopz 6.0.0 Имитирование статических функций более не поддерживаются этой функцией. Вместо это го следует использовать uopz_redefine() и uopz_set_return(), или Componere.

Примеры

Пример #1 Пример использования uopz_set_mock()

<?php
class A {
public function
who() {
echo
"A";
}
}

class
mockA {
public function
who() {
echo
"mockA";
}
}

uopz_set_mock(A::class, mockA::class);
(new
A)->who();
?>

Результат выполнения данного примера:

mockA

Пример #2 Пример использования uopz_set_mock()

<?php
class A {
public function
who() {
echo
"A";
}
}

uopz_set_mock(A::class, new class {
public function
who() {
echo
"mockA";
}
});
(new
A)->who();
?>

Результат выполнения данного примера:

mockA

Пример #3 uopz_set_mock() и статические члены класса

Начиная с uopz 6.0.0, имитация статических членов класса не поддерживается.

<?php
class A {
public static function
who() {
echo
"A";
}
}

uopz_set_mock(A::class, new class {
const
CON = 'mockA';
public static function
who() {
echo
"mockA";
}
});
echo
A::CON, PHP_EOL;
A::who();

Результат выполнения данного примера:

A
A

Вывод примера в uopz 5:

mockA
mockA

Смотрите также

  • uopz_get_mock() - Получить текущий имитатор (mock) для класса
  • uopz_unset_mock() - Удалить ранее установленный имитатор


uopz_set_property

(PECL uopz 5, PECL uopz 6, PECL uopz 7)

uopz_set_propertyУстанавливает значение существующего свойства класса или экземпляра

Описание

uopz_set_property(string $class, string $property, mixed $value): void
uopz_set_property(object $instance, string $property, mixed $value): void

Задаёт значение существующего статического свойства класса, если задан класс (class), либо значение существующего свойства экземпляра (вне зависимости от того, существует ли свойство экземпляра), если передан экземпляр (instance).

Список параметров

class

Имя класса.

instance

Экземпляр объекта.

property

Имя свойства.

value

Значение, присваиваемое свойству.

Возвращаемые значения

Функция не возвращает значения после выполнения.

Примеры

Пример #1 Простое использование uopz_set_property()

<?php
class Foo {
private static
$staticBar;
private
$bar;
public static function
testStaticBar() {
return
self::$staticBar;
}
public function
testBar() {
return
$this->bar;
}
}
$foo = new Foo;
uopz_set_property('Foo', 'staticBar', 10);
uopz_set_property($foo, 'bar', 100);
var_dump(Foo::testStaticBar());
var_dump($foo->testBar());
?>

Результат выполнения данного примера:

int(10)

Смотрите также

  • uopz_get_property() - Получает значение класса или свойство экземпляра


uopz_set_return

(PECL uopz 5, PECL uopz 6, PECL uopz 7)

uopz_set_returnПредоставить возвращаемое значение для существующей функции

Описание

uopz_set_return(string $function, mixed $value, bool $execute = false): bool
uopz_set_return(
    string $class,
    string $function,
    mixed $value,
    bool $execute = false
): bool

Установить возвращаемое значение для function на value. Если value замыкание и установлен execute, замыкание будет выполняться вместо исходной функции. Можно вызвать исходную функцию из замыкания.

Замечание:

Эта функция заменяет uopz_rename().

Список параметров

class

Имя класса, содержащего функцию

function

Имя существующей функции

value

Возвращаемое значение функцией. Если передано замыкание и параметр execute установлен, замыкание будет выполнено вместо исходной функции.

execute

Если true, и в параметре value передано замыкание, замыкание будет выполнено вместо исходной функции.

Возвращаемые значения

True в случае успешного выполнения, false в противном случае.

Примеры

Пример #1 Пример использования uopz_set_return()

<?php
uopz_set_return
("strlen", 42);
echo
strlen("Banana");
?>

Результат выполнения данного примера:

42

Пример #2 Пример использования uopz_set_return()

<?php
uopz_set_return
("strlen", function($str) { return strlen($str) * 2; }, true );
echo
strlen("Banana");
?>

Результат выполнения данного примера:

12

Пример #3 Пример использования uopz_set_return() с классом

<?php
class My {
public static function
strlen($arg) {
return
strlen($arg);
}
}
uopz_set_return(My::class, "strlen", function($str) { return strlen($str) * 2; }, true );
echo
My::strlen("Banana");
?>

Результат выполнения данного примера:

12


uopz_set_static

(PECL uopz 5, PECL uopz , PECL uopz 7)

uopz_set_staticУстанавливает статические переменные в области видимости функции или метода

Описание

uopz_set_static(string $function, array $static): void
uopz_set_static(string $class, string $function, array $static): void

Устанавливает статические переменные в области видимости функции или метода.

Список параметров

class

Имя класса.

function

Имя функции или метода.

static

Ассоциативный массив (array) имён переменных, сопоставленных с их значениями.

Возвращаемые значения

Функция не возвращает значения после выполнения.

Примеры

Пример #1 Простое использование uopz_set_static()

<?php
function foo() {
static
$bar = 'baz';
var_dump($bar);
}
uopz_set_static('foo', ['bar' => 'qux']);
foo();
?>

Результат выполнения данного примера:

string(3) "qux"

Смотрите также

  • uopz_get_static() - Возвращает статические переменные из области видимости функции или метода


uopz_undefine

(PECL uopz 1, PECL uopz 2, PECL uopz 5, PECL uopz 6, PECL uopz 7)

uopz_undefineОтменяет определение константы

Описание

uopz_undefine(string $constant): bool
uopz_undefine(string $class, string $constant): bool

Удаляет константу во время выполнения

Список параметров

class

Название класса, содержащего constant

constant

Имя существующей константы

Возвращаемые значения

Возвращает true в случае успешного выполнения или false в случае возникновения ошибки.

Примеры

Пример #1 Пример использования uopz_undefine()

<?php
define
("MY", true);

uopz_undefine("MY");

var_dump(defined("MY"));
?>

Результат выполнения данного примера:

bool(false)


uopz_unset_hook

(PECL uopz 5, PECL uopz 6, PECL uopz 7)

uopz_unset_hookУдаляет ранее установленную функцию или метод

Описание

uopz_unset_hook(string $function): bool
uopz_unset_hook(string $class, string $function): bool

Удаляет ранее установленную функцию или метод.

Список параметров

class

Имя класса.

function

Имя функции или метода.

Возвращаемые значения

Возвращает true в случае успешного выполнения или false в случае возникновения ошибки.

Примеры

Пример #1 Простое использование uopz_unset_hook()

<?php
function foo() {
echo
'foo';
}
uopz_set_hook('foo', function () {echo 'bar';});
foo();
echo
PHP_EOL;
uopz_unset_hook('foo');
foo();
?>

Результат выполнения данного примера:

barfoo
foo

Смотрите также

  • uopz_set_hook() - Устанавливает обработчик для выполнения при вызове функции или метода
  • uopz_get_hook() - Получает ранее установленный обработчик на функцию или метод


uopz_unset_mock

(PECL uopz 5, PECL uopz 6, PECL uopz 7)

uopz_unset_mockУдалить ранее установленный имитатор

Описание

uopz_unset_mock(string $class): void

Удаляет ранее установленный имитатор для class.

Список параметров

class

Имя имитированного класса.

Возвращаемые значения

Функция не возвращает значения после выполнения.

Ошибки

Выбрасывает RuntimeException, если ранее не был задан имитатор для class.

Примеры

Пример #1 Пример использования uopz_unset_mock()

<?php
class A {
public static function
who() {
echo
"A";
}
}

class
mockA {
public static function
who() {
echo
"mockA";
}
}

uopz_set_mock(A::class, mockA::class);
uopz_unset_mock(A::class);
A::who();
?>

Результат выполнения данного примера:

A

Смотрите также

  • uopz_set_mock() - Использовать имитатор вместо класса для новых объектов
  • uopz_get_mock() - Получить текущий имитатор (mock) для класса


uopz_unset_return

(PECL uopz 5, PECL uopz 6, PECL uopz 7)

uopz_unset_returnОтменяет ранее установленное возвращаемое значение для функции

Описание

uopz_unset_return(string $function): bool
uopz_unset_return(string $class, string $function): bool

Отменяет возвращаемое значение function, ранее заданное функцией uopz_set_return().

Список параметров

class

Имя класса, содержащего функцию

function

Имя функции

Возвращаемые значения

True в случае успешного выполнения

Примеры

Пример #1 Пример использования uopz_unset_return()

<?php
uopz_set_return
("strlen", 42);
$len = strlen("Banana");
uopz_unset_return("strlen");
echo
$len + strlen("Banana");
?>

Результат выполнения данного примера:

48

Содержание

  • uopz_add_function — Добавляет несуществующую функцию или метод
  • uopz_allow_exit — Позволяет управлять отключённым опкодом exit
  • uopz_backup — Резервирует функцию
  • uopz_compose — Составить класс
  • uopz_copy — Скопировать функцию
  • uopz_del_function — Удаляет ранее добавленную функцию или метод
  • uopz_delete — Удалить функцию
  • uopz_extend — Расширить класс во время выполнения
  • uopz_flags — Получить или установить флаги для функции или класса
  • uopz_function — Создаёт функцию во время выполнения
  • uopz_get_exit_status — Получить последний установленный статус выхода
  • uopz_get_hook — Получает ранее установленный обработчик на функцию или метод
  • uopz_get_mock — Получить текущий имитатор (mock) для класса
  • uopz_get_property — Получает значение класса или свойство экземпляра
  • uopz_get_return — Получает предыдущее установленное возвращаемое значение для функции
  • uopz_get_static — Возвращает статические переменные из области видимости функции или метода
  • uopz_implement — Реализует интерфейс во время выполнения
  • uopz_overload — Перегрузить опкод VM
  • uopz_redefine — Переопределить константу
  • uopz_rename — Переименовать функцию во время выполнения
  • uopz_restore — Восстановить ранее зарезервированную функцию
  • uopz_set_hook — Устанавливает обработчик для выполнения при вызове функции или метода
  • uopz_set_mock — Использовать имитатор вместо класса для новых объектов
  • uopz_set_property — Устанавливает значение существующего свойства класса или экземпляра
  • uopz_set_return — Предоставить возвращаемое значение для существующей функции
  • uopz_set_static — Устанавливает статические переменные в области видимости функции или метода
  • uopz_undefine — Отменяет определение константы
  • uopz_unset_hook — Удаляет ранее установленную функцию или метод
  • uopz_unset_mock — Удалить ранее установленный имитатор
  • uopz_unset_return — Отменяет ранее установленное возвращаемое значение для функции

  • Введение
  • Установка и настройка
  • Предопределённые константы
  • Функции Uopz
    • uopz_add_function — Добавляет несуществующую функцию или метод
    • uopz_allow_exit — Позволяет управлять отключённым опкодом exit
    • uopz_backup — Резервирует функцию
    • uopz_compose — Составить класс
    • uopz_copy — Скопировать функцию
    • uopz_del_function — Удаляет ранее добавленную функцию или метод
    • uopz_delete — Удалить функцию
    • uopz_extend — Расширить класс во время выполнения
    • uopz_flags — Получить или установить флаги для функции или класса
    • uopz_function — Создаёт функцию во время выполнения
    • uopz_get_exit_status — Получить последний установленный статус выхода
    • uopz_get_hook — Получает ранее установленный обработчик на функцию или метод
    • uopz_get_mock — Получить текущий имитатор (mock) для класса
    • uopz_get_property — Получает значение класса или свойство экземпляра
    • uopz_get_return — Получает предыдущее установленное возвращаемое значение для функции
    • uopz_get_static — Возвращает статические переменные из области видимости функции или метода
    • uopz_implement — Реализует интерфейс во время выполнения
    • uopz_overload — Перегрузить опкод VM
    • uopz_redefine — Переопределить константу
    • uopz_rename — Переименовать функцию во время выполнения
    • uopz_restore — Восстановить ранее зарезервированную функцию
    • uopz_set_hook — Устанавливает обработчик для выполнения при вызове функции или метода
    • uopz_set_mock — Использовать имитатор вместо класса для новых объектов
    • uopz_set_property — Устанавливает значение существующего свойства класса или экземпляра
    • uopz_set_return — Предоставить возвращаемое значение для существующей функции
    • uopz_set_static — Устанавливает статические переменные в области видимости функции или метода
    • uopz_undefine — Отменяет определение константы
    • uopz_unset_hook — Удаляет ранее установленную функцию или метод
    • uopz_unset_mock — Удалить ранее установленный имитатор
    • uopz_unset_return — Отменяет ранее установленное возвращаемое значение для функции


Windows Cache для PHP


Введение

Windows Cache Extension для PHP - это кеширующий модуль, позволяющий увеличить скорость работы PHP-приложений на Windows и Windows Server. Как только вы включаете Windows Cache Extension и он загружается движком PHP, приложения начинают получать все его преимущества без необходимости менять их код.

Модуль включает 5 различных типов кешей. Далее рассказывается про назначение и преимущества каждого типа кеша.

  • PHP Opcode Cache - PHP является скриптовым языком, который читает входящий поток данных, содержащий текст и/или инструкции языка и выдаёт новый поток данных, обычно в формате HTML. Т.е. на стороне веб-сервера, PHP читает, разбирает, компилирует и запускает PHP-скрипт каждый раз, когда его запрашивает клиент. Чтение, разбор и компиляция создают дополнительную нагрузку на процессорные ядра и файловую систему сервера, что сказывается на конечной производительности приложения. Кеширование байт-кода (опкода) PHP позволяет держать уже скомпилированный код в разделяемой памяти и использовать его при следующих запросах к тому же скрипту.

    Поддержка кеширования опкодов была удалена в Wincache 2.0.0. Так что если она вам нужна, то следует использовать модуль OPcache, который включён в PHP.

  • File Cache - даже если включено кеширование опкодов, PHP всё равно обращается к файлам на файловой системе. Когда PHP-скрипт размещён в удалённой файловой папке, файловые операции значительно снижают производительность. Windows Cache Extension включает файловое кеширование, которое используется для сохранения контента скриптов в разделяемой памяти, что сильно сокращает количество операций доступа к файловой системе для PHP.

  • Resolve File Path Cache - скрипты PHP довольно часто включают или оперируют файлами, используя относительные пути. Каждый такой путь сначала нормализуется PHP до абсолютного пути. Когда приложение использует большое количество файлов и обращается к ним по относительным путям, операции выведения абсолютных путей могут негативно сказаться на производительности. Модуль Windows Cache Extension предоставляет инструмент кеширования Resolve File Path, который используется для сохранения сопоставления относительных и абсолютных файловых путей, позволяя снизить количество операций их выведения.

  • User Cache (доступно с версии 1.1.0) - скрипты PHP могут получить преимущества кеширования в разделяемой памяти посредством API пользовательского кеширования. Объекты и переменные PHP могут быть сохранены в пользовательском кеше и переиспользованы в последующих запросах. Это может как повысить производительность приложения, так и разделить данные между несколькими процессами PHP.

  • Session Handler (доступно с версии 1.1.0) - обработчик сессий WinCache может быть использован для сохранения данных сессии в кеше в разделяемой памяти. Это позволяет избежать дисковых операций при записи и чтении данных сессии, что может сильно увеличить производительность, если таких данных много.



Установка и настройка

Содержание


Требования

В данный момент модуль поддерживается только для следующих конфигураций:

Windows OS:

  • Windows XP SP3 с IIS 5.1 и » FastCGI Extension
  • Windows Server 2003 с IIS 6.0 и » FastCGI Extension
  • Windows Vista SP1 с IIS 7.0 и FastCGI Module
  • Windows Server 2008 с IIS 7.0 и FastCGI Module
  • Windows 7 с IIS 7.5 и FastCGI Module
  • Windows Server 2008 R2 с IIS 7.5 и FastCGI Module

PHP:

  • PHP 5.2.X, не потокобезопасная сборка
  • PHP 5.3 X86, не потокобезопасная VC9 сборка

Замечание: Модуль WinCache может использоваться только если IIS настроен использовать PHP через FastCGI.



Установка

Этот модуль » PECL не поставляется вместе с PHP.

Информация по установке этого модуля PECL может быть найдена в главе руководства Установка PECL модулей. Дополнительная информация, такая как новые версии, скачивание, исходные файлы, информация о разработчике и CHANGELOG, может быть найдена здесь: » https://pecl.php.net/package/wincache.

Существует два пакета для этого модуля: один пакет для PHP 5.2.X, а другой для PHP 5.3.X. Выбор необходимого пакета зависит от вашей версии PHP.

Для установки и включения модуля следуйте следующей инструкции:

  1. Разархивируйте пакет во временную папку.

  2. Скопируйте php_wincache.dll в каталог с модулями PHP. Обычно этот каталог называется "ext" и расположен там же, где установлен PHP. К примеру: C:\Program Files\PHP\ext.

  3. Используя текстовый редактор откройте файл php.ini, который обычно лежит там же, где установлен PHP. К примеру: C:\Program Files\PHP\php.ini.

  4. Добавьте в конец файла строку: extension = php_wincache.dll.

  5. Сохраните и закройте файл php.ini.

  6. Пересоздайте пул приложений IIS для того, чтобы изменения вступили в силу. Для проверки того, что модуль включён, создайте файл phpinfo.php с кодом, вызывающим функцию PHP phpinfo.

  7. Сохраните phpinfo.php в корневом каталоге веб-сайта и обратитесь к нему через веб-браузер по следующей ссылке http://localhost/phpinfo.php. Найдите в выводе секцию wincache. Если модуль включён, то функция phpinfo покажет список конфигурационных параметров WinCache.

Замечание: Не забудьте удалить файл phpinfo.php после того, как он перестанет быть нужен.



Настройка во время выполнения

Поведение этих функций зависит от установок в php.ini.

В таблице представлен список конфигурационных параметров модуля WinCache:

Конфигурационные параметры WinCache
Имя По умолчанию Минимум Максимум Место изменения Список изменений
wincache.fcenabled "1" "0" "1" PHP_INI_ALL Доступно с WinCache 1.0.0
wincache.fcenabledfilter "NULL" "NULL" "NULL" PHP_INI_SYSTEM Доступно с WinCache 1.0.0
wincache.fcachesize "24" "5" "255" PHP_INI_SYSTEM Доступно с WinCache 1.0.0
wincache.fcndetect "1" "0" "1" PHP_INI_SYSTEM Доступно с WinCache 1.1.0
wincache.maxfilesize "256" "10" "2048" PHP_INI_SYSTEM Доступно с WinCache 1.0.0
wincache.ocenabled "1" "0" "1" PHP_INI_ALL Доступно с WinCache 1.0.0. Удалено в 2.0.0.0
wincache.ocenabledfilter "NULL" "NULL" "NULL" PHP_INI_SYSTEM Доступно с WinCache 1.0.0. Удалено в 2.0.0.0
wincache.ocachesize "96" "15" "255" PHP_INI_SYSTEM Доступно с WinCache 1.0.0. Удалено в 2.0.0.0
wincache.filecount "4096" "1024" "16384" PHP_INI_SYSTEM Доступно с WinCache 1.0.0
wincache.chkinterval "30" "0" "300" PHP_INI_SYSTEM Доступно с WinCache 1.0.0
wincache.ttlmax "1200" "0" "7200" PHP_INI_SYSTEM Доступно с WinCache 1.0.0
wincache.enablecli 0 0 1 PHP_INI_SYSTEM Доступно с WinCache 1.0.0
wincache.ignorelist NULL NULL NULL PHP_INI_ALL Доступно с WinCache 1.0.0
wincache.namesalt NULL NULL NULL PHP_INI_SYSTEM Доступно с WinCache 1.0.0
wincache.ucenabled 1 0 1 PHP_INI_SYSTEM Доступно с WinCache 1.1.0
wincache.ucachesize 8 5 85 PHP_INI_SYSTEM Доступно с WinCache 1.1.0
wincache.scachesize 8 5 85 PHP_INI_SYSTEM Доступно с WinCache 1.1.0
wincache.rerouteini NULL NULL NULL PHP_INI_SYSTEM Доступно с WinCache 1.2.0. Удалено в 1.3.7
wincache.reroute_enabled 1 0 1 PHP_INI_SYSTEM | PHP_INI_PERDIR Доступно с WinCache 1.3.7
wincache.srwlocks 1 0 1 PHP_INI_SYSTEM Доступно с WinCache 1.3.6.3. Удалено в 2.0.0.0
wincache.filemapdir NULL NULL NULL PHP_INI_SYSTEM Доступно с WinCache 1.3.7.4
Для подробного описания констант PHP_INI_*, обратитесь к разделу Где могут быть установлены параметры конфигурации.

Краткое разъяснение конфигурационных директив.

wincache.fcenabled bool
Включает/отключает файловое кеширование.
wincache.fcenabledfilter string
Определяет список идентификаторов IIS веб-серверов, разделённых запятой, для которых должно быть разрешено/запрещено файловое кеширование. Эта настройка работает в паре с wincache.fcenabled: если wincache.fcenabled установлено в 1, то для серверов, перечисленных в wincache.fcenabledfilter файловое кеширование будет отключено; если wincache.fcenabled установлено как 0, то для серверов, перечисленных в wincache.fcenabledfilter файловое кеширование будет включено.
wincache.fcachesize int
Определяет максимальный размер памяти (в мегабайтах) для файлового кеша. Когда размер всех закешированных файлов превысит это значение, из кеша будут удалены самые устаревшие файлы.
wincache.fcndetect bool
Включает/отключает функциональность оповещения об изменении файла. Если функционал оповещения об изменениях файла поддерживается, то он может быть использован для обновления кеша опкодов и файлового кеша при получении соответствующих оповещений. Если подобный механизм не поддерживается, например, при использовании сетевых папок, wincache будет самостоятельно проверять файлы на предмет изменения через заданные в настройке wincache.chkinterval интервалы времени.
wincache.maxfilesize int
Определяет максимальный размер одного файла (в килобайтах) для файлового кеша. Если размер файла превышает заданное значение, то он не будет закеширован. Данная настройка применяется только к файловому кешу.
wincache.ocenabled bool
Внимание

Эта опция была УДАЛЕНА в версии 2.0.0.0

Включает/отключает кеширование опкодов
wincache.ocenabledfilter string
Внимание

Эта опция была УДАЛЕНА в версии 2.0.0.0

Определяет список идентификаторов IIS веб-серверов, разделённых запятой, для которых должно быть разрешено/запрещено кеширование опкодов. Эта настройка работает в паре с wincache.ocenabled: если wincache.ocenabled установлено в 1, то для серверов, перечисленных в wincache.ocenabledfilter файловое кеширование будет отключено; если wincache.ocenabled установлено как 0, то для серверов, перечисленных в wincache.ocenabledfilter файловое кеширование будет разрешено.
wincache.ocachesize int
Внимание

Эта опция была УДАЛЕНА в версии 2.0.0.0

Определяет максимальный размер памяти (в мегабайтах) для кеша опкодов. Когда размер всех закешированных опкодов превысит это значение, из кеша будут удалены самые устаревшие из них. Обратите внимание, что кеш опкодов должен быть как минимум в 3 раза больше файлового кеша. Если это не так, то размер кеша опкодов будет автоматически увеличен.
wincache.filecount int
Определяет, сколько примерно файлов будет закешировано модулем, чтобы при старте был выделен соответствующий кусок памяти. Если количество файлов превысит заданное значение, то WinCache произведёт переаллокацию памяти.
wincache.chkinterval int
Определяет насколько часто (в секундах) модуль будет проверять файлы на предмет их изменения для обновления кешей. Значение 0 отключает данный функционал. Изменения файлов не будут отражены в кеше до тех пор, пока закешированная запись не будет удалена из кеша сборщиком устаревших записей, либо пока не будет переработан пул приложений IIS, либо не будет вызвана функция wincache_refresh_if_changed.
wincache.ttlmax int
Определяет максимальное время (в секундах) невостребованности для записи в кеше. Установка в 0 отключает процесс удаления устаревших записей, что приведёт к тому, что запись будет лежать в кеше пока сервер IIS не будет остановлен.
wincache.enablecli bool
Определяет, разрешено ли кеширование при работе PHP из командной строки (CLI).
wincache.ignorelist string

Определяет список файлов, которые не нужно кешировать. Указываются только имена файлов. Символ разделитель - вертикальная черта "|".

Пример #1 Пример использования wincache.ignorelist

wincache.ignorelist = "index.php|misc.php|admin.php"

wincache.namesalt string
Определяет строку, которая будет использоваться при именовании объектов, помещаемых в разделяемую память. Это необходимо для предотвращения коллизий, когда несколько процессов работают с разделяемой памятью. Длина данной строки не должна превышать 8 символов.
wincache.ucenabled bool
Включает/отключает пользовательский кеш.
wincache.ucachesize int
Определяет максимальный размер памяти (в мегабайтах) для пользовательского кеша. Когда размер всех закешированных переменных превысит это значение, из кеша будут удалены самые устаревшие переменные.
wincache.scachesize int
Определяет максимальный размер памяти (в мегабайтах) для сессионного кеша. Когда размер всех закешированных данных превысит это значение, из кеша будут удалены самые устаревшие данные.
wincache.rerouteini string
Внимание

Эта опция была УДАЛЕНА в версии 1.3.7. Начиная с 1.3.7. вместо неё используйте wincache.reroute_enabled.

Задаёт абсолютный или относительный путь к reroute.ini, который содержит список функций PHP, чья реализация должна быть подменена реализацией из модуля WinCache. Если задан относительный путь, то он будет разрешаться относительно местоположения файла php-cgi.exe.
wincache.reroute_enabled bool
Включает/отключает перенаправление некоторых функций файлового ввода/вывода для работы через файловый кеш.
wincache.srwlocks bool
Внимание

Эта опция была УДАЛЕНА в версии 2.0.0.0

Включает/отключает использование разделяемых блокировок чтения/записи. Выключение полезно при отладке ситуаций взаимных блокировок в WinCache.
wincache.filemapdir string
Задаёт абсолютный путь к директории, где WinCache будет держать временные файлы для сегментов разделяемой памяти. Эта директория должна располагаться на локальной машине и ни в коем случае не на сетевой файловой системе. Если директория не указана, то WinCache будет использовать Windows System Page File.



Скрипт статистики WinCache

Установочный пакет WinCache содержит PHP-скрипт, wincache.php, который можно использовать для получения статистики использования кеша.

Если модуль WinCache был установлен с помощью Microsoft Web Platform Installer, то скрипт будет располагаться по пути %SystemDrive%\Program Files\IIS\Windows Cache for PHP\. На 64-разрядных версиях Windows Server, скрипт лежит по пути %SystemDrive%\Program Files (x86)\IIS\Windows Cache for PHP. Если модуль устанавливался самостоятельно, то wincache.php будет лежать в том же каталоге, в который вы распаковывали установочный пакет.

Для использования wincache.php, скопируйте его в корневой каталог веб-сайта или в любой его подкаталог. Для защиты скрипта, откройте его в текстовом редакторе и измените значения констант USERNAME и PASSWORD. Если для аутентификации в IIS используется другой механизм, то следуйте инструкциям в комментариях:

Пример #1 Настройка аутентификации для wincache.php

<?php
/**
* ======================== CONFIGURATION SETTINGS ==============================
* If you do not want to use authentication for this page, set USE_AUTHENTICATION to 0.
* If you use authentication then replace the default password.
*/
define('USE_AUTHENTICATION', 1);
define('USERNAME', 'wincache');
define('PASSWORD', 'wincache');

/**
* The Basic PHP authentication will work only when IIS is configured to support
* Anonymous Authentication' and nothing else. If IIS is configured to support/use
* any other kind of authentication like Basic/Negotiate/Digest etc, this will not work.
* In that case use the array below to define the names of users in your
* domain/network/workgroup which you want to grant access to.
*/
$user_allowed = array('DOMAIN\user1', 'DOMAIN\user2', 'DOMAIN\user3');

/**
* If the array contains string 'all', then all the users authenticated by IIS
* will have access to the page. Uncomment the below line and comment above line
* to grant access to all users who gets authenticated by IIS.
*/
/* $user_allowed = array('all'); */

/** ===================== END OF CONFIGURATION SETTINGS ========================== */
?>

Замечание: Всегда защищайте скрипт wincache.php с помощью встроенного механизма, либо с помощью механизма аутентификации веб-сервера. Оставляя доступ к скрипту открытым вы можете скомпрометировать ваше приложение и веб-сервер.



Обработчик сессий WinCache

Обработчик сессий WinCache (доступен с WinCache 1.1.0) может использоваться для хранения данных сессий в кеше в разделяемой памяти. Использование памяти вместо файловой системы поможет улучшить производительность вашего приложения, если оно сохраняет большое количество сессионных данных. Кеш сессий Wincache использует дублирование данных на диске, что позволяет сохранить сессионные данные при пересоздании пула приложений IIS.

Для настройки использования обработчика сессий WinCache измените в файле php.ini настройку session.save_handler на wincache. По умолчанию, для хранения данных сессий используется временная директория Windows. Для изменения пути к сессионному файлу используйте настройку session.save_path.

Пример #1 Включение обработчика сессий WinCache

session.save_handler = wincache
session.save_path = C:\inetpub\temp\session\



Перенаправление функций WinCache

ОБРАТИТЕ ВНИМАНИЕ: wincache.rerouteini удалена в WinCache 1.3.7.0. Она была заменена автоматическим перенаправлением. Смотрите wincache.reroute_enabled.

Перенаправление функций WinCache (доступно с WinCache 1.2.0, удалено с WinCache 1.3.7.0) может использоваться для замены встроенных функций их эквивалентами, оптимизированными для работы с файловым кешем. Модуль WinCache включает оптимизированные под Windows реализации функций работы с файлами, что может повысить производительность PHP-приложений в случаях работы с файлами и сетевыми папками. Оптимизированные версии представлены для следующих функций:

Для настройки использования перенаправления в WinCache используется файл reroute.ini, который включён в установочный пакет. Скопируйте этот файл в ту же директорию, где находится php.ini. После этого добавьте в php.ini настройку wincache.rerouteini и укажите абсолютный или относительный путь к reroute.ini.

Пример #1 Включение перенаправления функций в WinCache

wincache.rerouteini = C:\PHP\reroute.ini

Замечание: Если перенаправление функций включено, то рекомендуется увеличить размер файлового кеша WinCache. Его размер настраивается в директиве wincache.fcachesize.

Файл reroute.ini содержит описание привязок встроенных функций PHP к их эквивалентам модуля WinCache. Каждая строка файла определяет привязку с использованием следующего синтаксиса:

<Имя функции PHP>:[<количество параметров функции>]=<имя функции wincache>

Пример файла приведён ниже. В этом примере вызов PHP-функции file_get_contents() подменяется вызовом функции wincache_file_get_contents() только если количество переданных параметров меньше или равно 2. Указание количества параметров полезно если подменяющая функция реализует обработку не всех исходных параметров.

Пример #2 Содержимое файла Reroute.ini

[FunctionRerouteList]
file_exists=wincache_file_exists
file_get_contents:2=wincache_file_get_contents
readfile:2=wincache_readfile
is_readable=wincache_is_readable
is_writable=wincache_is_writable
is_writeable=wincache_is_writable
is_file=wincache_is_file
is_dir=wincache_is_dir
realpath=wincache_realpath
filesize=wincache_filesize



Типы ресурсов

Данный модуль не определяет каких-либо типов ресурсов.




Предопределённые константы

Данный модуль не определяет никакие константы.



Функции WinCache


wincache_fcache_fileinfo

(PECL wincache >= 1.0.0)

wincache_fcache_fileinfoПолучает информацию о файлах, закешированных в файловом кеше

Описание

wincache_fcache_fileinfo(bool $summaryonly = false): array|false

Получает информацию о содержимом файлового кеша и его использовании.

Список параметров

summaryonly

Определяет, будет ли возвращаемый массив содержать информацию об отдельных записях кеша вместе со сводкой файлового кеша.

Возвращаемые значения

Массив метаданных о файловом кеше или false в случае возникновения ошибки.

Массив, возвращаемый этой функцией, содержит следующие элементы:

  • total_cache_uptime - общее время в секундах, в течение которого файловый кеш был активен
  • total_file_count - общее количество файлов, которые в данный момент находятся в файловом кеше
  • total_hit_count - количество раз, когда файлы обслуживались из файлового кеша
  • total_miss_count - количество раз, когда файлы не были найдены в файловом кеше
  • file_entries - массив, содержащий информацию обо всех закешированных файлах:

    • file_name - абсолютное имя закешированного файла
    • add_time - время в секундах с момента добавления файла в кеш
    • use_time - время в секундах с момента обращения к файлу в кеше
    • last_check - время в секундах с момента проверки файла на наличие модификаций
    • hit_count - количество раз, когда файл был обработан из кеша
    • file_size - размер кешируемого файла в байтах

Примеры

Пример #1 Пример использования wincache_fcache_fileinfo()

<pre>
<?php
print_r
(wincache_fcache_fileinfo());
?>
</pre>

Результат выполнения данного примера:

Array
(   [total_cache_uptime] => 3234
    [total_file_count] => 5
    [total_hit_count] => 0
    [total_miss_count] => 1
    [file_entries] => Array
        (
            [1] => Array
                (
                    [file_name] => c:\inetpub\wwwroot\checkcache.php
                    [add_time] => 1
                    [use_time] => 0
                    [last_check] => 1
                    [hit_count] => 1
                    [file_size] => 2435
                )
            [2] => Array (...iterates for each cached file)
        )
)

Смотрите также

  • wincache_fcache_meminfo() - Получает информацию об использовании памяти файлового кеша
  • wincache_ocache_fileinfo() - Получает информацию о файлах, закешированных в кеше опкодов
  • wincache_ocache_meminfo() - Получает информацию об использовании кеш-памяти опкодов
  • wincache_rplist_fileinfo() - Получает информацию о разрешении кеша пути к файлу разрешения
  • wincache_rplist_meminfo() - Получает информацию об использовании памяти с помощью кеша пути к файлу разрешения
  • wincache_refresh_if_changed() - Обновляет записи кеша для закешированных файлов
  • wincache_ucache_meminfo() - Получает информацию об использовании памяти пользовательского кеша
  • wincache_ucache_info() - Получает информацию о данных, хранящихся в пользовательском кеше
  • wincache_scache_info() - Получает информацию о файлах, закешированных в кеше сессии
  • wincache_scache_meminfo() - Получает информацию об использовании кеш-памяти сессии



wincache_fcache_meminfo

(PECL wincache >= 1.0.0)

wincache_fcache_meminfo Получает информацию об использовании памяти файлового кеша

Описание

wincache_fcache_meminfo(): array|false

Получает информацию об использовании памяти файлового кеша.

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Массив метаданных об использовании памяти файлового кеша или false в случае возникновения ошибки

Массив, возвращаемый этой функцией, содержит следующие элементы:

  • memory_total - объем памяти в байтах, выделенный для файлового кеша
  • memory_free - объем свободной памяти в байтах, доступной для файлового кеша
  • num_used_blks - количество блоков памяти, используемых файловым кешем
  • num_free_blks - количество свободных блоков памяти, доступных для файлового кеша
  • memory_overhead - объем памяти в байтах, используемый для внутренних структур файлового кеша

Примеры

Пример #1 Пример использования wincache_fcache_meminfo()

<pre>
<?php
print_r
(wincache_fcache_meminfo());
?>
</pre>

Результат выполнения данного примера:

Array
(
    [memory_total] => 134217728
    [memory_free] => 131339120
    [num_used_blks] => 361
    [num_free_blks] => 3
    [memory_overhead] => 5856
)

Смотрите также

  • wincache_fcache_fileinfo() - Получает информацию о файлах, закешированных в файловом кеше
  • wincache_ocache_fileinfo() - Получает информацию о файлах, закешированных в кеше опкодов
  • wincache_ocache_meminfo() - Получает информацию об использовании кеш-памяти опкодов
  • wincache_rplist_fileinfo() - Получает информацию о разрешении кеша пути к файлу разрешения
  • wincache_rplist_meminfo() - Получает информацию об использовании памяти с помощью кеша пути к файлу разрешения
  • wincache_refresh_if_changed() - Обновляет записи кеша для закешированных файлов
  • wincache_ucache_meminfo() - Получает информацию об использовании памяти пользовательского кеша
  • wincache_ucache_info() - Получает информацию о данных, хранящихся в пользовательском кеше
  • wincache_scache_info() - Получает информацию о файлах, закешированных в кеше сессии
  • wincache_scache_meminfo() - Получает информацию об использовании кеш-памяти сессии



wincache_lock

(PECL wincache >= 1.1.0)

wincache_lock Получает эксклюзивную блокировку для данного ключа

Описание

wincache_lock(string $key, bool $isglobal = false): bool

Получает эксклюзивную блокировку для данного ключа. Выполнение текущего скрипта будет заблокировано до тех пор, пока блокировка не будет получена. После получения блокировки другие сценарии, которые пытаются запросить блокировку с помощью того же ключа, будут заблокированы до тех пор, пока текущий скрипт не снимет блокировку с помощью wincache_unlock().

Внимание

Использование wincache_lock() и wincache_unlock() может вызвать взаимную блокировку при выполнении скриптов PHP в многопроцессорной среде, такой как FastCGI. Не используйте эти функции, если вы не уверены, что вам это нужно. Для большинства операций с пользовательским кешем эти функции использовать не обязательно.

Список параметров

key

Имя ключа в кеше для включения блокировки.

isglobal

Определяет, является ли область блокировки общесистемной или локальной. Локальные блокировки относятся к пулу приложений в случае IIS FastCGI или ко всем процессам PHP, которые имеют один и тот же идентификатор родительского процесса.

Возвращаемые значения

Возвращает true в случае успешного выполнения или false в случае возникновения ошибки.

Примеры

Пример #1 Пример использования wincache_lock()

<?php
$fp
= fopen("/tmp/lock.txt", "r+");
if (
wincache_lock(“lock_txt_lock”)) { // получить эксклюзивную блокировку
ftruncate($fp, 0); // обрезать файл
fwrite($fp, "Напишите что-нибудь здесь\n");
wincache_unlock(“lock_txt_lock”); // снять блокировку
} else {
echo
"Не удалось получить блокировку!";
}
fclose($fp);
?>

Смотрите также

  • wincache_unlock() - Снимает эксклюзивную блокировку данного ключа
  • wincache_ucache_set() - Добавляет переменную в пользовательский кеш и перезаписывает переменную, если она уже существует в кеше
  • wincache_ucache_get() - Получает переменную, хранящуюся в пользовательском кеше
  • wincache_ucache_delete() - Удаляет переменные из пользовательского кеша
  • wincache_ucache_clear() - Удаляет всё содержимое пользовательского кеша
  • wincache_ucache_exists() - Проверяет, существует ли переменная в пользовательском кеше
  • wincache_ucache_meminfo() - Получает информацию об использовании памяти пользовательского кеша
  • wincache_ucache_info() - Получает информацию о данных, хранящихся в пользовательском кеше
  • wincache_scache_info() - Получает информацию о файлах, закешированных в кеше сессии



wincache_ocache_fileinfo

(PECL wincache >= 1.0.0)

wincache_ocache_fileinfoПолучает информацию о файлах, закешированных в кеше опкодов

Описание

wincache_ocache_fileinfo(bool $summaryonly = false): array|false

Получает информацию о содержимом кеша опкодов и его использовании.

Внимание

Эта функция УДАЛЕНА в PHP 7.0.0.

Список параметров

summaryonly

Определяет, будет ли возвращаемый массив содержать информацию об отдельных записях кеша вместе со сводкой кеша опкодов.

Возвращаемые значения

Массив метаданных о кеше опкодов или false в случае возникновения ошибки.

Массив, возвращаемый этой функцией, содержит следующие элементы:

  • total_cache_uptime - общее время в секундах, в течение которого кеш опкода был активен.
  • total_file_count - общее количество файлов, которые в настоящее время находятся в кеше опкодов.
  • total_hit_count - количество раз, когда скомпилированный опкод был использован из кеша.
  • total_miss_count - количество раз, когда скомпилированный опкод не был найден в кеше.
  • is_local_cache - true, если метаданные кеша предназначены для экземпляра локального кеша, false, если метаданные предназначены для глобального кеша.
  • file_entries - массив, содержащий информацию обо всех закешированных файлах:

    • file_name - абсолютное имя закешированного файла.
    • add_time - время в секундах с момента добавления файла в кеш опкодов.
    • use_time - время в секундах с момента обращения к файлу в кеше опкодов.
    • last_check - время в секундах с момента проверки файла на наличие модификаций.
    • hit_count - количество раз, когда файл был использован из кеша.
    • function_count - количество функций в закешированном файле.
    • class_count - количество классов в закешированном файле.

Примеры

Пример #1 Пример использования wincache_ocache_fileinfo()

<pre>
<?php
print_r
(wincache_ocache_fileinfo());
?>
</pre>

Результат выполнения данного примера:

Array
(
    [total_cache_uptime] => 17357
    [total_file_count] => 121
    [total_hit_count] => 36562
    [total_miss_count] => 201
    [file_entries] => Array
        (
            [1] => Array
                (
                    [file_name] => c:\inetpub\wwwroot\checkcache.php
                    [add_time] => 17356
                    [use_time] => 7
                    [last_check] => 10
                    [hit_count] => 454
                    [function_count] => 0
                    [class_count] => 1
                )
            [2] => Array (...iterates for each cached file)
        )
)

Смотрите также

  • wincache_fcache_fileinfo() - Получает информацию о файлах, закешированных в файловом кеше
  • wincache_fcache_meminfo() - Получает информацию об использовании памяти файлового кеша
  • wincache_ocache_meminfo() - Получает информацию об использовании кеш-памяти опкодов
  • wincache_rplist_fileinfo() - Получает информацию о разрешении кеша пути к файлу разрешения
  • wincache_rplist_meminfo() - Получает информацию об использовании памяти с помощью кеша пути к файлу разрешения
  • wincache_refresh_if_changed() - Обновляет записи кеша для закешированных файлов
  • wincache_ucache_meminfo() - Получает информацию об использовании памяти пользовательского кеша
  • wincache_ucache_info() - Получает информацию о данных, хранящихся в пользовательском кеше
  • wincache_scache_info() - Получает информацию о файлах, закешированных в кеше сессии
  • wincache_scache_meminfo() - Получает информацию об использовании кеш-памяти сессии



wincache_ocache_meminfo

(PECL wincache >= 1.0.0)

wincache_ocache_meminfoПолучает информацию об использовании кеш-памяти опкодов

Описание

wincache_ocache_meminfo(): array|false

Получает информацию об использовании кеш-памяти опкодов.

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Массив метаданных об использовании кеш-памяти опкодов или false в случае возникновения ошибки.

Массив, возвращаемый этой функцией, содержит следующие элементы:

  • memory_total - объём памяти в байтах, выделенный для кеша опкодов.
  • memory_free - объём свободной памяти в байтах, доступной для кеша опкодов.
  • num_used_blks - количество блоков памяти, используемых кешем опкодов.
  • num_free_blks - количество свободных блоков памяти, доступных для кеша опкодов.
  • memory_overhead - объём памяти в байтах, используемый для внутренних структур кеша опкодов.

Внимание

Эта функция УДАЛЕНА в PHP 7.0.0.

Примеры

Пример #1 Пример использования wincache_ocache_meminfo()

<pre>
<?php
print_r
(wincache_ocache_meminfo());
?>
</pre>

Результат выполнения данного примера:

Array
(
    [memory_total] => 134217728
    [memory_free] => 112106972
    [num_used_blks] => 15469
    [num_free_blks] => 4
    [memory_overhead] => 247600
)

Смотрите также

  • wincache_fcache_fileinfo() - Получает информацию о файлах, закешированных в файловом кеше
  • wincache_fcache_meminfo() - Получает информацию об использовании памяти файлового кеша
  • wincache_ocache_fileinfo() - Получает информацию о файлах, закешированных в кеше опкодов
  • wincache_rplist_fileinfo() - Получает информацию о разрешении кеша пути к файлу разрешения
  • wincache_rplist_meminfo() - Получает информацию об использовании памяти с помощью кеша пути к файлу разрешения
  • wincache_refresh_if_changed() - Обновляет записи кеша для закешированных файлов
  • wincache_ucache_meminfo() - Получает информацию об использовании памяти пользовательского кеша
  • wincache_ucache_info() - Получает информацию о данных, хранящихся в пользовательском кеше
  • wincache_scache_info() - Получает информацию о файлах, закешированных в кеше сессии
  • wincache_scache_meminfo() - Получает информацию об использовании кеш-памяти сессии



wincache_refresh_if_changed

(PECL wincache >= 1.0.0)

wincache_refresh_if_changedОбновляет записи кеша для закешированных файлов

Описание

wincache_refresh_if_changed(array $files = NULL): bool

Обновляет записи кеша для файлов, имена которых были переданы во входном аргументе. Если аргумент не указан, обновляются все записи в кеше.

Список параметров

files

Массив имён файлов, которые необходимо обновить. Могут использоваться абсолютные или относительные пути к файлам.

Возвращаемые значения

Возвращает true в случае успешного выполнения или false в случае возникновения ошибки.

Примеры

WinCache выполняет регулярные проверки закешированных файлов, чтобы гарантировать, что если какой-либо файл был изменён, то соответствующая запись в кеше будет обновлена. По умолчанию эта проверка выполняется каждые 30 секунд. Если, например, PHP-скрипт обновляет другой PHP-скрипт, в котором хранятся параметры конфигурации приложения, то может случиться так, что после сохранения параметров конфигурации в файл приложение по-прежнему будет использовать старые параметры в течение некоторого времени, пока не будет обновлён кеш. В таких случаях может быть предпочтительнее обновить кеш сразу после изменения файла. В следующем примере показано, как это можно сделать.

Пример #1 Пример использования wincache_refresh_if_changed()

<?php
$filename
= 'C:\inetpub\wwwroot\config.php';
$handle = fopen($filename, 'w+');
if (
$handle === FALSE) die('Failed to open file '.$filename.' for writing');
fwrite($handle, '<?php $setting=something; ?>');
fclose($handle);
wincache_refresh_if_changed(array($filename));
?>

Смотрите также

  • wincache_fcache_fileinfo() - Получает информацию о файлах, закешированных в файловом кеше
  • wincache_fcache_meminfo() - Получает информацию об использовании памяти файлового кеша
  • wincache_ocache_fileinfo() - Получает информацию о файлах, закешированных в кеше опкодов
  • wincache_ocache_meminfo() - Получает информацию об использовании кеш-памяти опкодов
  • wincache_rplist_fileinfo() - Получает информацию о разрешении кеша пути к файлу разрешения
  • wincache_rplist_meminfo() - Получает информацию об использовании памяти с помощью кеша пути к файлу разрешения
  • wincache_ucache_meminfo() - Получает информацию об использовании памяти пользовательского кеша
  • wincache_ucache_info() - Получает информацию о данных, хранящихся в пользовательском кеше



wincache_rplist_fileinfo

(PECL wincache >= 1.0.0)

wincache_rplist_fileinfoПолучает информацию о разрешении кеша пути к файлу разрешения

Описание

wincache_rplist_fileinfo(bool $summaryonly = false): array|false

Получает информацию о закешированных сопоставлениях между относительными путями к файлам и соответствующими абсолютными путями к файлам.

Список параметров

summaryonly

Возвращаемые значения

Массив метаданных о кеше пути к файлу разрешения или false в случае возникновения ошибки.

Массив, возвращаемый этой функцией, содержит следующие элементы:

  • total_file_count - общее количество сопоставлений пути к файлу, хранящихся в кеше.
  • rplist_entries - массив, содержащий информацию обо всех путях закешированных файлов:

    • resolve_path - путь к файлу.
    • subkey_data - соответствующий абсолютный путь к файлу.

Примеры

Пример #1 Пример использования wincache_rplist_fileinfo()

<pre>
<?php
print_r
(wincache_rplist_fileinfo());
?>
</pre>

Результат выполнения данного примера:

Array
(
    [total_file_count] => 5
    [rplist_entries] => Array
        (
            [1] => Array
                (
                    [resolve_path] => checkcache.php
                    [subkey_data] => c:\inetpub\wwwroot|c:\inetpub\wwwroot\checkcache.php
                )

            [2] => Array (...iterates for each cached file)
        )
)

Смотрите также

  • wincache_fcache_meminfo() - Получает информацию об использовании памяти файлового кеша
  • wincache_fcache_fileinfo() - Получает информацию о файлах, закешированных в файловом кеше
  • wincache_ocache_fileinfo() - Получает информацию о файлах, закешированных в кеше опкодов
  • wincache_ocache_meminfo() - Получает информацию об использовании кеш-памяти опкодов
  • wincache_rplist_meminfo() - Получает информацию об использовании памяти с помощью кеша пути к файлу разрешения
  • wincache_refresh_if_changed() - Обновляет записи кеша для закешированных файлов
  • wincache_ucache_meminfo() - Получает информацию об использовании памяти пользовательского кеша
  • wincache_ucache_info() - Получает информацию о данных, хранящихся в пользовательском кеше
  • wincache_scache_info() - Получает информацию о файлах, закешированных в кеше сессии
  • wincache_scache_meminfo() - Получает информацию об использовании кеш-памяти сессии



wincache_rplist_meminfo

(PECL wincache >= 1.0.0)

wincache_rplist_meminfoПолучает информацию об использовании памяти с помощью кеша пути к файлу разрешения

Описание

wincache_rplist_meminfo(): array|false

Получает информацию об использовании памяти с помощью кеша пути к файлу разрешения.

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Массив метаданных, описывающий использование памяти с помощью кеша пути к файлу разрешения или false в случае возникновения ошибки.

Массив, возвращаемый этой функцией, содержит следующие элементы:

  • memory_total - объём памяти в байтах, выделенный для кеша пути к файлу разрешения.
  • memory_free - объём свободной памяти в байтах, доступной для кеша пути к файлу разрешения.
  • num_used_blks - количество блоков памяти, используемых кешем пути к файлу разрешения.
  • num_free_blks - количество свободных блоков памяти, доступных для кеша пути к файлу разрешения.
  • memory_overhead - объём памяти в байтах, используемый для внутренних структур кеширования пути к файлу разрешения.

Примеры

Пример #1 Пример использования wincache_rplist_meminfo()

<pre>
<?php
print_r
(wincache_rplist_meminfo());
?>
</pre>

Результат выполнения данного примера:

Array
(
    [memory_total] => 9437184
    [memory_free] => 9416744
    [num_used_blks] => 23
    [num_free_blks] => 1
    [memory_overhead] => 416
)

Смотрите также

  • wincache_fcache_fileinfo() - Получает информацию о файлах, закешированных в файловом кеше
  • wincache_fcache_meminfo() - Получает информацию об использовании памяти файлового кеша
  • wincache_ocache_fileinfo() - Получает информацию о файлах, закешированных в кеше опкодов
  • wincache_ocache_meminfo() - Получает информацию об использовании кеш-памяти опкодов
  • wincache_rplist_fileinfo() - Получает информацию о разрешении кеша пути к файлу разрешения
  • wincache_refresh_if_changed() - Обновляет записи кеша для закешированных файлов
  • wincache_ucache_meminfo() - Получает информацию об использовании памяти пользовательского кеша
  • wincache_ucache_info() - Получает информацию о данных, хранящихся в пользовательском кеше
  • wincache_scache_info() - Получает информацию о файлах, закешированных в кеше сессии
  • wincache_scache_meminfo() - Получает информацию об использовании кеш-памяти сессии



wincache_scache_info

(PECL wincache >= 1.1.0)

wincache_scache_infoПолучает информацию о файлах, закешированных в кеше сессии

Описание

wincache_scache_info(bool $summaryonly = false): array|false

Получает информацию о содержимом кеша сессии и его использовании.

Список параметров

summaryonly

Определяет, будет ли возвращаемый массив содержать информацию об отдельных записях кеша вместе со сводкой кеша сессии.

Возвращаемые значения

Массив метаданных о кеше сессии или false в случае возникновения ошибки.

Массив, возвращаемый этой функцией, содержит следующие элементы:

  • total_cache_uptime - общее время в секундах, в течение которого кеш сессии был активен.
  • total_item_count - общее количество элементов, которые в настоящее время находятся в кеше сессии.
  • is_local_cache - true, если метаданные кеша предназначены для экземпляра локального кеша, false, если метаданные предназначены для глобального кеша.
  • total_hit_count - количество раз, когда данные были обработаны из кеша.
  • total_miss_count - количество раз, когда данные не были найдены в кеше.
  • scache_entries - массив, содержащий информацию обо всех закешированных элементах:

    • key_name - имя ключа, который используется для хранения данных.
    • value_type - тип значения, хранимого ключом.
    • use_time - время в секундах с момента обращения к файлу в кеше опкодов.
    • last_check - время в секундах с момента проверки файла на наличие модификаций.
    • ttl_seconds - время, оставшееся для данных, чтобы оставаться в кеше, 0 означает бесконечность.
    • age_seconds - время, прошедшее с момента добавления данных в кеш.
    • hitcount - количество раз, когда данные были получены из кеша.

Примеры

Пример #1 Пример использования wincache_scache_info()

<pre>
<?php
print_r
(wincache_scache_info());
?>
</pre>

Результат выполнения данного примера:

Array
(
    [total_cache_uptime] => 17357
    [total_file_count] => 121
    [total_hit_count] => 36562
    [total_miss_count] => 201
    [scache_entries] => Array
        (
            [1] => Array
                (
                    [file_name] => c:\inetpub\wwwroot\checkcache.php
                    [add_time] => 17356
                    [use_time] => 7
                    [last_check] => 10
                    [hit_count] => 454
                    [function_count] => 0
                    [class_count] => 1
                )
            [2] => Array (...iterates for each cached file)
        )
)

Смотрите также

  • wincache_fcache_fileinfo() - Получает информацию о файлах, закешированных в файловом кеше
  • wincache_fcache_meminfo() - Получает информацию об использовании памяти файлового кеша
  • wincache_ocache_meminfo() - Получает информацию об использовании кеш-памяти опкодов
  • wincache_rplist_fileinfo() - Получает информацию о разрешении кеша пути к файлу разрешения
  • wincache_rplist_meminfo() - Получает информацию об использовании памяти с помощью кеша пути к файлу разрешения
  • wincache_refresh_if_changed() - Обновляет записи кеша для закешированных файлов
  • wincache_ucache_meminfo() - Получает информацию об использовании памяти пользовательского кеша
  • wincache_ucache_info() - Получает информацию о данных, хранящихся в пользовательском кеше
  • wincache_scache_meminfo() - Получает информацию об использовании кеш-памяти сессии



wincache_scache_meminfo

(PECL wincache >= 1.1.0)

wincache_scache_meminfoПолучает информацию об использовании кеш-памяти сессии

Описание

wincache_scache_meminfo(): array|false

Получает информацию об использовании памяти кешем сессии.

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Массив метаданных об использовании кеш-памяти сессии или false в случае возникновения ошибки.

Массив, возвращаемый этой функцией, содержит следующие элементы:

  • memory_total - объём памяти в байтах, выделенный для кеш-памяти сессии.
  • memory_free - объём свободной памяти в байтах, доступной для кеш-памяти сессии.
  • num_used_blks - количество блоков памяти, используемых кешем сессии.
  • num_free_blks - количество свободных блоков памяти, доступных для кеша сессии.
  • memory_overhead - объём памяти в байтах, используемый для внутренних структур кеша сессии.

Примеры

Пример #1 Пример использования wincache_scache_meminfo()

<pre>
<?php
print_r
(wincache_scache_meminfo());
?>
</pre>

Результат выполнения данного примера:

Array
(
    [memory_total] => 5242880
    [memory_free] => 5215056
    [num_used_blks] => 6
    [num_free_blks] => 3
    [memory_overhead] => 176
)

Смотрите также

  • wincache_fcache_fileinfo() - Получает информацию о файлах, закешированных в файловом кеше
  • wincache_fcache_meminfo() - Получает информацию об использовании памяти файлового кеша
  • wincache_ocache_fileinfo() - Получает информацию о файлах, закешированных в кеше опкодов
  • wincache_rplist_fileinfo() - Получает информацию о разрешении кеша пути к файлу разрешения
  • wincache_rplist_meminfo() - Получает информацию об использовании памяти с помощью кеша пути к файлу разрешения
  • wincache_refresh_if_changed() - Обновляет записи кеша для закешированных файлов
  • wincache_ucache_info() - Получает информацию о данных, хранящихся в пользовательском кеше
  • wincache_scache_info() - Получает информацию о файлах, закешированных в кеше сессии



wincache_ucache_add

(PECL wincache >= 1.1.0)

wincache_ucache_addДобавляет переменную в пользовательский кеш, только если переменная ещё не существует в кеше

Описание

wincache_ucache_add(string $key, mixed $value, int $ttl = 0): bool
wincache_ucache_add(array $values, mixed $unused = NULL, int $ttl = 0): bool

Добавляет переменную в пользовательский кеш, только если эта переменная ещё не существует в кеше. Добавленная переменная остаётся в пользовательском кеше, пока не истечёт срок её действия или она не будет удалена с помощью функций wincache_ucache_delete() или wincache_ucache_clear().

Список параметров

key

Сохраняет переменную с использованием этого имени key. Если переменная с таким же key уже существует, завершится ошибкой и вернёт false. key чувствителен к регистру. Чтобы переопределить значение, даже если key уже существует, используйте функцию wincache_ucache_set(). key также может принимать массив пар имя => значение, где имена будут использоваться в качестве ключей. Это можно использовать для добавления нескольких значений в кеш за одну операцию, что позволяет избежать состояния гонки.

value

Значение переменной, которую необходимо сохранить. Value поддерживает все типы данных, кроме ресурсов, таких как дескрипторы файлов. Параметр игнорируется, если первым аргументом является массив. Общее руководство - передать null в качестве value при использовании массива key. Если value является объектом или массивом, содержащим объекты, то объекты будут сериализованы. Подробнее о сериализации объектов смотрите в описании __sleep().

values

Ассоциативный массив ключей и значений.

ttl

Время, в течение которого переменная находится в кеше, в секундах. После того, как значение, указанное в ttl будет передано, сохранённая переменная будет удалена из кеша. Параметр принимает значение по умолчанию 0, что означает, что переменная останется в кеше, пока она не будет явно удалена с помощью функций wincache_ucache_delete() или wincache_ucache_clear().

Возвращаемые значения

Если key является строкой, функция возвращает true в случае успешного выполнения и false в случае возникновения ошибки.

Если key является массивом, функция возвращает:

  • Если все пары имя => значение в массиве могут быть установлены, функция возвращает пустой массив;
  • Если все пары имя => значение в массиве не могут быть установлены, функция возвращает false;
  • Если некоторые из них могут быть установлены, а другие - нет, функция возвращает массив с парами name => value, которые не удалось добавить в пользовательский кеш.

Примеры

Пример #1 Пример использования wincache_ucache_add() с key в виде строки

<?php
$bar
= 'BAR';
var_dump(wincache_ucache_add('foo', $bar));
var_dump(wincache_ucache_add('foo', $bar));
var_dump(wincache_ucache_get('foo'));
?>

Результат выполнения данного примера:

bool(true)
bool(false)
string(3) "BAR"

Пример #2 Пример использования wincache_ucache_add() с key в виде массива

<?php
$colors_array
= array('green' => '5', 'Blue' => '6', 'yellow' => '7', 'cyan' => '8');
var_dump(wincache_ucache_add($colors_array));
var_dump(wincache_ucache_add($colors_array));
var_dump(wincache_ucache_get('Blue'));
?>

Результат выполнения данного примера:

array(0) { }
array(4) {
  ["green"]=> int(-1)
  ["Blue"]=> int(-1)
  ["yellow"]=> int(-1)
  ["cyan"]=> int(-1)
}
string(1) "6"

Смотрите также

  • wincache_ucache_set() - Добавляет переменную в пользовательский кеш и перезаписывает переменную, если она уже существует в кеше
  • wincache_ucache_get() - Получает переменную, хранящуюся в пользовательском кеше
  • wincache_ucache_delete() - Удаляет переменные из пользовательского кеша
  • wincache_ucache_clear() - Удаляет всё содержимое пользовательского кеша
  • wincache_ucache_exists() - Проверяет, существует ли переменная в пользовательском кеше
  • wincache_ucache_meminfo() - Получает информацию об использовании памяти пользовательского кеша
  • wincache_ucache_info() - Получает информацию о данных, хранящихся в пользовательском кеше
  • __sleep()



wincache_ucache_cas

(PECL wincache >= 1.1.0)

wincache_ucache_casСравнивает переменную со старым значением и присваивает ей новое значение

Описание

wincache_ucache_cas(string $key, int $old_value, int $new_value): bool

Сравнивает переменную, связанную с key с old_value и, если она совпадает, присваивает ей new_value.

Список параметров

key

key, который использовался для сохранения переменной в кеш. key чувствителен к регистру.

old_value

Старое значение переменной, на которую указывает key в пользовательском кеше. Значение должно быть типа long, иначе функция вернёт false.

new_value

Новое значение, которое будет присвоено указателю переменной key, если будет найдено совпадение. Значение должно быть типа long, иначе функция вернёт false.

Возвращаемые значения

Возвращает true в случае успешного выполнения или false в случае возникновения ошибки.

Примеры

Пример #1 Пример использования wincache_ucache_cas()

<?php
wincache_ucache_set
('counter', 2922);
var_dump(wincache_ucache_cas('counter', 2922, 1));
var_dump(wincache_ucache_get('counter'));
?>

Результат выполнения данного примера:

bool(true)
int(1)

Смотрите также



wincache_ucache_clear

(PECL wincache >= 1.1.0)

wincache_ucache_clearУдаляет всё содержимое пользовательского кеша

Описание

wincache_ucache_clear(): bool

Очищает/удаляет все значения, хранящиеся в пользовательском кеше.

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Возвращает true в случае успешного выполнения или false в случае возникновения ошибки.

Примеры

Пример #1 Пример использования wincache_ucache_clear()

<?php
wincache_ucache_set
('green', 1);
wincache_ucache_set('red', 2);
wincache_ucache_set('orange', 4);
wincache_ucache_set('blue', 8);
wincache_ucache_set('cyan', 16);
$array1 = array('green', 'red', 'orange', 'blue', 'cyan');
var_dump(wincache_ucache_get($array1));
var_dump(wincache_ucache_clear());
var_dump(wincache_ucache_get($array1));
?>

Результат выполнения данного примера:

array(5) { ["green"]=> int(1)
           ["red"]=> int(2)
           ["orange"]=> int(4)
           ["blue"]=> int(8)
           ["cyan"]=> int(16) }
bool(true)
bool(false)

Смотрите также

  • wincache_ucache_set() - Добавляет переменную в пользовательский кеш и перезаписывает переменную, если она уже существует в кеше
  • wincache_ucache_add() - Добавляет переменную в пользовательский кеш, только если переменная ещё не существует в кеше
  • wincache_ucache_delete() - Удаляет переменные из пользовательского кеша
  • wincache_ucache_get() - Получает переменную, хранящуюся в пользовательском кеше
  • wincache_ucache_exists() - Проверяет, существует ли переменная в пользовательском кеше
  • wincache_ucache_meminfo() - Получает информацию об использовании памяти пользовательского кеша
  • wincache_ucache_info() - Получает информацию о данных, хранящихся в пользовательском кеше



wincache_ucache_dec

(PECL wincache >= 1.1.0)

wincache_ucache_decУменьшает значение, связанное с ключом

Описание

wincache_ucache_dec(string $key, int $dec_by = 1, bool &$success = ?): mixed

Уменьшает значение, связанное с key на 1 или как указано в dec_by.

Список параметров

key

key, который использовался для сохранения переменной в кеш. key чувствителен к регистру.

dec_by

Значение, на которое должна быть уменьшена переменная, связанная с key. Если аргумент является числом с плавающей точкой, он будет усечён до ближайшего целого числа. Переменная, связанная с key, должна иметь тип long, иначе функция завершится ошибкой и вернёт false.

success

Будет установлено значение true в случае успешного выполнения и false в случае возникновения ошибки.

Возвращаемые значения

Возвращает уменьшенное значение в случае успешного выполнения и false в случае возникновения ошибки.

Примеры

Пример #1 Пример использования wincache_ucache_dec()

<?php
wincache_ucache_set
('counter', 1);
var_dump(wincache_ucache_dec('counter', 2923, $success));
var_dump($success);
?>

Результат выполнения данного примера:

int(2922)
bool(true)

Смотрите также

  • wincache_ucache_inc() - Увеличивает значение, связанное с ключом
  • wincache_ucache_cas() - Сравнивает переменную со старым значением и присваивает ей новое значение



wincache_ucache_delete

(PECL wincache >= 1.1.0)

wincache_ucache_deleteУдаляет переменные из пользовательского кеша

Описание

wincache_ucache_delete(mixed $key): bool

Удаляет элементы из пользовательского кеша, на которые указывает параметр key.

Список параметров

key

Параметр key, который использовался для хранения переменной в кеше. key чувствителен к регистру. key может быть массивом ключей.

Возвращаемые значения

Возвращает true в случае успешного выполнения или false в случае возникновения ошибки.

Если параметр key является массивом, функция возвращает false, если не удаётся удалить каждый элемент массива из пользовательского кеша, в противном случае возвращается массив, состоящий из всех удалённых ключей.

Примеры

Пример #1 Пример использования wincache_ucache_delete() с key в виде строки

<?php
wincache_ucache_set
('foo', 'bar');
var_dump(wincache_ucache_delete('foo'));
var_dump(wincache_ucache_exists('foo'));
?>

Результат выполнения данного примера:

bool(true)
bool(false)

Пример #2 Пример использования wincache_ucache_delete() с key в виде массива

<?php
$array1
= array('green' => '5', 'blue' => '6', 'yellow' => '7', 'cyan' => '8');
wincache_ucache_set($array1);
$array2 = array('green', 'blue', 'yellow', 'cyan');
var_dump(wincache_ucache_delete($array2));
?>

Результат выполнения данного примера:

array(4) { [0]=> string(5) "green"
           [1]=> string(4) "Blue"
           [2]=> string(6) "yellow"
           [3]=> string(4) "cyan" }

Пример #3 Пример использования wincache_ucache_delete() с key в виде массива, из которого нельзя удалить некоторые элементы

<?php
$array1
= array('green' => '5', 'blue' => '6', 'yellow' => '7', 'cyan' => '8');
wincache_ucache_set($array1);
$array2 = array('orange', 'red', 'yellow', 'cyan');
var_dump(wincache_ucache_delete($array2));
?>

Результат выполнения данного примера:

array(2) { [0]=> string(6) "yellow"
           [1]=> string(4) "cyan" }

Смотрите также

  • wincache_ucache_set() - Добавляет переменную в пользовательский кеш и перезаписывает переменную, если она уже существует в кеше
  • wincache_ucache_add() - Добавляет переменную в пользовательский кеш, только если переменная ещё не существует в кеше
  • wincache_ucache_get() - Получает переменную, хранящуюся в пользовательском кеше
  • wincache_ucache_clear() - Удаляет всё содержимое пользовательского кеша
  • wincache_ucache_exists() - Проверяет, существует ли переменная в пользовательском кеше
  • wincache_ucache_meminfo() - Получает информацию об использовании памяти пользовательского кеша
  • wincache_ucache_info() - Получает информацию о данных, хранящихся в пользовательском кеше



wincache_ucache_exists

(PECL wincache >= 1.1.0)

wincache_ucache_existsПроверяет, существует ли переменная в пользовательском кеше

Описание

wincache_ucache_exists(string $key): bool

Проверяет, существует ли переменная key в пользовательском кеше или нет.

Список параметров

key

Параметр key, который использовался для хранения переменной в кеше. key чувствителен к регистру.

Возвращаемые значения

Возвращает true, если переменная с key существует, в противном случае возвращает false.

Примеры

Пример #1 Пример использования wincache_ucache_exists()

<?php
if (!wincache_ucache_exists('green'))
wincache_ucache_set('green', 1);
var_dump(wincache_ucache_exists('green'));
?>

Результат выполнения данного примера:

bool(true)

Смотрите также

  • wincache_ucache_set() - Добавляет переменную в пользовательский кеш и перезаписывает переменную, если она уже существует в кеше
  • wincache_ucache_add() - Добавляет переменную в пользовательский кеш, только если переменная ещё не существует в кеше
  • wincache_ucache_get() - Получает переменную, хранящуюся в пользовательском кеше
  • wincache_ucache_clear() - Удаляет всё содержимое пользовательского кеша
  • wincache_ucache_delete() - Удаляет переменные из пользовательского кеша
  • wincache_ucache_meminfo() - Получает информацию об использовании памяти пользовательского кеша
  • wincache_ucache_info() - Получает информацию о данных, хранящихся в пользовательском кеше



wincache_ucache_get

(PECL wincache >= 1.1.0)

wincache_ucache_getПолучает переменную, хранящуюся в пользовательском кеше

Описание

wincache_ucache_get(mixed $key, bool &$success = ?): mixed

Получает переменную, хранящуюся в пользовательском кеше.

Список параметров

key

Параметр key, который использовался для хранения переменной в кеше. key чувствителен к регистру. key может быть массивом ключей. В этом случае возвращаемое значение будет массивом значений каждого элемента в массиве key. Если возвращается объект или массив, содержащий объекты, то объекты будут десериализованы. Подробнее о десериализации объектов смотрите __wakeup().

success

Будет установлено значение true в случае успешного выполнения или false в случае возникновения ошибки.

Возвращаемые значения

Если параметр key является строкой, функция возвращает значение переменной, хранящейся с этим ключом. Для параметра success будет установлено значение true в случае успешного выполнения или false в случае возникновения ошибки.

Если параметр key - это массив, параметр success всегда будет иметь значение true. Возвращённый массив (пары имя => значение) будет содержать только те пары имя => значение, для которых операция получения в пользовательском кеше была успешной. Если ни один из ключей в массиве ключей не находит совпадения в пользовательском кеше, будет возвращён пустой массив.

Примеры

Пример #1 wincache_ucache_get() с key в виде строки

<?php
wincache_ucache_add
('color', 'blue');
var_dump(wincache_ucache_get('color', $success));
var_dump($success);
?>

Результат выполнения данного примера:

string(4) "blue"
bool(true)

Пример #2 wincache_ucache_get() с key в виде массива

<?php
$array1
= array('green' => '5', 'Blue' => '6', 'yellow' => '7', 'cyan' => '8');
wincache_ucache_set($array1);
$array2 = array('green', 'Blue', 'yellow', 'cyan');
var_dump(wincache_ucache_get($array2, $success));
var_dump($success);
?>

Результат выполнения данного примера:

array(4) { ["green"]=> string(1) "5"
           ["Blue"]=> string(1) "6"
           ["yellow"]=> string(1) "7"
           ["cyan"]=> string(1) "8" }
bool(true)

Смотрите также

  • wincache_ucache_add() - Добавляет переменную в пользовательский кеш, только если переменная ещё не существует в кеше
  • wincache_ucache_set() - Добавляет переменную в пользовательский кеш и перезаписывает переменную, если она уже существует в кеше
  • wincache_ucache_delete() - Удаляет переменные из пользовательского кеша
  • wincache_ucache_clear() - Удаляет всё содержимое пользовательского кеша
  • wincache_ucache_exists() - Проверяет, существует ли переменная в пользовательском кеше
  • wincache_ucache_meminfo() - Получает информацию об использовании памяти пользовательского кеша
  • wincache_ucache_info() - Получает информацию о данных, хранящихся в пользовательском кеше
  • __wakeup()



wincache_ucache_inc

(PECL wincache >= 1.1.0)

wincache_ucache_incУвеличивает значение, связанное с ключом

Описание

wincache_ucache_inc(string $key, int $inc_by = 1, bool &$success = ?): mixed

Увеличивает значение, связанное с key на 1 или как указано в inc_by.

Список параметров

key

key, который использовался для сохранения переменной в кеш. key чувствителен к регистру.

inc_by

Значение, на которое должна быть увеличена переменная, связанная с key. Если аргумент является числом с плавающей точкой, он будет усечён до ближайшего целого числа. Переменная, связанная с key, должна иметь тип long, иначе функция завершится ошибкой и вернёт false.

success

Будет установлено значение true в случае успешного выполнения и false в случае возникновения ошибки.

Возвращаемые значения

Возвращает увеличенное значение в случае успешного выполнения и false в случае возникновения ошибки.

Примеры

Пример #1 Пример использования wincache_ucache_inc()

<?php
wincache_ucache_set
('counter', 1);
var_dump(wincache_ucache_inc('counter', 2921, $success));
var_dump($success);
?>

Результат выполнения данного примера:

int(2922)
bool(true)

Смотрите также

  • wincache_ucache_dec() - Уменьшает значение, связанное с ключом
  • wincache_ucache_cas() - Сравнивает переменную со старым значением и присваивает ей новое значение



wincache_ucache_info

(PECL wincache >= 1.1.0)

wincache_ucache_infoПолучает информацию о данных, хранящихся в пользовательском кеше

Описание

wincache_ucache_info(bool $summaryonly = false, string $key = NULL): array|false

Получает информацию о данных, хранящихся в пользовательском кеше.

Список параметров

summaryonly

Определяет, будет ли возвращаемый массив содержать информацию об отдельных записях кеша вместе со сводкой пользовательского кеша.

key

Ключ записи в пользовательском кеше. Если указано, то возвращаемый массив будет содержать информацию только об этой записи кеша. Если не указано и для summaryonly установлено значение false, тогда возвращаемый массив будет содержать информацию обо всех записях кеша.

Возвращаемые значения

Массив метаданных об использовании пользовательского кеша или false в случае возникновения ошибки

Массив, возвращаемый этой функцией, содержит следующие элементы:

  • total_cache_uptime - общее время в секундах, в течение которого пользовательский кеш был активен.
  • total_item_count - общее количество элементов, которые в данный момент находятся в пользовательском кеше.
  • is_local_cache - true - метаданные кеша предназначены для экземпляра локального кеша, false, если метаданные предназначены для глобального кеша.
  • total_hit_count - количество раз, когда данные были получены из кеша.
  • total_miss_count - количество раз, когда данные не были найдены в кеше.
  • ucache_entries - массив, содержащий информацию обо всех кешированных элементах:

    • key_name - имя ключа, который используется для хранения данных.
    • value_type - тип значения, хранимого ключом.
    • use_time - время в секундах с момента обращения к файлу в кеше опкодов.
    • last_check - время в секундах с момента проверки файла на наличие модификаций.
    • is_session - указывает, являются ли данные переменной сессии.
    • ttl_seconds - время, оставшееся для данных, чтобы находиться в кеше, 0 означает бесконечность.
    • age_seconds - время, прошедшее с момента добавления данных в кеш.
    • hitcount - количество раз, когда данные были получены из кеша.

Примеры

Пример #1 Пример использования wincache_ucache_info()

<?php
wincache_ucache_get
('green');
wincache_ucache_set('green', 2922);
wincache_ucache_get('green');
wincache_ucache_get('green');
wincache_ucache_get('green');
print_r(wincache_ucache_info());
?>

Результат выполнения данного примера:

Array
( ["total_cache_uptime"] => int(0)
  ["is_local_cache"] => bool(false)
  ["total_item_count"] => int(1)
  ["total_hit_count"] => int(3)
  ["total_miss_count"] => int(1)
  ["ucache_entries"] => Array(1)
    ( [1] => Array(6)
      (
        ["key_name"] => string(5) "green"
        ["value_type"] => string(4) "long"
        ["is_session"] => int(0)
        ["ttl_seconds"] => int(0)
        ["age_seconds"] => int(0)
        ["hitcount"] => int(3)
       )
    )
)

Смотрите также

  • wincache_fcache_meminfo() - Получает информацию об использовании памяти файлового кеша
  • wincache_ocache_fileinfo() - Получает информацию о файлах, закешированных в кеше опкодов
  • wincache_ocache_meminfo() - Получает информацию об использовании кеш-памяти опкодов
  • wincache_rplist_meminfo() - Получает информацию об использовании памяти с помощью кеша пути к файлу разрешения
  • wincache_rplist_fileinfo() - Получает информацию о разрешении кеша пути к файлу разрешения
  • wincache_refresh_if_changed() - Обновляет записи кеша для закешированных файлов
  • wincache_ucache_meminfo() - Получает информацию об использовании памяти пользовательского кеша
  • wincache_scache_info() - Получает информацию о файлах, закешированных в кеше сессии
  • wincache_scache_meminfo() - Получает информацию об использовании кеш-памяти сессии



wincache_ucache_meminfo

(PECL wincache >= 1.1.0)

wincache_ucache_meminfoПолучает информацию об использовании памяти пользовательского кеша

Описание

wincache_ucache_meminfo(): array|false

Получает информацию об использовании памяти пользовательского кеша.

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Массив метаданных об использовании памяти пользовательского кеша или false в случае возникновения ошибки

Массив, возвращаемый этой функцией, содержит следующие элементы:

  • memory_total - объем памяти в байтах, выделенный для пользовательского кеша
  • memory_free - объем свободной памяти в байтах, доступной для пользовательского кеша
  • num_used_blks - количество блоков памяти, используемых пользовательским кешем
  • num_free_blks - количество свободных блоков памяти, доступных для пользовательского кеша
  • memory_overhead - объем памяти в байтах, используемый для внутренних структур пользовательского кеша

Примеры

Пример #1 Пример использования wincache_ucache_meminfo()

<pre>
<?php
print_r
(wincache_ucache_meminfo());
?>
</pre>

Результат выполнения данного примера:

Array
(
    [memory_total] => 5242880
    [memory_free] => 5215056
    [num_used_blks] => 6
    [num_free_blks] => 3
    [memory_overhead] => 176
)

Смотрите также

  • wincache_fcache_fileinfo() - Получает информацию о файлах, закешированных в файловом кеше
  • wincache_fcache_meminfo() - Получает информацию об использовании памяти файлового кеша
  • wincache_ocache_fileinfo() - Получает информацию о файлах, закешированных в кеше опкодов
  • wincache_rplist_fileinfo() - Получает информацию о разрешении кеша пути к файлу разрешения
  • wincache_rplist_meminfo() - Получает информацию об использовании памяти с помощью кеша пути к файлу разрешения
  • wincache_refresh_if_changed() - Обновляет записи кеша для закешированных файлов
  • wincache_ucache_info() - Получает информацию о данных, хранящихся в пользовательском кеше
  • wincache_scache_info() - Получает информацию о файлах, закешированных в кеше сессии
  • wincache_scache_meminfo() - Получает информацию об использовании кеш-памяти сессии



wincache_ucache_set

(PECL wincache >= 1.1.0)

wincache_ucache_setДобавляет переменную в пользовательский кеш и перезаписывает переменную, если она уже существует в кеше

Описание

wincache_ucache_set(mixed $key, mixed $value, int $ttl = 0): bool
wincache_ucache_set(array $values, mixed $unused = NULL, int $ttl = 0): bool

Добавляет переменную в пользовательский кеш. Заменяет переменную, если она уже существует в кеше. Добавленная или обновлённая переменная остаётся в пользовательском кеше, пока не истечёт срок её действия или она не будет удалена с помощью функций wincache_ucache_delete() или wincache_ucache_clear().

Список параметров

key

Сохраняет переменную с использованием этого имени key. Если переменная с таким же key уже существует, функция перезапишет предыдущее значение новым. key чувствителен к регистру. key также может принимать массив пар имя => значение, где имена будут использоваться в качестве ключей. Это можно использовать для добавления нескольких значений в кеш за одну операцию, что позволяет избежать состояния гонки.

value

Значение переменной, которую необходимо сохранить. Value поддерживает все типы данных, кроме ресурсов, таких как дескрипторы файлов. Параметр игнорируется, если первым аргументом является массив. Общее руководство - передать null в качестве value при использовании массива key. Если value является объектом или массивом, содержащим объекты, то объекты будут сериализованы. Подробнее о сериализации объектов смотрите в описании __sleep().

values

Ассоциативный массив ключей и значений.

ttl

Время, в течение которого переменная находится в кеше, в секундах. После того, как значение, указанное в ttl будет передано, сохранённая переменная будет удалена из кеша. Параметр принимает значение по умолчанию 0, что означает, что переменная останется в кеше, пока она не будет явно удалена с помощью функций wincache_ucache_delete() или wincache_ucache_clear().

Возвращаемые значения

Если key является строкой, функция возвращает true в случае успешного выполнения и false в случае возникновения ошибки.

Если key является массивом, функция возвращает:

  • Если все пары имя => значение в массиве могут быть установлены, функция возвращает пустой массив;
  • Если все пары имя => значение в массиве не могут быть установлены, функция возвращает false;
  • Если некоторые из них могут быть установлены, а другие - нет, функция возвращает массив с парами name => value, которые не удалось добавить в пользовательский кеш.

Примеры

Пример #1 Пример использования wincache_ucache_set() с key в виде строки

<?php
$bar
= 'BAR';
var_dump(wincache_ucache_set('foo', $bar));
var_dump(wincache_ucache_get('foo'));
$bar1 = 'BAR1';
var_dump(wincache_ucache_set('foo', $bar1));
var_dump(wincache_ucache_get('foo'));
?>

Результат выполнения данного примера:

bool(true)
string(3) "BAR"
bool(true)
string(3) "BAR1"

Пример #2 Пример использования wincache_ucache_set() с key в виде массива

<?php
$colors_array
= array('green' => '5', 'Blue' => '6', 'yellow' => '7', 'cyan' => '8');
var_dump(wincache_ucache_set($colors_array));
var_dump(wincache_ucache_set($colors_array));
var_dump(wincache_ucache_get('Blue'));
?>

Результат выполнения данного примера:

array(0) {}
array(0) {}
string(1) "6"

Смотрите также

  • wincache_ucache_add() - Добавляет переменную в пользовательский кеш, только если переменная ещё не существует в кеше
  • wincache_ucache_get() - Получает переменную, хранящуюся в пользовательском кеше
  • wincache_ucache_delete() - Удаляет переменные из пользовательского кеша
  • wincache_ucache_clear() - Удаляет всё содержимое пользовательского кеша
  • wincache_ucache_exists() - Проверяет, существует ли переменная в пользовательском кеше
  • wincache_ucache_meminfo() - Получает информацию об использовании памяти пользовательского кеша
  • wincache_ucache_info() - Получает информацию о данных, хранящихся в пользовательском кеше
  • __sleep()



wincache_unlock

(PECL wincache >= 1.1.0)

wincache_unlock Снимает эксклюзивную блокировку данного ключа

Описание

wincache_unlock(string $key): bool

Снимает исключительную блокировку, которая была получена для данного ключа с помощью wincache_lock(). Если какой-либо другой процесс был заблокирован в ожидании блокировки этого ключа, этот процесс сможет получить блокировку.

Внимание

Использование wincache_lock() и wincache_unlock() может вызвать взаимную блокировку при выполнении скриптов PHP в многопроцессорной среде, такой как FastCGI. Не используйте эти функции, если вы не уверены, что вам это нужно. Для большинства операций с пользовательским кешем эти функции использовать не обязательно.

Список параметров

key

Имя ключа в кеше для снятия блокировки.

Возвращаемые значения

Возвращает true в случае успешного выполнения или false в случае возникновения ошибки.

Примеры

Пример #1 Пример использования wincache_unlock()

<?php
$fp
= fopen("/tmp/lock.txt", "r+");
if (
wincache_lock(“lock_txt_lock”)) { // получить эксклюзивную блокировку
ftruncate($fp, 0); // обрезать файл
fwrite($fp, "Напишите что-нибудь здесь\n");
wincache_unlock(“lock_txt_lock”); // снять блокировку
} else {
echo
"Не удалось получить блокировку!";
}
fclose($fp);
?>

Смотрите также

  • wincache_lock() - Получает эксклюзивную блокировку для данного ключа
  • wincache_ucache_set() - Добавляет переменную в пользовательский кеш и перезаписывает переменную, если она уже существует в кеше
  • wincache_ucache_get() - Получает переменную, хранящуюся в пользовательском кеше
  • wincache_ucache_delete() - Удаляет переменные из пользовательского кеша
  • wincache_ucache_clear() - Удаляет всё содержимое пользовательского кеша
  • wincache_ucache_exists() - Проверяет, существует ли переменная в пользовательском кеше
  • wincache_ucache_meminfo() - Получает информацию об использовании памяти пользовательского кеша
  • wincache_ucache_info() - Получает информацию о данных, хранящихся в пользовательском кеше
  • wincache_scache_info() - Получает информацию о файлах, закешированных в кеше сессии


Содержание

  • wincache_fcache_fileinfo — Получает информацию о файлах, закешированных в файловом кеше
  • wincache_fcache_meminfo — Получает информацию об использовании памяти файлового кеша
  • wincache_lock — Получает эксклюзивную блокировку для данного ключа
  • wincache_ocache_fileinfo — Получает информацию о файлах, закешированных в кеше опкодов
  • wincache_ocache_meminfo — Получает информацию об использовании кеш-памяти опкодов
  • wincache_refresh_if_changed — Обновляет записи кеша для закешированных файлов
  • wincache_rplist_fileinfo — Получает информацию о разрешении кеша пути к файлу разрешения
  • wincache_rplist_meminfo — Получает информацию об использовании памяти с помощью кеша пути к файлу разрешения
  • wincache_scache_info — Получает информацию о файлах, закешированных в кеше сессии
  • wincache_scache_meminfo — Получает информацию об использовании кеш-памяти сессии
  • wincache_ucache_add — Добавляет переменную в пользовательский кеш, только если переменная ещё не существует в кеше
  • wincache_ucache_cas — Сравнивает переменную со старым значением и присваивает ей новое значение
  • wincache_ucache_clear — Удаляет всё содержимое пользовательского кеша
  • wincache_ucache_dec — Уменьшает значение, связанное с ключом
  • wincache_ucache_delete — Удаляет переменные из пользовательского кеша
  • wincache_ucache_exists — Проверяет, существует ли переменная в пользовательском кеше
  • wincache_ucache_get — Получает переменную, хранящуюся в пользовательском кеше
  • wincache_ucache_inc — Увеличивает значение, связанное с ключом
  • wincache_ucache_info — Получает информацию о данных, хранящихся в пользовательском кеше
  • wincache_ucache_meminfo — Получает информацию об использовании памяти пользовательского кеша
  • wincache_ucache_set — Добавляет переменную в пользовательский кеш и перезаписывает переменную, если она уже существует в кеше
  • wincache_unlock — Снимает эксклюзивную блокировку данного ключа


Сборка для Windows

Содержание


Пререквизиты

Для сборки модуля WinCache требуется:

  1. Исходный код PHP
  2. Окружение сборки PHP
  3. Исходный код WinCache

Первые два пункта полностью покрываются статьёй руководства » сборка PHP под Windows.

Получение исходного кода WinCache описано в разделе Скачивание PECL-модулей.



Компиляция и сборка

Следующие шаги описывают, как компилировать и собирать WinCache под Windows OS:

  1. Откройте консоль командной строки

  2. Перейдите в папку с исходными кодами PHP

  3. Выполните команду:

    cscript.exe win32\build\buildconf.js

  4. Выполните команду:

    configure.bat --help
    Вывод будет содержать новый флаг --enable-wincache.

  5. Выполните команду:

    configure.js [все опции для сборки PHP] --enable-wincache
    --enable-wincache это единственная дополнительная опция, которая требуется для правильной сборки модуля WinCache. Эта опция соберёт WinCache и будет статически связывать его с PHP dll. Чтобы создать модуль WinCache в качестве автономной библиотеки DLL, используйте параметр --enable-wincache=shared.

  6. Выполните команду:

    nmake



Проверка сборки

Следующие шаги описывают процесс проверки того, что модуль был собран корректно:

  1. Перейдите в папку, где находится скомпилированный PHP

  2. Выполните команду:

    php.exe -n -d extension=php_wincache.dll -re wincache
    Если модуль собран правильно, в выводе этой команды будут показаны INI-директивы и функции поддерживаемые WinCache.





Hierarchical Profiler


Введение

XHProf — это легковесный профайлер основанный на иерархии и инструментировании. В процессе сбора данных он отслеживает количество вызовов и инклюзивные метрики рёбер динамического графа вызовов программы. Эксклюзивные метрики, такие как затраченное время, время CPU и потребление памяти, рассчитываются в фазе репортинга/постпроцессинга. Профилирование функции может быть сломано вызывающими или вызываемыми функциями. XHProf отслеживает рекурсивные функции путём анализа циклов в графе вызовов в момент сбора данных и избегает зацикленности путём назначения уникальных имён на основе глубины для рекурсивных вызовов.

XHProf содержит простой HTML интерфейс (написанный на PHP). UI на основе браузера сильно облегчает просмотр результатов и пересылку их всем желающим. Также поддерживается графическое отображение графа вызовов.

Отчёты XHProf часто полезны для анализа структуры запускаемого кода. Иерархическая структура отчётов позволяет определить, к примеру, цепочку вызовов, приведшую к вызову конкретной функции.

XHProf поддерживает сравнение двух разных запусков ("diff") или агрегацию данных нескольких запусков. Сравнительные и агрегированные отчёты, также как одиночные, предоставляют как "плоские", так и "иерархические" взгляды на результаты профилирования.

Дополнительная документация доступна на сайте » facebook xhprof.



Установка и настройка

Содержание


Требования

В целом не требуется, так как xhprof включает интерфейс, написанный на PHP. Он используется для сохранения и отображения результатов профилирования в удобном виде в браузере. Таким образом, включение встроенного в PHP веб-сервера позволит использовать xprof максимально продуктивно.

Также существует форк GUI интерфейса - » http://github.com/preinheimer/xhprof



Установка

Информация по установке этого модуля PECL может быть найдена в главе руководства Установка PECL модулей. Дополнительная информация, такая как новые версии, скачивание, исходные файлы, информация о разработчике и CHANGELOG, может быть найдена здесь: » https://pecl.php.net/package/xhprof



Настройка во время выполнения

Поведение этих функций зависит от установок в php.ini.

Опции настройки Xhprof
Имя По умолчанию Место изменения Список изменений
xhprof.output_dir "" PHP_INI_ALL  

Краткое разъяснение конфигурационных директив.

xhprof.output_dir string

Директория используемая реализацией интерфейса iXHProfRuns по умолчанию (класс XHProfRuns_Default) для сохранения результатов профилирования.



Типы ресурсов

Данный модуль не определяет каких-либо типов ресурсов.




Предопределённые константы

Перечисленные ниже константы определены данным модулем и могут быть доступны только в том случае, если PHP был собран с поддержкой этого модуля или же в том случае, если данный модуль был динамически загружен во время выполнения.

XHPROF_FLAGS_NO_BUILTINS (int)
Используется для исключения профилирования встроенных функций.
XHPROF_FLAGS_CPU (int)
Используется для добавления в отчёт информации по профилированию CPU.
XHPROF_FLAGS_MEMORY (int)
Используется для добавления в отчёт информации по профилированию памяти.


Примеры

Пример #1 Примеры использования Xhprof, опционально с GUI

В этом примере профайлер запускается, останавливается и использует встроенный GUI интерфейс для сохранения и разбора результатов. Другими словами, исполнение кода модуля завершается на функции xhprof_disable().

<?php
xhprof_enable
(XHPROF_FLAGS_CPU + XHPROF_FLAGS_MEMORY);

for (
$i = 0; $i <= 1000; $i++) {
$a = $i * $i;
}

$xhprof_data = xhprof_disable();

$XHPROF_ROOT = "/tools/xhprof/";
include_once
$XHPROF_ROOT . "/xhprof_lib/utils/xhprof_lib.php";
include_once
$XHPROF_ROOT . "/xhprof_lib/utils/xhprof_runs.php";

$xhprof_runs = new XHProfRuns_Default();
$run_id = $xhprof_runs->save_run($xhprof_data, "xhprof_testing");

echo
"http://localhost/xhprof/xhprof_html/index.php?run={$run_id}&source=xhprof_testing\n";

?>

Результатом выполнения данного примера будет что-то подобное:

http://localhost/xhprof/xhprof_html/index.php?run=t11_4bdf44d21121f&source=xhprof_testing


Функции Xhprof


xhprof_disable

(PECL xhprof >= 0.9.0)

xhprof_disableОстанавливает профилирование xhprof

Описание

xhprof_disable(): array

Останавливает профилирование и возвращает собранные данные.

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Массив с результатами профилирования.

Примеры

Пример #1 Пример использования xhprof_disable()

<?php
xhprof_enable
();

$foo = strlen("foo bar");

$xhprof_data = xhprof_disable();

print_r($xhprof_data);
?>

Результатом выполнения данного примера будет что-то подобное:

Array
(
    [main()==>strlen] => Array
        (
            [ct] => 1
            [wt] => 279
        )

    [main()==>xhprof_disable] => Array
        (
            [ct] => 1
            [wt] => 9
        )

    [main()] => Array
        (
            [ct] => 1
            [wt] => 610
        )

)


xhprof_enable

(PECL xhprof >= 0.9.0)

xhprof_enableЗапуск профилирования xhprof

Описание

xhprof_enable(int $flags = 0, array $options = ?): void

Запускает профилирование.

Список параметров

flags

Необязательные флаги для получения дополнительной информации при профилировании. Подробности можно найти в разделе Константы XHprof. Например, XHPROF_FLAGS_MEMORY включает профилирование памяти.

options

Массив (array) необязательных опций, а конкретно опция 'ignored_functions' со списком функций, которые не нужно профилировать.

Возвращаемые значения

null

Список изменений

Версия Описание
PECL xhprof 0.9.2 Добавлен необязательный параметр options.

Примеры

Пример #1 Пример использования xhprof_enable()

<?php
// 1. время исполнения + память + CPU; также игнорируем функции стандартной библиотеки
xhprof_enable(XHPROF_FLAGS_NO_BUILTINS | XHPROF_FLAGS_CPU | XHPROF_FLAGS_MEMORY);

// 2. время исполнения; игнорируем при профилировании call_user_func*
xhprof_enable(
0,
array(
'ignored_functions' => array('call_user_func',
'call_user_func_array')));

// 3. время исполнения + память; игнорируем при профилировании call_user_func*
xhprof_enable(
XHPROF_FLAGS_MEMORY,
array(
'ignored_functions' => array('call_user_func',
'call_user_func_array')));
?>

Смотрите также

  • xhprof_disable() - Останавливает профилирование xhprof
  • xhprof_sample_enable() - Запуск сэмплирующего режима профилирования XHProf
  • memory_get_usage() - Возвращает количество памяти, выделенное для PHP
  • getrusage() - Получает информацию об использовании текущего ресурса


xhprof_sample_disable

(PECL xhprof >= 0.9.0)

xhprof_sample_disableОстановить сэмплирующие профилирование xhprof

Описание

xhprof_sample_disable(): array

Остановить сэмплирующие профилирование xhprof.

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Массив данных, собранный профайлером.

Примеры

Пример #1 Пример использования xhprof_sample_disable()

<?php
xhprof_sample_enable
();

for (
$i = 0; $i <= 10000; $i++) {
$a = strlen($i);
$b = $i * $a;
$c = rand();
}

$xhprof_data = xhprof_sample_disable();

print_r($xhprof_data);
?>

Результатом выполнения данного примера будет что-то подобное:

Array
(
    [1272935300.800000] => main()
    [1272935300.900000] => main()
)


xhprof_sample_enable

(PECL xhprof >= 0.9.0)

xhprof_sample_enableЗапуск сэмплирующего режима профилирования XHProf

Описание

xhprof_sample_enable(): void

Запуск сэмплирующего режима профилирования, который является облегчённой версией xhprof_enable(). Интервал семплирования составляет 0.1 секунды и при каждой итерации записывается стек вызовов. Данный режим предназначен для снижения накладных расходов при мониторинге производительности.

Список параметров

У этой функции нет параметров.

Возвращаемые значения

null

Смотрите также

  • xhprof_sample_disable() - Остановить сэмплирующие профилирование xhprof
  • xhprof_enable() - Запуск профилирования xhprof
  • memory_get_usage() - Возвращает количество памяти, выделенное для PHP
  • getrusage() - Получает информацию об использовании текущего ресурса

Содержание

  • xhprof_disable — Останавливает профилирование xhprof
  • xhprof_enable — Запуск профилирования xhprof
  • xhprof_sample_disable — Остановить сэмплирующие профилирование xhprof
  • xhprof_sample_enable — Запуск сэмплирующего режима профилирования XHProf



Yac


Введение

Yac (Yet Another cache) - это свободный от блокировок кеш пользовательских данных с общей памятью, который можно использовать для замены APC и локального кеширования в памяти.



Установка и настройка

Содержание


Требования



Установка

Этот модуль » PECL не поставляется вместе с PHP.

Информация по установке этого модуля PECL может быть найдена в главе руководства Установка PECL модулей. Дополнительная информация, такая как новые версии, скачивание, исходные файлы, информация о разработчике и CHANGELOG, может быть найдена здесь: » https://pecl.php.net/package/yac.

Бинарные файлы Windows (файлы DLL) для этого модуля PECL доступны на сайте PECL.



Настройка во время выполнения

Поведение этих функций зависит от установок в php.ini.

Опции настройки Yac
Имя По умолчанию Место изменения Список изменений
yac.compress_threshold -1 PHP_INI_SYSTEM
yac.debug 0 PHP_INI_ALL
yac.enable 1 PHP_INI_SYSTEM
yac.enable_cli 0 PHP_INI_SYSTEM
yac.keys_memory_size 4M PHP_INI_SYSTEM
yac.serializer php PHP_INI_SYSTEM
yac.values_memory_size 64M PHP_INI_SYSTEM

Краткое разъяснение конфигурационных директив.

yac.compress_threshold int

yac.debug int

yac.enable int

yac.enable_cli int

yac.keys_memory_size string

yac.serializer string

yac.values_memory_size string



Типы ресурсов




Предопределённые константы

Перечисленные ниже константы определены данным модулем и могут быть доступны только в том случае, если PHP был собран с поддержкой этого модуля или же в том случае, если данный модуль был динамически загружен во время выполнения.

YAC_VERSION (string)
YAC_MAX_KEY_LEN (int)
Максимальная длина ключа может быть 48 байтов.
YAC_MAX_VALUE_RAW_LEN (int)
YAC_MAX_RAW_COMPRESSED_LEN (int)
YAC_SERIALIZER_PHP (int)
Использовать php serialize в качестве сериализатора
YAC_SERIALIZER_JSON (int)
Использовать json в качестве сериализатора (требуется --enable-json)
YAC_SERIALIZER_IGBINARY (int)
Использовать igbinary в качестве сериализатора (требуется --enable-igbinary)
YAC_SERIALIZER_MSGPACK (int)
Использовать msgpack в качестве сериализатора (требуется --enable-msgpack)
YAC_SERIALIZER (string)
Какой сериализатор используется в yac



Класс Yac

(PECL yac >= 1.0.0)

Введение

Обзор классов

class Yac {
/* Свойства */
protected $_prefix;
/* Методы */
public __construct(string $prefix = "")
public add(string $keys, mixed $value, int $ttl = 0): bool
public add(array $key_vals): bool
public delete(string|array $keys, int $ttl = ?): bool
public dump(int $$num): mixed
public flush(): bool
public get(string|array $key, int &$cas = null): mixed
public __get(string $key): mixed
public info(): array
public set(string $keys, mixed $value, int $ttl = 0): bool
public add(array $key_vals): bool
public __set(string $keys, mixed $value): mixed
}

Свойства

_prefix


Yac::add

(PECL yac >= 1.0.0)

Yac::addСохраняет в кеш

Описание

public Yac::add(string $keys, mixed $value, int $ttl = 0): bool
public Yac::add(array $key_vals): bool

Добавляет элемент в кеш.

Список параметров

keys

Ключ (string)

value

Смешанное значение. Могут быть сохранены все типы значений php, кроме resource

ttl

Время жизни

Возвращаемые значения

bool, true в случае успешного выполнения, false в случае возникновения ошибки

Замечание:

Yac::add() может завершиться с ошибкой, если не удалось получить блокировку cas, поэтому, если вам нужно, чтобы значение сохранялось должным образом, вы можете написать следующее:

Пример #1 Убедитесь, что элемент хранится

while(!$yac->set("key", "vale));



Yac::__construct

(PECL yac >= 1.0.0)

Yac::__constructКонструктор класса

Описание

public Yac::__construct(string $prefix = "")

Префикс используется для добавления к ключам, его можно использовать для предотвращения конфликтов между приложениями.

Список параметров

prefix

Префикс (string)

Ошибки

Выбрасывает Exception, если Yac не включён. Выбрасывает Exception, если prefix превышает максимальную длину ключа 48 (YAC_MAX_KEY_LEN) байтов.



Yac::delete

(PECL yac >= 1.0.0)

Yac::deleteУдаляет элементы из кеша

Описание

public Yac::delete(string|array $keys, int $ttl = ?): bool

Удаляет элементы из кеша

Список параметров

keys

Строковый ключ или массив из нескольких ключей, которые нужно удалить

ttl

Если задана задержка, удаление отметит элементы как недопустимые в течение ttl секунд.

Возвращаемые значения



Yac::dump

(PECL yac >= 1.0.0)

Yac::dumpДамп кеша

Описание

public Yac::dump(int $$num): mixed

Дамп значений, хранящихся в кеше

Список параметров

num

Максимальное количество элементов, которые должны быть возвращены

Возвращаемые значения

Смешанное значение.



Yac::flush

(PECL yac >= 1.0.0)

Yac::flushОчищает кеш

Описание

public Yac::flush(): bool

Удаляет все кешированные значения

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Логическое значение, всегда возвращает true



Yac::get

(PECL yac >= 1.0.0)

Yac::getИзвлекает значения из кеша

Описание

public Yac::get(string|array $key, int &$cas = null): mixed

Извлекает значения из кеша

Список параметров

key

Ключ (string) или массив (array), состоящий из нескольких ключей

cas

Если не null, будет установлен регистр извлечённых элементов.

Возвращаемые значения

Смешанное значение в случае успешного выполнения, false в случае возникновения ошибки



Yac::__get

(PECL yac >= 1.0.0)

Yac::__getГеттер

Описание

public Yac::__get(string $key): mixed

Извлекает значения из кеша

Список параметров

key

Ключ (string)

Возвращаемые значения

Смешанное значение в случае успешного выполнения, null в случае возникновения ошибки



Yac::info

(PECL yac >= 1.0.0)

Yac::infoСостояние кеша

Описание

public Yac::info(): array

Получает статус кеш-системы

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Вернуть массив, соответствующий: "memory_size", "slots_memory_size", "values_memory_size", "segment_size", "segment_num", "miss", "hits", "fails", "kicks", "recycles", "slots_size", "slots_used"



Yac::set

(PECL yac >= 1.0.0)

Yac::setСохраняет в кеш

Описание

public Yac::set(string $keys, mixed $value, int $ttl = 0): bool
public Yac::add(array $key_vals): bool

Добавляет элемент в кеш, если ключ уже существует, заменяет его.

Список параметров

keys

Ключ (string)

value

Смешанное значение. Могут быть сохранены все типы значений php, кроме resource

ttl

Время жизни

Возвращаемые значения

Собственное значение



Yac::__set

(PECL yac >= 1.0.0)

Yac::__setСеттер

Описание

public Yac::__set(string $keys, mixed $value): mixed

Сохраняет элемент в кеш

Список параметров

keys

Ключ (string)

value

Смешанное значение. Могут быть сохранены все типы значений php, кроме resource

Возвращаемые значения

Всегда возвращает собственное значение


Содержание





Обработка аудио форматов


Аудиопотоки OpenAL


Введение

Платформонезависимая работа с аудиопотоками. Требуется » библиотека OpenAL.



Установка и настройка

Содержание


Требования

Для сборки этого модуля не требуются внешние библиотеки.



Установка

Этот модуль » PECL не поставляется вместе с PHP.

Информация по установке этого модуля PECL может быть найдена в главе руководства Установка PECL модулей. Дополнительная информация, такая как новые версии, скачивание, исходные файлы, информация о разработчике и CHANGELOG, может быть найдена здесь: » https://pecl.php.net/package/openal.

DLL для этого модуля PECL в данный момент недоступна. Смотрите также раздел сборка на Windows.



Настройка во время выполнения

Данный модуль не определяет никакие директивы конфигурации в php.ini.



Типы ресурсов

Этот модуль определяет четыре типа ресурсов: Open AL(Device) - возвращается openal_device_open(), Open AL(Context) - возвращается openal_context_create(), Open AL(Buffer) - возвращается openal_buffer_create(), и Open AL(Source) - возвращается openal_source_create().




Предопределённые константы

Перечисленные ниже константы определены данным модулем и могут быть доступны только в том случае, если PHP был собран с поддержкой этого модуля или же в том случае, если данный модуль был динамически загружен во время выполнения.

ALC_FREQUENCY (int)
Атрибут контекста
ALC_REFRESH (int)
Атрибут контекста
ALC_SYNC (int)
Атрибут контекста
AL_FREQUENCY (int)
Настройка буфера
AL_BITS (int)
Настройка буфера
AL_CHANNELS (int)
Настройка буфера
AL_SIZE (int)
Настройка буфера
AL_BUFFER (int)
Настройка источника/слушателя (целое число)
AL_SOURCE_RELATIVE (int)
Настройка источника/слушателя (целое число)
AL_SOURCE_STATE (int)
Настройка источника/слушателя (целое число)
AL_PITCH (int)
Настройка источника/слушателя (рациональное число)
AL_GAIN (int)
Настройка источника/слушателя (рациональное число)
AL_MIN_GAIN (int)
Настройка источника/слушателя (рациональное число)
AL_MAX_GAIN (int)
Настройка источника/слушателя (рациональное число)
AL_MAX_DISTANCE (int)
Настройка источника/слушателя (рациональное число)
AL_ROLLOFF_FACTOR (int)
Настройка источника/слушателя (рациональное число)
AL_CONE_OUTER_GAIN (int)
Настройка источника/слушателя (рациональное число)
AL_CONE_INNER_ANGLE (int)
Настройка источника/слушателя (рациональное число)
AL_CONE_OUTER_ANGLE (int)
Настройка источника/слушателя (рациональное число)
AL_REFERENCE_DISTANCE (int)
Настройка источника/слушателя (рациональное число)
AL_POSITION (int)
Настройка источника/слушателя (рациональный вектор)
AL_VELOCITY (int)
Настройка источника/слушателя (рациональный вектор)
AL_DIRECTION (int)
Настройка источника/слушателя (рациональный вектор)
AL_ORIENTATION (int)
Настройка источника/слушателя (рациональный вектор)
AL_FORMAT_MONO8 (int)
Формат PCM
AL_FORMAT_MONO16 (int)
Формат PCM
AL_FORMAT_STEREO8 (int)
Формат PCM
AL_FORMAT_STEREO16 (int)
Формат PCM
AL_INITIAL (int)
Статус источника
AL_PLAYING (int)
Статус источника
AL_PAUSED (int)
Статус источника
AL_STOPPED (int)
Статус источника
AL_LOOPING (int)
Статус источника
AL_TRUE (int)
Логическое значение, понимаемое OpenAL
AL_FALSE (int)
Логическое значение, понимаемое OpenAL


Функции OpenAL


openal_buffer_create

(PECL openal >= 0.1.0)

openal_buffer_create Сгенерировать буфер OpenAL

Описание

openal_buffer_create(): resource

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Возвращает ресурс Open AL(Buffer) в случае успешного выполнения или false в случае возникновения ошибки.

Смотрите также



openal_buffer_data

(PECL openal >= 0.1.0)

openal_buffer_data Загрузка буфера с данными

Описание

openal_buffer_data(
    resource $buffer,
    int $format,
    string $data,
    int $freq
): bool

Список параметров

buffer

Ресурс Open AL(Buffer) (созданный ранее с помощью openal_buffer_create()).

format

Формат data, представленный одной из констант: AL_FORMAT_MONO8, AL_FORMAT_MONO16, AL_FORMAT_STEREO8 и AL_FORMAT_STEREO16

data

Блок двоичных аудиоданных в указанном формате format и с частотой freq.

freq

Частота data, заданная в герцах.

Возвращаемые значения

Возвращает true в случае успешного выполнения или false в случае возникновения ошибки.

Смотрите также



openal_buffer_destroy

(PECL openal >= 0.1.0)

openal_buffer_destroy Уничтожает буфер OpenAL

Описание

openal_buffer_destroy(resource $buffer): bool

Список параметров

buffer

Ресурс Open AL(Buffer) (ранее созданный с помощью openal_buffer_create()).

Возвращаемые значения

Возвращает true в случае успешного выполнения или false в случае возникновения ошибки.

Смотрите также



openal_buffer_get

(PECL openal >= 0.1.0)

openal_buffer_get Получить свойство буфера OpenAL

Описание

openal_buffer_get(resource $buffer, int $property): int|false

Список параметров

buffer

Ресурс Open AL(Buffer) (созданный ранее с помощью openal_buffer_create()).

property

Одно из свойств, заданное в виде константы: AL_FREQUENCY, AL_BITS, AL_CHANNELS и AL_SIZE.

Возвращаемые значения

Возвращает целочисленное значение, соответствующее запрошенному свойству property или false в случае возникновения ошибки.

Смотрите также



openal_buffer_loadwav

(PECL openal >= 0.1.0)

openal_buffer_loadwav Загрузить файл в формате wav в буфер

Описание

openal_buffer_loadwav(resource $buffer, string $wavfile): bool

Список параметров

buffer

Ресурс Open AL(Buffer) (ранее созданный с помощью openal_buffer_create()).

wavfile

Путь к файлу .wav в файловой системе local.

Возвращаемые значения

Возвращает true в случае успешного выполнения или false в случае возникновения ошибки.

Смотрите также



openal_context_create

(PECL openal >= 0.1.0)

openal_context_create Создать контекст обработки звука

Описание

openal_context_create(resource $device): resource

Список параметров

device

Ресурс Open AL(Device) (созданный ранее с помощью openal_device_create()).

Возвращаемые значения

Возвращает ресурс Open AL(Context) в случае успешного выполнения, false в случае возникновения ошибки.

Смотрите также



openal_context_current

(PECL openal >= 0.1.0)

openal_context_current Сделать указанный контекст текущим

Описание

openal_context_current(resource $context): bool

Список параметров

context

Ресурс Open AL(Context) (созданный ранее с помощью openal_context_create()).

Возвращаемые значения

Возвращает true в случае успешного выполнения или false в случае возникновения ошибки.

Смотрите также



openal_context_destroy

(PECL openal >= 0.1.0)

openal_context_destroy Уничтожает контекст

Описание

openal_context_destroy(resource $context): bool

Список параметров

context

Ресурс Open AL(Context) (созданный ранее с помощью openal_context_create()).

Возвращаемые значения

Возвращает true в случае успешного выполнения или false в случае возникновения ошибки.

Смотрите также



openal_context_process

(PECL openal >= 0.1.0)

openal_context_process Обработать указанный контекст

Описание

openal_context_process(resource $context): bool

Список параметров

context

Ресурс Open AL(Context) (созданный ранее с помощью openal_context_create()).

Возвращаемые значения

Возвращает true в случае успешного выполнения или false в случае возникновения ошибки.

Смотрите также



openal_context_suspend

(PECL openal >= 0.1.0)

openal_context_suspend Приостановить указанный контекст

Описание

openal_context_suspend(resource $context): bool

Список параметров

context

Ресурс Open AL(Context) (созданный ранее с помощью openal_context_create()).

Возвращаемые значения

Возвращает true в случае успешного выполнения или false в случае возникновения ошибки.

Смотрите также



openal_device_close

(PECL openal >= 0.1.0)

openal_device_close Закрыть устройство OpenAL

Описание

openal_device_close(resource $device): bool

Список параметров

device

Ресурс Open AL(Device) (созданный ранее с помощью openal_device_open()), который нужно закрыть.

Возвращаемые значения

Возвращает true в случае успешного выполнения или false в случае возникновения ошибки.

Смотрите также



openal_device_open

(PECL openal >= 0.1.0)

openal_device_open Инициализировать звуковой уровень OpenAL

Описание

openal_device_open(string $device_desc = ?): resource

Список параметров

device_desc

При необходимости открыть аудиоустройство, указав значение параметра device_desc. Если device_desc не указан, будет использовано первое аудиоустройство.

Возвращаемые значения

Возвращает ресурс Open AL(Device) в случае успешного выполнения или false в случае возникновения ошибки.

Смотрите также



openal_listener_get

(PECL openal >= 0.1.0)

openal_listener_get Получить свойство прослушивателя

Описание

openal_listener_get(int $property): mixed

Список параметров

property

Запрашиваемое свойство, представленное одной из констант: AL_GAIN (float), AL_POSITION (array(float,float,float)), AL_VELOCITY (array(float,float,float)) и AL_ORIENTATION (array(float,float,float)).

Возвращаемые значения

Возвращает число с плавающей точкой или массив чисел с плавающими точками (при необходимости) или false в случае возникновения ошибки.

Смотрите также



openal_listener_set

(PECL openal >= 0.1.0)

openal_listener_set Установка свойства прослушивателя

Описание

openal_listener_set(int $property, mixed $setting): bool

Список параметров

property

Устанавливаемое свойство, представленное одной из констант: AL_GAIN (float), AL_POSITION (array(float,float,float)), AL_VELOCITY (array(float,float,float)) и AL_ORIENTATION (array(float,float,float)).

setting

Значение для установки, либо число с плавающей точкой, либо массив с числами с плавающими точками.

Возвращаемые значения

Возвращает true в случае успешного выполнения или false в случае возникновения ошибки.

Смотрите также



openal_source_create

(PECL openal >= 0.1.0)

openal_source_create Сгенерировать источник ресурса

Описание

openal_source_create(): resource

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Возвращает ресурс Open AL(Source) в случае успешного выполнения или false в случае возникновения ошибки.

Смотрите также



openal_source_destroy

(PECL openal >= 0.1.0)

openal_source_destroy Уничтожение ресурса источника

Описание