Создайте веб-сервер в PHP (без Apache)

Я просто пробовал этот код:

<?php
set_time_limit(0);

$address = '176.9.117.136';
$port = 9000;

$sock = socket_create(AF_INET, SOCK_STREAM, 0);
socket_bind($sock, $address, $port) or die('Could not bind to address');

while(1)
{
    socket_listen($sock);
    $client = socket_accept($sock);

    $input = socket_read($client, 1024);
    echo $input;

    $output = 'URL: http://ip-of-my-server:9000/
HTTP/1.1 200 OK
Date: Tue, 10 Jul 2012 16:58:23 GMT
Server: TestServer/1.0.0 (PHPServ)
Last-Modified: Fri, 06 Jul 2012 14:29:58 GMT
ETag: "13c008e-1b9-4c42a193de580"
Accept-Ranges: bytes
Content-Length: 441
Vary: Accept-Encoding
Content-Type: text/html

';
    socket_write($client, $output);

    socket_close($client);
}

socket_close($sock);
?>

Но есть проблема. Вместо использования содержимого $output в качестве заголовков Apache возвращает свои собственные заголовки...

Я не знаю, почему, потому что я выполняю script с помощью этой команды: php webserv.php.

Однако он практически работает, потому что, когда я загружаю страницу http://ip-of-my-server:9000/ из своего браузера, он показывает мне заголовки, отправленные клиентом на сервере, и возвращает содержимое $output клиенту (моему браузеру).

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

Ответ 1

Есть ли причина для внедрения HTTP-сервера в PHP (из всех вещей)? Там нет нитей и т.д. Было бы боль... (если это не какая-то академическая вещь...)

PHP 5.4 поставляется с встроенным веб-сервером. Возможно, это то, что вы ищете...


Update:

В то время как я понимаю вашу мотивацию изучать подобные вещи, я считаю, что вы ошибаетесь, пробовав подобные вещи с помощью PHP. PHP не предназначен для длительных процессов (например, для сервера), он не предназначен для параллельной обработки (потоков). Даже для многопроцессорной обработки потребуется PCNTL, в частности pcntl_fork() и ограничьте свою образовательную прогулку до системы на базе Unix (это может быть и не проблема).

Если ваша цель - понять, как серверы работают с concurrency, я предлагаю играть с языком, предназначенным для этого (Erlang, Go, Scala,...). Или играйте на языке, который, по крайней мере, эмулирует параллельную обработку (Python, Ruby,... [вроде, из-за их GILs]).

Если ваша цель - понять HTTP (и позвольте мне сказать вам, что HTTP - это зверь, если вы проходите мимо HTTP/1.0 и хотите сделать это правильно), fiddling с PHP может быть прекрасным, если это единственный язык вы уверены. Если да, посмотрите на код примера (чат-сервер) в этой (грустно немецкой) статье на Socket Servers в PHP, чтобы получить основной материал сокета, который концентрируется на фактическом HTTP.


Обновление 2:

Чтобы ответить на вопрос о заголовках... Я не знаю, как apache будет вписываться в сценарий, описанный в вашем вопросе. Но я вижу, что вы используете разрывы строк, чтобы разграничить заголовки и двойной разрыв строки, чтобы разграничить заголовки. Если вы не сохранили ваш php файл, используя \r\n в качестве разрыва строки по умолчанию (стиль Windows), вы являетесь частью заголовка, и он будет распознан как тело. В зависимости от http-клиента (пользовательского агента, может быть, это ваш браузер или завиток или что-то еще), это может обрабатываться "вставлять некоторые заголовки по умолчанию". Замените разрывы строк на \r\n и повторите попытку.

Если ваш сервер доступен из Интернета, попробуйте средства тестирования заголовков, чтобы проверить, что ваш HTTP-звук. Если это только localhost, посмотрите, что выталкивает curl -I http://ip-of-my-server:9000.

Ответ 2

Я думаю, что в данном случае то, что вы подразумеваете под web-server, - это просто некоторая связь сокетов между сервером и клиентом или сортировка. Мой опыт работы с PHP и сокетами был с прокси-серверами Flash.

Это связано с вложением пикселя Flash 1x1px где-то на вашей странице и использования его в качестве моста между флэш-пикселом, Javascript и PHP Socket Server. (сокет-связь действительно бриз с ActionScript, как только вы знаете, как он работает). Этот метод также является единственным способом получения максимальной совместимости с браузером (даже более продвинутые фреймворки websocket, такие как socket.io, используют этот метод пиксельных пикселей как резерв).

Другим вариантом является, конечно, WebSockets, аналогично тем, которые используются на этом самом сайте для функции обновления в реальном времени. Существует даже тег, посвященный этому здесь, в Stack Overflow.

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

Надеюсь, что это направит вас в правильном направлении...

Ответ 3

Код, который вы пробовали изначально, был очень близок, но потребовалось несколько незначительных изменений:

<?php
set_time_limit(0);

$address = '127.0.0.1';
$port = 80;

$sock = socket_create(AF_INET, SOCK_STREAM, 0);
socket_bind($sock, $address, $port) or die('Could not bind to address');

echo "\n Listening On port $port For Connection... \n\n";

while(1)
{
    socket_listen($sock);
    $client = socket_accept($sock);

    $input = socket_read($client, 1024);

    $incoming = array();
    $incoming = explode("\r\n", $input);

    $fetchArray = array();
    $fetchArray = explode(" ", $incoming[0]);

    $file = $fetchArray[1];
    if($file == "/"){ 

        $file = "index.html"; 

    } else {

        $filearray = array();
        $filearray = explode("/", $file);
        $file = $filearray[1];
    }

echo $fetchArray[0] . " Request " . $file . "\n"; 

$output = "";
$Header = "HTTP/1.1 200 OK \r\n" .
"Date: Fri, 31 Dec 1999 23:59:59 GMT \r\n" .
"Content-Type: text/html \r\n\r\n";

$Content = file_get_contents($file);
$output = $Header . $Content;

    socket_write($client,$output,strlen($output));
    socket_close($client);
}

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

приветствует, что это помогло!