Created
April 30, 2011 18:18
-
-
Save greut/949850 to your computer and use it in GitHub Desktop.
A web server in pure PHP (non-concurrent and concurrent)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env php | |
<?php | |
$app = function($request) { | |
$body = <<<EOS | |
<!DOCTYPE html> | |
<html> | |
<meta charset=utf-8> | |
<title>Hello World!</title> | |
<h1>Hello World!</h1> | |
</html> | |
EOS; | |
return array( | |
'200 OK', | |
array('Content-Type' => 'text/html;charset=utf-8'), | |
$body | |
); | |
}; | |
$socket = stream_socket_server('tcp://0.0.0.0:8000', $errno, $errstr); | |
if (!$socket) { | |
echo $errstr, ' (', $errno,')', PHP_EOL; | |
} else { | |
$defaults = array( | |
'Content-Type' => 'text/html', | |
'Server' => 'PHP '.phpversion() | |
); | |
echo 'Server is running on 0.0.0.0:8000, relax.', PHP_EOL; | |
while ($conn = stream_socket_accept($socket, -1)) { | |
$request = ''; | |
while (substr($request, -4) !== "\r\n\r\n") { | |
$request .= fread($conn, 1024); | |
} | |
list($code, $headers, $body) = $app($request); | |
$headers += $defaults; | |
if (!isset($headers['Content-Length'])) { | |
$headers['Content-Length'] = strlen($body); | |
} | |
$header = ''; | |
foreach ($headers as $k => $v) { | |
$header .= $k.': '.$v."\r\n"; | |
} | |
fwrite($conn, implode("\r\n", array( | |
'HTTP/1.1 '.$code, | |
$header, | |
$body | |
))); | |
fclose($conn); | |
} | |
fclose($socket); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env php | |
<?php | |
$app = function($request) { | |
$body = <<<EOS | |
<!DOCTYPE html> | |
<html> | |
<meta charset=utf-8> | |
<title>Hello World!</title> | |
<h1>Hello World!</h1> | |
</html> | |
EOS; | |
return array( | |
'200 OK', | |
array('Content-Type' => 'text/html;charset=utf-8'), | |
$body | |
); | |
}; | |
$defaults = array( | |
'Content-Type' => 'text/html', | |
'Server' => 'PHP '.phpversion() | |
); | |
if (($sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)) < 0) { | |
echo 'failed to create socket : ', socket_strerror($sock), PHP_EOL; | |
exit(); | |
} | |
if (($ret = socket_bind($sock, '0.0.0.0', 8000)) < 0) { | |
echo 'failed to bind socket : ', socket_strerror($ret), PHP_EOL; | |
exit(); | |
} | |
if (($ret = socket_listen($sock, 0)) < 0) { | |
echo 'failed to listent to socket : ', socket_strerror($ret), PHP_EOL; | |
exit(); | |
} | |
echo 'Server is running on 0.0.0.0:8000, relax.', PHP_EOL; | |
$listening = true; | |
while ($listening) { | |
$conn = socket_accept($sock); | |
if ($conn < 0) { | |
echo 'error: ', socket_strerror($conn), PHP_EOL; | |
exit(); | |
} else if ($conn === false) { | |
usleep(100); | |
} else { | |
$pid = pcntl_fork(); | |
if ($pid == -1) { | |
echo 'fork failure: ', PHP_EOL; | |
exit(); | |
} else if ($pid == 0) { | |
$listening = false; | |
socket_close($sock); | |
$request = ''; | |
while (substr($request, -4) !== "\r\n\r\n") { | |
$request .= socket_read($conn, 1024); | |
} | |
list($code, $headers, $body) = $app($request); | |
$headers += $defaults; | |
if (!isset($headers['Content-Length'])) { | |
$headers['Content-Length'] = strlen($body); | |
} | |
$header = ''; | |
foreach ($headers as $k => $v) { | |
$header .= $k.': '.$v."\r\n"; | |
} | |
socket_write($conn, implode("\r\n", array( | |
'HTTP/1.1 '.$code, | |
$header, | |
$body | |
))); | |
socket_close($conn); | |
} else { | |
socket_close($conn); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment