403

Использование преимуществ встроенного PHP сервера

Одним из крутейший новшеств в php 5.4 является встроенный сервер, созданный специально для разработки и тестирования. Теперь вы можете писать и тестировать свой код не имея полноценного веб-сервера — просто запустите встроенный сервер, протестируйте свой код, и выключите его, когда закончите.
Сервер, так же, предоставляет возможность и для творческого использования. Например, вы можете распространять портативное web-приложение на CD или USB, или даже как десктопное приложение, созданное на PHP без использования GTK или других графических библиотек.

В мануале PHP подчеркивается, что встроенный сервер предназначен для разработки и рекомендуется не использовать его на боевом сервере. Отсутствуют какие-либо INI директивы отвечающие за сервер (за исключением раскрашивания вывода в консоли), и, кажется, что основная идея документации: «у нас теперь тоже есть Web сервер, отстаньте от нас».
Несмотря на это, я считаю, что встроенные сервер может быть ценным инструментом для разработки и тестирования. К примеру, на моей машине я использую предустановленный Apache с кастомной конфигурацией, подходящей для меня, но иногда я хочу попробовать какие-либо новые Web-приложения. Со встроенным web-сервером я могу протестировать приложение прямо из папки «downloads» или временной папки и переместить в обычную среду, только тогда, когда это будет необходимо.
Но для начала, это не так просто, ведь многие написанные приложения используют .htaccess и mod_rewrite. Но я уверен, что кто-то (может быть один из вас, почему бы и нет?) напишет адаптер для этого, и я хотел бы быть первым, кто протестируют его.
В этой статье я объясню некоторые основные примеры использования встроенного сервера и покажу вам как сделать его полезным для разработки и тестирования.

Читайте также:  Телефоны поддерживают java приложения

Используем встроенный сервер

и найдите там описание параметров «-S» и «-t», которые используются только для сервера.
Для проверки сервера вы можете создать в текущей директории файл index.php, который будет содержать в себе вызов функции phpinfo() и затем запустить сервер:

[ec2-user@ip-10-229-67-156 ~]$ php -S 127.0.0.1:8080 PHP 5.4.0RC7 Development Server started at Fri Feb 26 18:49:29 2012 Listening on 127.0.0.1:8080 Document root is /home/ec2-user Press Ctrl-C to quit. 

image

И теперь вы можете увидеть содержимое отданной встроенным web-сервером:

В консоль же будет писаться каждый запрос клиента:

[Sun Feb 26 18:55:30 2012] 80.180.55.37:36318 [200]: / [Sun Feb 26 18:56:23 2012] 80.180.55.37:36584 [200]: / 

Возвращаясь назад, разберем параметр командной строки «-S», который используется для указания адреса, с которого сервер будет доступен. Возможные значения:
localhost — сервер будет доступен только с локальной машины,
0.0.0.0 — на любому интерфейсе машины,
Любой внешний или серый IP — только на указанном IP
Параметр «-t» устанавливает указанную директорию «directory root». Например:

[ec2-user@ip-10-229-67-156 ~]$ php -S :8090 -t /home/ec2-user/public 
[ec2-user@ip-10-229-67-156 ~]$ php -S >localhost or your public IP>:8080 -t /home/ec2-user/public public/index.php 

Если скрипт вернет FALSE, тогда запрашиваемый URI будет обрабатываться сервером, который будет выдавать запрошенный ресурс, либо вернет 404 ошибку. Если скрипт возвращает что-либо ещё, вывод скрипта передастся клиенту.
Хотя данный подход даёт нам больше контроля, есть несколько вещей, которые вы должны знать. Во-первых, PHP сервер отдаёт только минимальный набор HTTP заголовков:

Connection: closed Content-Type: text/html Host: aws-dev-01.vtardia.com X-Powered-By: PHP/5.4.0RC7 
Accept-Ranges: bytes Connection: Keep-Alive Content-Length: 631 Content-Type: text/html Date: Sat, 04 Feb 2012 18:24:42 GMT Etag: "bbb99-277-4ace8c5470a40" Keep-Alive: timeout=15, max=100 Last-Modified: Wed, 14 Sep 2011 15:54:09 GMT Server: Apache/2.2.21 (Unix) DAV/2 

Если ваше приложение использует заголовки, то оно должно учитывать разницу в development-среде и в production.
Во-вторых, встроенный сервер имеет другое SAPI (Server API). Таким образом выполняя маршрутизацию в index,php вы можете определить на тестовом или боевом сервер происходит обращение к скрипту. php_sapi_name() вернет «cli-server» на встроенном сервере:

Существует одна специальная INI директива — «cli_server.color». Данная директива возвращает раскрашенный вывод в консоли. Создайте пустой файл с именем cli-server.ini и вставьте эту строку:

Вы можете создать уникальную конфигурацию окружения для вашего сервера, указав в вашем INI файле необходимые директивы. Не объявленные директивы примут значения по-умолчанию. Сейчас мы объявили только одну директиву — cli_server.color.
Запустить сервер с параметром «-c» с указанием INI файла:

[ec2-user@ip-10-229-67-156 ~]$ php -S localhost -c cli-server.ini 

Если ваш терминал поддерживает цвета, то вы сможете увидеть «цветной» вывод в консоли. 200 статус будет выделен зеленым, 404 — оранжевым, а ошибки сценария будут выделены красным цветом.

Создаём персональный сервер

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

Папка «library» содержит код приложения, «public» — корневая директория, содержит index.php и несколько статичных файлов. Особое внимание в этом руководстве будет уделено папке «server», и поэтому наше приложение будет состоять из простого «Hello Word!» и нескольких картинок и css.
Наша цель — получить возможность запускать сервер из директории приложения одной командой, а наш сервер будет заботиться о роутинге, HTTP заголовках и ошибках.

[ec2-user@ip-10-229-67-156 myapp]$ ./start.sh 
#! /bin/bash INIFILE="$(pwd)/server/server.ini" DOCROOT="$(pwd)/public" ROUTER="$(pwd)/server/router.php" HOST=0.0.0.0 PORT=8080 PHP=$(which php) if [ $? != 0 ] ; then echo "Unable to find PHP" exit 1 fi $PHP -S $HOST:$PORT -c $INIFILE -t $DOCROOT $ROUTER 

Я предполагаю, что скрипт запускается из директории приложения, поэтому INIFILE, DOCROOT, ROUTER определяются используя pwd. Путь до php определяется используя команду which. Если php не был найден в пользовательском $PATH, то скрипт завершит работу ошибкой.
Данный способ работает достаточно хорошо, но давайте предоставим пользователю возможность изменить любой из заданных параметров из командной строки, например:

if [ ! -z $INIFILE ]; then INIFILE="$(pwd)/server/server.ini" fi 

Продолжим, папка «errors» содержит файлы для сообщений об HTTP ошибках. Вот пример о 403 ошибке: хотя я и использовал только HTML, скрипт будет подключен, использую include, поэтому вы можете использовать любой php код:

      

403: Forbidden

Sorry, the requested resource is not accessible.

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

 // Parse allowed host list if (!empty($config['hostsAllowed'])) < if (!in_array($_SERVER['REMOTE_ADDR'], $config['hostsAllowed'])) < logAccess(403); http_response_code(403); include ERRORS . '/403.php'; exit; >> // if requesting a directory then serve the default index $path = parse_url($_SERVER["REQUEST_URI"], PHP_URL_PATH); $ext = pathinfo($path, PATHINFO_EXTENSION); if (empty($ext)) < $path = rtrim($path, "/") . "/" . DIRECTORY_INDEX; >// If the file exists then return false and let the server handle it if (file_exists($_SERVER["DOCUMENT_ROOT"] . $path)) < return false; >// default behavior logAccess(404); http_response_code(404); include ERRORS . "/404.php"; 

В первых строках я определяю некоторые глобальные параметры, такие как DIRECTORY_INDEX, директория с шаблонами ошибок. Параметр date_default_timezone_set() должен совпадать с настройками ОС, иначе будут несоответствия между записями в логе и на сервере. Так же я добавил список разрешенных IP адресов, для повышения безопасности.
Функция logAccess() необходима, потому что когда скрипт роутинга принимает запрос лог сервера по-умолчанию игнорируется. Функция принимает только код статуса, а формат вывода полностью соответствует формату сервера.
Наша первая задача — проверка безопасности. Если IP клиента не находится в массиве разрешенных IP, выводим сообщение об ошибке и завершаем работу скрипта. Нам необходимо отдавать код статуса отличный от 200 и функция header() не будет работать в здесь, поэтому мы используем новую функцию — http_response_code.
Если IP клиента находится в массиве разрешенных IP, то следующий наш шаг — получение запрашиваемого пути и расширения файла. Если расширение пустое, считаем, что пользователь запрашивает папку и строим получаем путь, используя определенный сначала DIRECTORY_INDEX.
В завершении, если запрашиваемый файл существует, возвращаем FALSE, и позволяем серверу обратиться к файлу. Если же нет, то отображается сообщение о 404 ошибке.

Резюме

Это всё. Как видите, php сервер просто в использовании. Наш персональный сервер очень прост. Код можно оптимизировать и включать в более сложные и функциональные классы. Happy coding!

p.s. С радостью приму критику и замечания к переводу в личку.

Источник

Разработка сервера на php и системных скриптов

На stackoverflow очень много вопросов типа «какой сервер поставить для разработки на php». Многие советуют apache2 и nginx+php-fpm. Но сегодняшняя статья о такой возможности, как встроенный сервер php.

Встроенный сервер в php появился начиная с версии 5.4.0, и запускается командой:

$ php -S localhost:8000 index.php

-S — запустить сервер
localhost — хост(ip address) на котором будет сервер
8000 — порт сервера
index.php — файл обработки запросов

Роутинг сервера осуществляется с помощью php-файла, выполняющего данные функции, так вот, если этот файл возвращает `false`, то будет запрошен файл напрямую; если же это не так, то будет обрабатываться файл, который мы указали как роутер.

К примеру, если в файл index.php добавить следующее условие:

То при запросе файлов статики они будут отданы напрямую сервером, а любой другой запрос будет обработан через index.php…

Часть 2. Пишем системный скрипт и сервер на php

И так как же написать системный скрипт для linux? Ответ довольно прост — первым делом мы должны указать интерпретатор, который будет выполнять этот скрипт. Так как мы пишем скрипт на php, то и укажем его интерпретатором в первой строке:

Далее опишем те параметры, которые принимает скрипт из консоли:

if(isset($argv[1])) < $host = $argv[1]; >else < help(); >if(isset($argv[2])) < $port = $argv[2]; >else

Два простых if’а, которые проверяют 1 и 2 аргумент, которые будут host и port соответственно, и если это не так, то выводит функцию help().

И, наконец, дописываем инструкцию, запускающую сервер.

system(sprintf('php -S %s:%s', $host, $port));

После того как скрипт готов, изменяем его права и закидываем в папку /usr/bin/server.

$ chmod 0777 server $ sudo cp server /usr/bin/server

Ну вот и всё, теперь нам остаёться только зайти в папку с проектом и запустить сервер командой.

Для доступа к веб части сервера, вводим в адресную строку localhost:8080 и переходим.

Вывод: Встроенный сервер php предназначен только для разработки, и это намного экономичнее apache2 и nginx+php-fpm…

Источник

Оцените статью