- 2007-07-21 (土) 13:19
- PHP
この記事の所要時間: 約 1分24秒
PHPで簡易サーバを書いてみました。ブラウザから来たHTTPリクエストをそのまま返すだけのものです。実用性はあまり無いですが、ブラウザがどんなリクエストを出しているか確認するにはちょっとだけ便利かもしれません。;-)
socketsライブラリを有効にする
PHPでsocketsライブラリが有効になっている必要があります。Win環境ならPHPパッケージにDLLが用意されているので、php.ini等で下のように有効にすればokです。
# ; を外す extension=php_sockets.dll
サーバを起動する
下のソースをローカルに保存して、phpコマンドで実行するとサーバが起動します。デフォルトではlocalhostの9000ポートでlistenします。
<?php
class HttpServer {
private $socket = null;
private $method = null;
private $uri = null;
private $headers = null;
private $body = null;
public function __construct($port = 9000) {
$this->socket = socket_create_listen($port);
if ($this->socket === false) {
$this->error();
}
}
public function execute() {
while (true) {
$client = socket_accept($this->socket);
if ($client === false) {
$this->error();
}
$request = $this->read($client);
$header = "HTTP/1.x 200 OK\r\n";
$header .= "Content-Type: text/html\r\n";
$header .= "\r\n\r\n";
socket_write($client, $header, strlen($header));
$request = nl2br($request);
socket_write($client, $request, strlen($request));
socket_close($client);
}
}
private function read($client) {
$this->body = "";
$req = "";
while (true) {
$buff = socket_read($client, 2048, PHP_BINARY_READ);
$req .= $buff;
if ($buff === false) {
$this->error();
} else if ($buff === "" || strlen($buff) < 2048) {
if (preg_match("/\r\n\r\n$/", $req)) {
$this->parseHeader($req);
} else {
$this->body .= $buff;
}
if ($this->isComplete()) {
return $req;
}
}
}
}
protected function parseHeader($req) {
$lines = explode("\r\n", $req);
$this->setRequestLine(array_shift($lines));
foreach ($lines as $line) {
$line = trim($line);
if (empty($line)) {
continue;
}
$this->setHeader($line);
}
}
protected function setRequestLine($line) {
list($this->method, $this->uri) = explode(" ", $line);
}
protected function setHeader($line) {
$header = explode(":", $line);
$this->headers[trim(array_shift($header))] = trim(join( ":", $header ));
}
protected function isComplete() {
if ($this->method == "POST" && !empty($this->headers['Content-Length'])) {
return strlen($this->body) == $this->headers['Content-Length'];
}
return true;
}
private function error() {
$message = sprintf("error:%d %s", socket_last_error()
, socket_strerror(socket_last_error()));
die($message);
}
public function __destruct() {
if (is_resource($this->socket)) {
socket_close($this->socket);
}
}
}
$server = new HttpServer();
$server->execute();
?>
ブラウザでサーバへアクセスする
あとはブラウザで[http://localhost:9000/]にアクセスすればリクエストの内容がそのまま表示されます。適当なフォームをHTMLで作ってPOSTするとその内容もそのまま表示されます。
次はHTTPサーバ?
新大阪<->品川の新幹線で時間があったのでちゃちゃっと書いてみました。本当はもうちょっとちゃんとしたHTTPサーバもどきにしようと考えていたのですが、これはこれで面白かったのでアップしときます。。。
あとコードを書く際はZendFramework付属のhttp_serverを参考にしました。ZFはコードが読みやすいので結構好印象です。PHP5フレームワーク・ライブラリとして今後が楽しみですね。
- Newer: Twitter 自分宛のメッセージを携帯で見る
- Older: 携帯サイトに楽天ダイナミックアドを設置する
トラックバック:1
- このエントリーのトラックバックURL
- /blog/2007/07/php_http_echo_server.html/trackback
- Listed below are links to weblogs that reference
- HTTPリスエストをそのまま返すPHPサーバ from Shin x blog
- pingback from ぱんぴーまっしぐら » 今日のチェキ 2007-07-24 10-07-04 (日) 8:38
-
[…] ■HTTPリスエストをそのまま返すPHPサーバ […]

