Расширение php что это
Файлы PHP – для чего нужны, как открыть или конвертировать
Файл с расширением PHP представляет собой файл исходного кода PHP, который содержит код препроцессора гипертекста. Они часто используются в качестве файлов веб-страниц, которые генерируют HTML-код из движка PHP, работающего на веб-сервере.
Содержимое HTML, которое движок PHP создает из кода, – это то, что видно в вашем веб-браузере. Поскольку на веб-сервере выполняется код PHP, доступ к странице PHP не дает вам доступа к коду, а предоставляет контент HTML, который генерирует сервер.
Как открыть файлы PHP
Файлы PHP – это просто текстовые документы, поэтому вы можете открыть их в любом текстовом редакторе или веб-браузере. Блокнот в Windows – один из примеров, но подсветка синтаксиса настолько полезна при кодировании на PHP, что обычно предпочитают более специализированные редакторы PHP.
Некоторые текстовые редакторы включают подсветку синтаксиса. Вот некоторые популярные редакторы PHP: Adobe Dreamweaver, Eclipse PHP Development Tools, Zend Studio, phpDesigner, EditPlus и WeBuilder.
Однако, хотя эти программы позволяют вам редактировать или изменять файлы PHP, они не позволяют вам фактически запускать сервер PHP. Для этого вам нужно что-то вроде веб-сервера Apache.
Как конвертировать файл PHP
См. документацию по jason_encode на PHP.net, чтобы узнать, как преобразовать массивы PHP в код Javascript в формате JSON (JavaScript Object Notation). Это доступно только в PHP 5.2 и выше.
Чтобы сгенерировать PDF-файлы из PHP, смотрите FPDF или dompdf.
Переименование файла таким образом не выполняет реальное преобразование файла, а просто позволяет правильной программе открыть файл. Реальные преобразования обычно происходят либо в инструменте преобразования файлов, либо в меню «Сохранить как» или «Экспорт» программы.
Как заставить PHP работать с HTML
Код PHP, встроенный в файл HTML, понимается как PHP, а не HTML, если он заключен в эти теги вместо общего тега HTML:
Иногда можно увидеть, что веб-страница использует PHP, посмотрев её URL, например, когда файл PHP по умолчанию называется index.php. В этом примере это может выглядеть как http://www.examplesite.com/index.php
Дополнительная информация о PHP
PHP был портирован почти на все операционные системы и полностью бесплатен для использования. Официальный сайт PHP – это PHP.net. Есть целый раздел документации, который служит онлайн-руководством по PHP, если вам нужна помощь, чтобы узнать больше о том, что вы можете делать с PHP или как всё это работает. Ещё один хороший источник – W3Schools.
Первая версия PHP была выпущена в 1995 году и называлась Personal Home Page Tools (инструменты PHP). Изменения проводились на протяжении многих лет, новые версии выпускались каждые несколько месяцев.
Скрипты на стороне сервера – наиболее распространенное применение PHP. Как описано выше, это работает с синтаксическим анализатором PHP, веб-сервером и веб-браузером, где браузер обращается к серверу, на котором выполняется программное обеспечение PHP, так что браузер может отображать всё, что производит сервер.
Другой сценарий командной строки, где не используются ни браузер, ни сервер. Эти типы реализаций PHP полезны для автоматизированных задач.
Описание расширения PHP. Чем открыть файл с расширением PHP?
Расширение PHP
Чем открыть файл PHP
В Windows: Adobe Dreamweaver CS5, Adobe Creative Suite, Adobe Contribute, Eclipse PHP Development Tools, MPSoftware phpDesigner, ES-Computing EditPlus, Notepad++, Microsoft Windows NotePad, Microsoft Expression Web, Zend Studio, PHPEdit, Apache Web Server с PHP, WampServer, Любой другой вэб-браузер, Любой другой текстовый редактор
В Mac OS: Adobe Dreamweaver CS5, Zend Studio for Mac, TextEdit, Adobe Creative Suite for Mac, Eclipse PHP Development Tools, MacroMates TextMate, Bare Bones BBEdit, Bare Bones TextWrangler, MAMP, Apache Web Server с PHP, Любой другой вэб-браузер, Любой другой текстовый редактор
В Linux: Eclipse PHP Development Tools, gedit, Apache Web Server с PHP, Любой другой вэб-браузер, Любой другой текстовый редактор
Кроссплатформенное ПО: PHP (Hypertext PreProcessor)
Описание PHP
Популярность:
Разработчик: Расмус Лердорф (версии 1.0, 2.0), Энди Гутманс и Зеев Сураски (все версии начиная с 3.0)
Расширение PHP используется для файлов, написанных на языке PHP. Ранее назывался как «Инструменты для создания персональных веб-страниц» (англ. «Personal Home Page Tools»), «PHP препроцессор гипертекста» (англ. PHP Hypertext Preprocessor) является файлом с открытым исходным кодом на стороне сервера, написанным на скриптовом языке. PHP очень популярен для разработки веб-приложений, потому что программисты могут использовать его и легко создавать веб-страницы с динамическим содержимым, которые взаимодействуют с базами данных.
.PHP в настоящее время является наиболее распространенным серверным языком сценариев. Это проект с открытым кодом, разработанный специально для быстрой разработки динамических веб-страниц, и может работать либо как модуль Apache или как CGI, или на менее распространенных веб-серверах. Язык сценариев PHP является нестрого типизированным и имеет гигантский встроенный набор функций и синтаксис похож и на Perl, и C++. Почти каждый веб-хостинг во всем мире поддерживает PHP, что означает, что вы можете переключиться, когда вы найдете более дешевый план.
Mime тип: application/x-httpd-php, text/php, application/php, magnus-internal/shellcgi, application/x-php
Файл формата PHP: чем открыть, описание, особенности
Файлы такого формата содержат в себе язык программирования php. Открыть php файл можно специальным П.
Файлы такого формата содержат в себе язык программирования php. Открыть php файл можно специальным ПО, либо в окне браузера. Помимо файлов для программирования сайтов есть три разновидности php-расширения, которые применяются в отдельных нераспространенных сервисах. Это слайд-шоу программы Callisto PhotoParade, рабочий файл CreataCard, содержащий автосохранения и файл издательской программы Microsoft Picture It! Они не так распространены, поэтому вероятность встретить их невелика. Как открыть php файл для веб-программирования, расскажем ниже.
Общее описание формата PHP
Язык программирования PHP в 1995 году разработал датский программист Расмус Релдорф. Спустя два года после выхода первой версии Релдорф выпустил улучшенный вариант. Его стал использовать каждый сотый домен в интернете. В 1998 году документ переделали израильские программисты, которые в дальнейшем продолжили заниматься проектом. Их версия получила название PHP 3.0. На сегодняшний день используется 7.0.0 версия, выпущенная в 2015 году. Язык PHP находится на 6 месте по популярности, на нем написаны интернет-гиганты Facebook и Wikipedia.
У расширения язык без конкретного назначения. Он наиболее распространен при разработке веб-приложений и динамических сайтов. Своей популярностью язык обязан широким выбором встроенных и внешних инструментов для разработки, совместимости с системами управления баз через дополнительные модули, взаимодействию с куками и сессиями и так далее.
Как и чем открыть файл php расширения
Файл php открыть не так просто, как html. Есть два способа: программный и браузерный. В двух случаях нужен интерпретатор, либо специальное ПО, причем важно отметить, что запустить php и открыть – не одно и то же.
Открыть php в браузере
Чтобы понять, как открыть файл php в браузере, важно понять отличие php от html. Последний открывается на стороне клиента – то есть в браузере, а php – на сервере. Чтобы запустить php, нужно либо приобрести домен и работать с php на нем, либо установить локальный сервер на компьютере. Последний способ предпочтительнее, поскольку бесплатный и позволяет создавать безграничное количество сайтов, которые хранятся на вашем ПК.
Есть три основных вида локальных серверов:
После установки локального сервера на компьютере необходимо создать сайт.
Затем в папке сервера необходимо найти папку под названием «home», в ней создаете еще одну и называете ее как домен будущего сайта. Далее создаем еще одну папку и называем «www», в нее перетаскиваем нужные документы.
Далее запускаем браузер и в адресной строке пишем название сайта/название файла php. После нажатия на «Enter», php запускается в виде приложения, а не текстового кода. Это позволяет тестировать интерактивные возможности получившейся страницы.
Открыть php на компьютере
Способов, чем открыть файл php на компьютере достаточно много. Так как они открываются в текстовом формате, специализированные редакторы программного кода смогут работать с php.
Чем открыть php:
Некоторые программы из перечисленных работают только на Windows, поэтому в случае использования на других ОС проверьте совместимость перед установкой.
Что такое PHP? Пишем свою первую программу на PHP
PHP — что это такое? PHP – язык программирования, который исполняется на стороне сервера, в то время как JavaScript исполняется в браузере на стороне пользователя.
Прочитав эту статью о PHP программировании, вы узнаете :
Сценарный язык vs программный язык
Программный язык | Сценарный язык |
Предлагает свойства, необходимые для разработки полноценных приложений. | В основном используется для выполнения рутинных задач. |
Перед исполнением код нужно компилировать. | Код исполняется без компиляции. |
Необязательно встраивать в другие языки. | Обычно встраивается в другие программные среды. |
Как расшифровывается PHP?
PHP-код можно встраивать в HTML или использовать в CMS и веб-фреймворках.
Что такое PHP?
PHP — язык программирования, который активно используется в разработке:
PHP-скрипты могут быть выполнятся только на тех серверах, где установлен интерпретатор данного языка.
Синтаксис PHP
На рисунке, приведенном ниже, демонстрируется базовая архитектура веб-приложения и процесс обработки запросов сервером. Это важно знать при изучении PHP программирования с нуля:
Зачем нужен PHP?
Для чего используется PHP и какова его доля на рынке?
На основе PHP работает более 20 миллионов сайтов и веб-приложений:
PHP vs ASP.NET vs JSP vs CFML
ASP – Active Server Pages.
JSP – Java Server Pages.
CFML – Cold Fusion Markup Language.
В таблице ниже язык программирования PHP сравнивается с различными серверными языками.
Файловые расширения PHP
Сами PHP-теги не чувствительны к регистру, но настоятельно рекомендуется использовать нижний регистр:
Мы расцениваем строки PHP-кода как выражения. Они оканчиваются точкой с запятой ( ; ). Если у вас будет только одно выражение, то точку с запятой можно опустить. Если выражений больше одного, то каждая строка должна завершаться точкой с запятой.
PHP Hello World
Резюме
Пожалуйста, опубликуйте свои комментарии по текущей теме материала. Мы очень благодарим вас за ваши комментарии, подписки, дизлайки, отклики, лайки!
Дайте знать, что вы думаете по этой теме статьи в комментариях. За комментарии, отклики, лайки, подписки, дизлайки низкий вам поклон!
Создание расширений PHP: Введение в PHP и Zend
Если вы читаете данную статью, скорее всего у вас есть некоторый интерес к созданию расширений для языка PHP. Если же нет… возможно, когда вы прочтёте эту статью, то обнаружите в себе этот интерес, не смотря на то, что вы о нём даже не подозревали!
Материал, изложенный в данной статье, подразумевает знакомство как с самим языком PHP, так и с языком, на котором написан интерпретатор PHP: C.
Что такое Расширение?
Если вам приходилось использовать PHP, то вы использовали и расширения. За небольшим исключением каждая доступная для использования функция в языке PHP сгруппирована в то или иное расширение. Основная часть функций (более 400) входит в состав стандартного расширения. Исходные коды PHP распространяются с порядка 86 расширениями, имеющими примерно по 30 функций в каждом. Посчитав, получим где-то 2500 функций в сумме. Если этого не достаточно, репозитарий PECL предлагает свыше 100 дополнительных расширений, ещё больше можно найти на бескрайних просторах интернета.
«Что же, с учётом всего этого множества функций, живущих в расширениях, тогда остаётся вне расширений?» — спросите вы. «Что расширения расширяют? Что такое ядро PHP?»
Ядро PHP реализовано в виде 2-х отдельных частей. Техническая часть языка представлена в виде Zend Engine (ZE). ZE отвечает за преобразование понятного для человека скрипта в понятные для компьютера токены (tokens), после чего выполняет их. Кроме того, ZE отвечает за управление памятью, область видимости переменных, обработку вызова функций.
Второй частью ядра является то, что непосредственно называется «ядром» (the PHP core). Оно отвечает за взаимодействие со слоем SAPI (Server Application Programming Interface, интерфейс взаимодействия PHP с другим серверным ПО — CLI, CGI, Apache и так далее). Кроме того, ядро реализует обобщённый слой контроля для проверок safe_mode и open_basedir (данные фичи объявлены depricated с версии 5.3), так же, как и слой потоков, который ассоциирует файловые и сетевые I/O операции с функциями fopen, fread и fwrite.
Жизненный цикл
Когда происходит запуск заданного SAPI (например, при запуске сервера Apache по команде /usr/local/apache/bin/apachectl start), PHP начинает свою работу с запуска подсистемы ядра. К концу процедуры запуска он загружает код каждого расширения и вызывает его функцию Module Initialization (MINIT). Это даёт каждому расширению возможность инициализировать внутренние переменные, выделить память под ресурсы, зарегистрировать обработчики ресурсов и свои функции в ZE, что бы при вызове каким-нибудь скриптом функции этого расширения ZE знал, какой код ему выполнять.
Далее PHP ждёт от слоя SAPI запроса на обработку страницы. В случае CGI или CLI SAPI это происходит незамедлительно и только один раз. В случае SAPI Apache, IIS или другого полноценного web-сервера запрос на обработку страницы происходит каждый раз при запросе (возможно конкурентном) страницы удалённым пользователем. Однако, вне зависимости от того, каким образом пришёл запрос, его обработка начинается с того, что ядро PHP просит ZE настроить окружающую среду для запуска скрипта, после чего вызывает функцию Request Initialization (RINIT) для каждого расширения. RINIT даёт расширениям возможность настроить специфичные переменные окружения, выделить память для специфичных ресурсов запроса и выполнить другие задания. Наглядным примером функции RINIT в действии может служить расширение session, в котором при включенной настройке session.auto_start функция RINIT автоматически вызывает исполнение функции session_start и инициализирует переменную $_SESSION.
После того, как запрос инициализирован, ZE транслирует PHP скрипт в токены, а затем в опкоды (opcodes), которые он может выполнить. Если какой-нибудь из этих опкодов запрашивает вызов функции из расширения, ZE формирует аргументы для вызова этой функции и временно передаёт ей управление до её завершения.
После того как скрипт завершил своё выполнение, PHP вызывает функцию Request Shutdown (RSHUTDOWN) для каждого расширения, что выполнить все необходимые для завершения чистки (например, сохранение сессионных переменных на диск). Следующим шагом ZE выполняет процесс чистки (также известный как сборка мусора), который фактически выполняет метод unset для каждой переменной, использованной в выполненном скрипте (начиная с PHP 5.3 механизм сборки мусора значительно улучшен).
Завершив обработку запроса, PHP ждёт от SAPI либо запроса на обработку другого скрипта, либо сигнала на завершение. В случае CGI или CLI SAPI «следующий запрос» невозможен, поэтому SAPI инициализирует завершение работы PHP незамедлительно. В процессе завершения PHP перебирает все расширения и для каждого вызывает функцию Module Shutdown (MSHUTDOWN), после чего завершает свою собственную подсистему ядра.
Этот процесс поначалу может показаться немного запутанным, но, погрузившись в работу над расширениями, вы постепенно прочувствуете его.
Выделение памяти
Для того, что бы избежать утечек памяти в плохо написанных расширениях, ZE использует свой собственный внутренний механизм управления памятью, основанный на дополнительном флаге для определения времени жизни данных. Постоянное (persistent) выделение памяти означает, что память будет выделена более, чем на время обработки запроса одной страницы. Непостоянное (non-persistent) выделение памяти означает освобождение памяти после обработки запроса вне зависимости от того, была ли вызвана функция освобождения памяти. К примеру, выделение памяти под пользовательские переменные носит непостоянный характер, так как по завершению обработки запроса они становятся бесполезными.
Несмотря на то, что расширение в теории может возложить на ZE освобождение непостоянной памяти автоматически по завершению каждого запроса, делать это не рекомендуется. Выделенная память будет оставаться долгое время невостребованной, ассоциированные с этой памятью ресурсы будут иметь меньше шансов быть закрытыми правильно, и, в конце концов, создание путаницы с освобождением памяти — плохая практика. Как вы увидите позже, убедиться, что все данные отчищены верно, достаточно легко.
Давайте кратко сравним традиционные функции выделения памяти (которые стоит использовать только при работе с внешними библиотеками) с функциями постоянного и непостоянного выделения памяти в PHP/ZE.
Традиционные | Непостоянные | Постоянные |
---|---|---|
malloc(count) | emalloc(count) | pemalloc(count, 1) * |
calloc(count, num) | ecalloc(count, 1) | pecalloc(count, num, 1) |
strdup(str) | estrdup(str) | pestrdup(str, 1) |
strndup(str, len) | estrndup(str, len) | pemalloc() & memcpy() |
free(ptr) | efree(ptr) | pefree(ptr, 1) |
realloc(ptr, newsize) | erealloc(ptr, newsize) | perealloc(ptr, newsize, 1) |
malloc(count * num + extr) ** | safe_emalloc(count, num, extr) | safe_pemalloc(count, num, extr) |
* Семейство функций pemalloc принимает в качестве параметра флаг «постоянности», который позволяет им вести себя как их непостоянные аналоги.
К примеру: emalloc(1234) тоже самое, что и pemalloc(1234, 0)
** safe_emalloc() и (в PHP 5) safe_pemalloc реализуют дополнительную проверку целочисленных переполнений.
Настройка и сборка окружения
Теперь, когда вы ознакомились с теорией работы PHP и Zend Engine, могу поспорить, вам не терпится погрузиться в работу и начать что-нибудь делать. Однако, перед этим вам нужно обзавестись кое-какими утилитами для сборки и настроить окружение для ваших целей.
Прежде всего, вам необходим сам PHP и набор средств сборки, необходимых для PHP. Если вам не приходилось собирать PHP из исходников, предлагаю взглянуть на эту статью. Несмотря на то, что использование бинарного пакета с исходниками PHP может показаться заманчивым, такие сборки зачастую лишены двух важных параметров программы ./configure, которые очень полезны во время процесса разработки. Первый из них это —enable-debug. Эта опция компилирует PHP с дополнительной отладочной информацией в исполняемых файлах, так что при возникновении ошибки сегментации (segfault) вы сможете получить дамп ядра и воспользоваться отладчиком gdb, что бы выяснить, где и почему произошла ошибка.
Название второй опции зависит от того, с какой версией PHP вы собираетесь работать. В PHP 4.3 она называется —enable-experimental-zts, начиная с PHP 5, она переименована в —enable-maintainer-zts. Эта опция заставит PHP думать, что он работает в многопотоковой (multithread) среде, и позволит вам отловить общие ошибки, которые незаметны в среде без потоков, но повлекут нестабильную работу вашего расширения в многопотоковой среде.
Скомпилировав PHP с дополнительными опциями и установив его на сервер разработки (или рабочую станцию), вы можете преступать к созданию своего первого расширения.
Hello World
#ifndef PHP_HELLO_H
#define PHP_HELLO_H 1
#define PHP_HELLO_WORLD_VERSION «1.0»
#define PHP_HELLO_WORLD_EXTNAME «hello»
extern zend_module_entry hello_module_entry;
#define phpext_hello_ptr &hello_module_entry
#include «php.h»
#include «php_hello.h»
static function_entry hello_functions[] = <
PHP_FE(hello_world, NULL)
>;
zend_module_entry hello_module_entry = <
#if ZEND_MODULE_API_NO >= 20010901
STANDARD_MODULE_HEADER,
#endif
PHP_HELLO_WORLD_EXTNAME,
hello_functions,
NULL,
NULL,
NULL,
NULL,
NULL,
#if ZEND_MODULE_API_NO >= 20010901
PHP_HELLO_WORLD_VERSION,
#endif
STANDARD_MODULE_PROPERTIES
>;
#ifdef COMPILE_DL_HELLO
ZEND_GET_MODULE(hello)
#endif
str = estrdup( «Hello World» );
RETURN_STRING(str, 0);
>
В этом примере вы вручную выделили непостоянную память для строки «Hello World», которую передали обратно в вызывающий скрипт с помощьюфункции RETURN_STRING, указав ей 0 в качестве второго параметра, что заставляет функцию не делать копию строки, так как она может воспользоваться нашей.
Сборка расширения
Если всё пойдёт так, как должно, вы увидите строку Hello World в качестве результата работы скрипта, так как функция hello_world из загруженного расширения возвращает строку, а команда echo отображает то, что ей было передано на вход (в данном случае – результат работы функции hello_world).
В данном примере мы возвращали строку, другие скалярные типы данных могут быть возвращены по схожему принципу: RETURN_LONG для целочисленных значений, RETURN_DOUBLE для чисел с плавающей точкой, RETURN_BOOL для TRUE/FALSE и RETURN_NULL для, как вы догадались, NULL-значений. Давайте посмотрим на каждую из них в действии, добавив строки с макросом PHP_FE в структуру function_entity и соответствующие им макросы PHP_FUNCTION в файле hello.c:
static function_entry hello_functions[] = <
PHP_FE(hello_world, NULL)
PHP_FE(hello_long, NULL)
PHP_FE(hello_double, NULL)
PHP_FE(hello_bool, NULL)
PHP_FE(hello_null, NULL)
>;
PHP_FUNCTION(hello_world);
PHP_FUNCTION(hello_long);
PHP_FUNCTION(hello_double);
PHP_FUNCTION(hello_bool);
PHP_FUNCTION(hello_null);
Так как вы не вносили изменений в файл config.m4, технически нет необходимости повторять шаги phpize и ./configure, а можно сразу перейти к выполнению команды make. Тем не менее, на этот раз я попрошу вас пройти через все три шага сборки заново с целью убедиться, что никаких проблем не возникло. Кроме того, в качестве последнего шага вы можете использовать команду make clean all вместо make, что бы быть уверенным, что все файлы с исходниками будут пересобраны. Повторюсь, что это не необходимо ввиду типа изменений, которые вы сделали, но лучше перестраховаться, чем наткнуться на ошибку. После того, как модуль собран, вам остаётся скопировать его в каталог расширений, заменив им старую версию.
Сейчас вы можете снова вызвать интерпретатор PHP, передав ему нехитрые скрипты для того, что бы протестировать только что добавленные функции. На самом деле – почему бы ни сделать это сейчас? Я подожду вас здесь…
Готово? Хорошо. Если для просмотра результата работы каждой функции вы использовали var_dump, а не echo, то, возможно, обратили внимание, что hello_bool возвращает TRUE. Это результат равенства 1-це аргумента функции. Также как и в PHP-скриптах, целочисленное значение 0 эквивалентно FALSE, в то время как любое другое число эквивалентно TRUE. Авторы расширений зачастую используют соглашение, согласно которому этим числом является 1. Желательно, но не обязательно, что бы и вы придерживались этого соглашения. Кроме того, для большего удобства доступны макросы RETURN_TRUE и RETURN_FALSE. Ниже приведён пример функции hello_bool с использованием макроса RETURN_TRUE.
Обратите внимание, что никаких круглых скобок при вызове макроса не использовалось. В этом плане макросы RETURN_TRUE и RETURN_FALSE отличаются от остальных макросов семейства RETURN_*, так что будьте внимательны и не попадитесь на этом!
Вы, возможно, заметили, что во всех предыдущих примерах мы не передаём параметр, отвечающий за создание копии результата. Причина этого в том, что для таких простых скалярных величин не требуется выделение или освобождение дополнительной памяти.
Существуют ещё 3 дополнительных возвращаемых типа: RESOURCE (возвращаемый, к примеру, функциями mysql_connect, fsockopen или ftp_connect), ARRAY (также известный как HASH) и OBJECT (возвращаемый по ключевому слову new). Речь о них пойдёт позже.
INI-настройки
Zend Engine предоставляет два подхода для работы с INI-данными. Сейчас мы рассмотрим наиболее простой из них, а к более общему вернёмся после ознакомления с глобальными переменными.
Предположим, вы хотите объявить в файле php.ini настройку hello.greeting для вашего расширения, которая будет содержать значение для вывода функцией hello_world. Для этого нам придётся добавить несколько изменений в файлы hello.c и php_hello.h в рамках изменения структуры hello_module_entry. Начнём с добавления следующих прототипов перед списком прототипов пользовательских функций в файле php_hello.h:
PHP_FUNCTION(hello_world);
PHP_FUNCTION(hello_long);
PHP_FUNCTION(hello_double);
PHP_FUNCTION(hello_bool);
PHP_FUNCTION(hello_null);
zend_module_entry hello_module_entry = <
#if ZEND_MODULE_API_NO >= 20010901
STANDARD_MODULE_HEADER,
#endif
PHP_HELLO_WORLD_EXTNAME,
hello_functions,
PHP_MINIT(hello),
PHP_MSHUTDOWN(hello),
NULL,
NULL,
NULL,
#if ZEND_MODULE_API_NO >= 20010901
PHP_HELLO_WORLD_VERSION,
#endif
STANDARD_MODULE_PROPERTIES
>;
#include «php.h»
#include «php_ini.h»
#include «php_hello.h»
PHP_FUNCTION(hello_world)
<
RETURN_STRING(INI_STR( «hello.greeting» ), 1);
>
Обратите внимание, что вы создаёте копию значения, полученного от INI_STR. Причина в том, что строка, возвращаемая INI_STR является статической. Другими словами, если вы попытаетесь её изменить рабочее окружение PHP может стать нестабильным или даже аварийно завершиться.
Первый набор внесённых в этой главе изменений добавляет два новых метода, с которыми вы должны быть уже знакомы: MINIT и MSHUTDOWN. Как упоминалось ранее, эти методы вызываются при первом запуске SAPI-слоя и в процессе завершения его работы соответственно. Они не вызываются в течение или между запросами. В этом примере они используются для регистрации записей из файла php.ini, объявленных в вашем расширении. Также в этих функциях могут быть зарегистрированы ресурсы, объекты и обработчики потоков.
Последний четвёртый параметр позволяет указать функцию обратного вызова (callback), вызываемую при изменении настройки с помощью функции ini_set. Это позволяет расширениям производить более полный контроль над условиями изменения настройки или вызывать соответствующую функцию в зависимости от нового значения настройки.
Глобальные переменные
Довольно часто расширению требуется обработать переменную в отдельном запросе, сохраняя её значение независимым от других запросов, которые могут обрабатываться в тоже самое время. В немногопоточном SAPI это можно сделать очень просто: всего лишь объявите глобальную переменную в файле с исходным кодом и обращайтесь к ней, когда вам нужно. Проблема в том, что, так как PHP спроектирован для работы с многопоточными web-серверами (такими как Apache 2 и ISS), ему необходимо хранить глобальные переменные, используемые одним потоком, отдельно от глобальных переменных другого. PHP значительно упрощает эту задачу благодаря использованию слоя абстракции TSRM (Thread Safe Resource Manager) иногда называемого ZTS (Zend Thread Safety). Фактически в данной статье уже использовались части TSRM, чего вы даже не заметили. (Не пытайтесь найти их, так как пока для вас это слишком сложно).
Первая часть создания потокобезопасной глобальной переменной, как и любой другой глобальной переменной, заключается в её объявлении. В качестве примера мы объявим одну глобальную переменную типа long, начальным значением которой будет 0. Каждый раз, когда функция hello_long будет вызываться, мы будем увеличивать значение глобальной переменной и возвращать её значение.
Добавьте следующий фрагмент кода в файл php_hello.h сразу после строки #define PHP_HELLO_H:
ZEND_BEGIN_MODULE_GLOBALS(hello)
long counter;
ZEND_END_MODULE_GLOBALS(hello)
#ifdef ZTS
#define HELLO_G(v) TSRMG(hello_globals_id, zend_hello_globals *, v)
#else
#define HELLO_G(v) (hello_globals.v)
#endif
PHP_MINIT_FUNCTION(hello);
PHP_MSHUTDOWN_FUNCTION(hello);
PHP_RINIT_FUNCTION(hello);
#include «php.h»
#include «php_ini.h»
#include «php_hello.h»
zend_module_entry hello_module_entry = <
#if ZEND_MODULE_API_NO >= 20010901
STANDARD_MODULE_HEADER,
#endif
PHP_HELLO_WORLD_EXTNAME,
hello_functions,
PHP_MINIT(hello),
PHP_MSHUTDOWN(hello),
PHP_RINIT(hello),
NULL,
NULL,
#if ZEND_MODULE_API_NO >= 20010901
PHP_HELLO_WORLD_VERSION,
#endif
STANDARD_MODULE_PROPERTIES
>;
И измените вашу функцию MINIT вместе с добавлением ещё нескольких функций для обработки инициализации при старте запроса:
static void php_hello_init_globals(zend_hello_globals *hello_globals)
<
>
PHP_RINIT_FUNCTION(hello)
<
HELLO_G(counter) = 0;
PHP_MINIT_FUNCTION(hello)
<
ZEND_INIT_MODULE_GLOBALS(hello, php_hello_init_globals, NULL);
В изменениях, которые вы внесли в файл php_hello.h, вы использовали пару макросов – ZEND_BEGIN_MODULE_GLOBALS и ZEND_END_MODULE_GLOBALS. С их помощью была определена структура zend_hello_globals, содержащая одну переменную типа long. После этого был определён макрос HELLO_G, позволяющий в зависимости от режима компиляции (с учётом или без многопоточности) получать значение из пула потоков или просто взять его из глобальной области видимости.
В файле hello.c с помощью макроса ZEND_DECLARE_MODULE_GLBALS вы объявили структуру zend_hello_globals либо как глобальную (при непотокобезопасной сборке), либо как член пула ресурсов потока. Нам как авторам расширения не нужно задумываться об этом механизме, так как всю работу берёт на себя ZE. И, наконец, вы используете функцию ZEND_INIT_MODULE_GLOBALS для выделения идентификатора потокобезопасного ресурса.
Возможно, вы заметили, что функция php_hello_init_globals на самом деле ничего не делает. Кроме того, инициализация счётчика значением 0 оказалась в функции RINIT. Почему?
Ключ к ответу на этот вопрос кроется в моменте, когда эти функции вызываются. Функция php_hello_init_globals вызывается только при запуске нового процесса или потока. Однако, каждый процесс может обслуживать более одного запроса, так что использование этой функции для инициализации нашего счётчика значением 0 будет верно только для первого запроса. Последующий запрос к этому же процессу по прежнему будет работать со старым значением счётчика и, следовательно, не будет начинать отчёт с нуля. Для инициализации счётчика значением 0 для каждого запроса мы использовали функция RINIT, которая, как вы уже читали, вызывается перед каждым запросом обработки скрипта. Мы включили функцию php_hello_init_globals в наш код как минимум из-за того, что передача NULL в качестве соответствующего параметра ZEND_INIT_MODULE_GLOBALS функции init приведёт к ошибке сегментации для платформ без поддержки потоков.
INI-настройки и глобальные переменные
ZEND_BEGIN_MODULE_GLOBALS(hello)
long counter;
zend_bool direction;
ZEND_END_MODULE_GLOBALS(hello)
static void php_hello_init_globals(zend_hello_globals *hello_globals)
<
hello_globals->direction = 1;
>
PHP_FUNCTION(hello_long)
<
if (HELLO_G(direction)) <
HELLO_G(counter)++;
> else <
HELLO_G(counter)—;
>
Вот и всё! С помощью метода OnUpdateBool (метод является часть ZE), переданного в качестве третьего параметра макроса STD_PHP_INI_ENTRY, будет производиться автоматическое приведение типа значения настройки, полученного из файла php.ini, .htaccess, или с помощью функции ini_set, к соответствующему значению TRUE/FALSE, которое вы можете получить прямо внутри скрипта. Последние три параметра функции STD_PHP_INI_ENTRY указывают PHP, какую глобальную переменную изменить, как выглядит структура глобальных переменных нашего расширения, и имя контейнера глобальных переменных, в котором они содержаться.
Что дальше?
В этой статье мы разобрали структуру простого PHP расширения, которое экспортирует функции, возвращающие значения, загружает и обрабатывает INI-настройки, сохраняя их на протяжении обработки запроса.
В следующей статье мы рассмотрим внутреннюю структуру переменных PHP, способы их хранения и обработки. Поработаем с функцией zend_parse_parameters, используемой для получения параметров из программы при вызове функции, и откроем способы возвращения более сложных результатов из функции, таких как массив, объект и ресурс.
В некоторых местах перевод имеет довольно вольный формат, что является следствием трудностей перевода, которые мне не удалось преодолеть в полной мере. Кроме того перевод содержит некоторое количество мелких дополнений, показавшихся мне актуальными.
Процесс сборки расширения согласно статье проверен на исходниках PHP 5.3.2.
У автора есть несколько статей по данной тематике: 1, 2.1, 2.2, 3. Четвёртая статья видимо так и не увидит свет ввиду публикации автором книги «Extending and Embedding PHP», посвящённой данной тематике.