Reputation: 549
I just tried this code:
<?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);
?>
But there is a problem. Instead of using the content of $output as the headers, Apache returns its own headers...
I don't know why because I execute the script via this command: php webserv.php
.
However it practically works, because when I load the page http://ip-of-my-server:9000/
from my browser, it shows me the headers sent by the client on the server, and returns the content of $output
to the client (my browser).
I want to create my own webserver only in PHP if it's possible. I just want to know how to run it without Apache, so I can manage my own HTTP headers.
Upvotes: 13
Views: 18181
Reputation: 21
The code you tried originally was very close but just required a few minor changes:
<?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);
}
This code here will now will revive the header of the request packet to find the requested file and then it will go to the local directory for that file. As it stands this only works with html so it doesn't support images but it would do fine as a really light weight web-server. also it currently defaults to index.html, so just save this, put some html files in the same directory and point a browser at it.
cheers hope this helped!
Upvotes: 2
Reputation: 13557
Is there a reason to implement an HTTP server in PHP (of all things)? There's no threading, etc. It would be a pain… (unless this is some sort of academic thing…)
PHP 5.4 ships with a built-in webserver. Maybe that is what you're looking for…
Update:
While I understand your motivation to learn this sort of stuff, I believe you're on the wrong track trying this sort of stuff with PHP. PHP is not really designed for long running processes (like a server would be), it is not equipped for parallel processing (threads). Even multi-processing would require PCNTL, specifically pcntl_fork() and limit your educational walkabout to a Unix based system (which may not be a problem, though).
If your goal is to understand how servers deal with concurrency, I suggest playing with a language designed for that (Erlang, Go, Scala, …). Or play with a language that at least sort of emulates parallel processing (Python, Ruby, … [sort of, because of their GILs]).
If your goal is to understand HTTP (and let me tell you HTTP is a beast, if you're going past HTTP/1.0 and want to do it right), fiddling with PHP may be fine, if it's the only language you're firm in. If so, have a look at the example code (chat server) in this (sadly German) article on Socket Servers in PHP to get the basic socket stuff running an concentrate on the actual HTTP.
Update 2:
To answer your question regarding the headers…
I have no clue how apache would fit into the scenario described in your question. But I see you're using line-breaks to delimit headers and a double line-break to delimit headers from body. Unless you've saved your php file using \r\n
as the default line-break (windows-style), you're header-part is malformed and would thus be recognized as the body. Depending on the http client (user agent, may it be your browser, or curl, or whatever) this may be treated with "insert some default headers". Replace your line-breaks with \r\n
and try again.
If your server is reachable from the internet, try some header test tools to verify your HTTP is sound. If it is localhost-only, see what curl -I http://ip-of-my-server:9000
spits out.
Upvotes: 18
Reputation: 48006
I think what you are meaning by web-server
in this instance is simply some socket communication between a server and a client or sorts. My experience with PHP and sockets has been with flash proxy clients.
This involves embedding a 1x1px flash pixel somewhere on your page and using it as a bridge between the flash pixel, Javascript and PHP Socket Server. (socket communication is really a breeze with ActionScript once you know how it works). This method is also the only way you'll get maximum browser compatibility (even the more advanced websocket frameworks like socket.io use this flash pixel method as a fallback).
Another option is of course WebSockets similar to the ones used on this very site for the live-refresh feature. There is even a tag dedicated to it here on Stack Overflow.
If you want to play around creating a socket server with PHP, your client would have to be something other than just your browser.
Hope this steers you in the right direction...
Upvotes: 2