-
-
Save delonnewman/124f58114297099fe6f8d61f059755b9 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