検索
ホームページバックエンド開発PHPチュートリアルPHPで動的Webサーバーを実装する方法

この記事では主に PHP で動的 Web サーバーを実装する方法を紹介します。興味のある方はぜひ参考にしてください。

Web サーバーを実装する場合は、Web サーバーの動作原理を一般的に理解する必要があります。 Web サーバーにアクセスする 1.html を例として、静的テキスト サーバーから始めましょう。サーバーがリッスンするポート番号が次の場合、クライアントはサーバーに http リクエストを送信します。 9002 の場合、このマシン自身のテスト アクセスのアドレスは

http://localhost:9002/1.html です。 2. サーバーはポート 9002 をリッスンします。リクエストを受信した後、Web ディレクトリの http ヘッダーからアクセスする必要がある URI リソースを取得できます。 。

3. サーバーは、アクセスする必要があるリソース ファイルを読み取り、それを http エンティティに埋めてクライアントに返します。

概略図は次のとおりです。

php
<?php
class web_config {
 // 监听的端口号
 const PORT = 9003;
 // 项目根目录
 const WEB_ROOT = "/Users/zhoumengkang/Documents/html";
}
class server {
 private $ip;
 private $port;
 public function __construct($ip, $port) {
 $this->ip = $ip;
 $this->port = $port;
 $this->await();
 }
 private function await() {
 $sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
 if ($sock < 0) {
 echo "Error:" . socket_strerror(socket_last_error()) . "\n";
 }
 $ret = socket_bind($sock, $this->ip, $this->port);
 if (!$ret) {
 echo "BIND FAILED:" . socket_strerror(socket_last_error()) . "\n";
 exit;
 }
 echo "OK\n";
 $ret = socket_listen($sock);
 if ($ret < 0) {
 echo "LISTEN FAILED:" . socket_strerror(socket_last_error()) . "\n";
 }
 do {
 $new_sock = null;
 try {
 $new_sock = socket_accept($sock);
 } catch (Exception $e) {
 echo $e->getMessage();
 echo "ACCEPT FAILED:" . socket_strerror(socket_last_error()) . "\n";
 }
 try {
 $request_string = socket_read($new_sock, 1024);
 $response = $this->output($request_string);
 socket_write($new_sock, $response);
 socket_close($new_sock);
 } catch (Exception $e) {
 echo $e->getMessage();
 echo "READ FAILED:" . socket_strerror(socket_last_error()) . "\n";
 }
 } while (TRUE);
 }
 /**
 * @param $request_string
 * @return string
 */
 private function output($request_string){
 // 静态 GET /1.html HTTP/1.1 ...
 $request_array = explode(" ",$request_string);
 if(count($request_array) < 2){
 return $this->not_found();
 }
 $uri = $request_array[1];
 $filename = web_config::WEB_ROOT . $uri;
 echo "request:".$filename."\n";
 // 静态文件的处理
 if (file_exists($filename)) {
 return $this->add_header(file_get_contents($filename));
 } else {
 return $this->not_found();
 }
 }
 /**
 * 404 返回
 * @return string
 */
 private function not_found(){
 $content = "
<h1 id="File-nbsp-Not-nbsp-Found-nbsp">File Not Found </h1>
";
 return "HTTP/1.1 404 File Not Found\r\nContent-Type: text/html\r\nContent-Length: ".strlen($content)."\r\n\r\n".$content;
 }
 /**
 * 加上头信息
 * @param $string
 * @return string
 */
 private function add_header($string){
 return "HTTP/1.1 200 OK\r\nContent-Length: ".strlen($string)."\r\nServer: mengkang\r\n\r\n".$string;
 }
}
$server = new server("127.0.0.1", web_config::PORT);

コードは github https://github.com/zhoumengkang/php にアップロードされています。 /tree/master/php-webserver/static

上記のコードで述べたように、ターミナルでファイルが実行されている限り、静的 Web サーバーが起動します。

下の写真は、Web ディレクトリ内の 1.jpg ファイルにアクセスしているスクリーンショットです。

単純な静的 Web サーバーが完成しました。次の質問は、動的コンテンツの出力をサポートする方法です。 Web サーバー内で特定のプログラムを実行し、結果をクライアントに返すだけでよいのでしょうか?しかし、このようにして、Web サーバーのコードはビジネス コードと結合されます。さまざまなビジネス シナリオで使用できる Web サーバーを解決するにはどうすればよいでしょうか。

CGI の登場により、この問題は解決されました。では、CGIとは何でしょうか?以下の文章をコピーします。

CGI は、外部アプリケーション (CGI プログラム) と Web サーバー間のインターフェース規格であり、CGI プログラムと Web サーバーの間で情報を転送するための手順です。 CGI 仕様により、Web サーバーが外部プログラムを実行し、その出力を Web ブラウザに送信できるようになり、Web の単純な静的ハイパーメディア ドキュメントのセットが完全に新しい対話型メディアに変わります。

私は非常に混乱しています。たとえば、私たちが使用している PHP のグローバル変数

$_SERVER['QUERY_STRING']

は次のとおりです。 Web サーバーが CGI プロトコルを通じて使用するもの。たとえば、Nginx では、fastcgi 構成 <span style="max-width:90%"></span> コードが次のとおりであることを覚えているかもしれません:

fastcgi_param  
QUERY_STRING      
 $query_string;

はい、nginx は独自のグローバル変数

$query_string

を設定します。 fastcgi_param の環境変数に渡されます。 <span style="font-family:NSimsun"></span> 以下では、CGI の

QUERY_STRING

をブリッジとして使用し、クライアントから要求された URI 内の情報を CGI プログラムに渡します。 <span style="font-family:NSimsun"></span>putenv を使用して、<span style="font-family:NSimsun"></span>QUERY_STRING をリクエストの環境変数に保存します。 <span style="font-family:NSimsun"></span>Web サーバーでアクセスされるリソースが

.cgi

であることに同意します。これは、php を見つけるために nginx で場所を設定するのと似ています。手順は同じです。 CGI プログラムをリクエストする必要があるかどうかを確認するのはすべてのルールです。 Web サーバーと区別するために、ユーザー情報を照会し、ユーザー ID に基づいてユーザー情報を照会する CGI プログラムを C で作成しました。 <span style="font-family:NSimsun"></span>おおよそのアクセスロジックは以下の通りです

デモを実行したい場合は以下の操作を行う必要があります

1.

#config.php

<span style="max-width:90%">WEB_ROOT</span><span style="font-family:NSimsun"></span>## のプロジェクト ルート ディレクトリを変更します。 #2.cgi-demo\user.c

をコンパイルし、コマンド gcc -o user.cgi user.c<span style="font-family:NSimsun"></span> をコンパイルしてから user.cgi<span style="font-family:NSimsun"></span> 設定したプロジェクトのルート ディレクトリにファイルを置きます。<span style="font-family:NSimsun"></span>3 php start.php を実行します。

ターミナルで次のようにします。 Web サーバーが開始されます。<span style="font-family:NSimsun">http://localhost:9003/user.cgi? id=1</span> 訪問中に次のような効果が見られました。

実際、静的サーバーに基づいて CGI を作成したところです。リクエストが転送され、github 上の 3 つが処理されたと判断されました。ファイルのコードは、誰もが視聴できるように 1 つのファイルにマージされています。

php
<?php
class web_config {
 // 监听的端口号
 const PORT = 9003;
 // 项目根目录
 const WEB_ROOT = "/Users/zhoumengkang/Documents/html";
 // 系统支持的 cgi 程序的文件扩展名
 const CGI_EXTENSION = "cgi";
}
class server {
 private $ip;
 private $port;
 public function __construct($ip, $port) {
 $this->ip = $ip;
 $this->port = $port;
 $this->await();
 }
 private function await() {
 $sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
 if ($sock < 0) {
 echo "Error:" . socket_strerror(socket_last_error()) . "\n";
 }
 $ret = socket_bind($sock, $this->ip, $this->port);
 if (!$ret) {
 echo "BIND FAILED:" . socket_strerror(socket_last_error()) . "\n";
 exit;
 }
 echo "OK\n";
 $ret = socket_listen($sock);
 if ($ret < 0) {
 echo "LISTEN FAILED:" . socket_strerror(socket_last_error()) . "\n";
 }
 do {
 $new_sock = null;
 try {
 $new_sock = socket_accept($sock);
 } catch (Exception $e) {
 echo $e->getMessage();
 echo "ACCEPT FAILED:" . socket_strerror(socket_last_error()) . "\n";
 }
 try {
 $request_string = socket_read($new_sock, 1024);
 $response = $this->output($request_string);
 socket_write($new_sock, $response);
 socket_close($new_sock);
 } catch (Exception $e) {
 echo $e->getMessage();
 echo "READ FAILED:" . socket_strerror(socket_last_error()) . "\n";
 }
 } while (TRUE);
 }
 /**
 * @param $request_string
 * @return string
 */
 private function output($request_string){
 // 静态 GET /1.html HTTP/1.1 ...
 // 动态 GET /user.cgi?id=1 HTTP/1.1 ...
 $request_array = explode(" ",$request_string);
 if(count($request_array) < 2){
 return "";
 }
 $uri = $request_array[1];
 echo "request:".web_config::WEB_ROOT . $uri."\n";
 $query_string = null;
 if ($uri == "/favicon.ico") {
 return "";
 }
 if (strpos($uri,"?")) {
 $uriArr = explode("?", $uri);
 $uri = $uriArr[0];
 $query_string = isset($uriArr[1]) ? $uriArr[1] : null;
 }
 $filename = web_config::WEB_ROOT . $uri;
 if ($this->cgi_check($uri)) {
 $this->set_env($query_string);
 $handle = popen(web_config::WEB_ROOT.$uri, "r");
 $read = stream_get_contents($handle);
 pclose($handle);
 return $this->add_header($read);
 }
 // 静态文件的处理
 if (file_exists($filename)) {
 return $this->add_header(file_get_contents($filename));
 } else {
 return $this->not_found();
 }
 }
 /**
 * 设置环境变量 给 cgi 程序使用
 * @param $query_string
 * @return bool
 */
 private function set_env($query_string){
 if($query_string == null){
 return false;
 }
 if (strpos($query_string, "=")) {
 putenv("QUERY_STRING=".$query_string);
 }
 }
 /**
 * 判断请求的 uri 是否是合法的 cgi 资源
 * @param $uri
 * @return bool
 */
 private function cgi_check($uri){
 $info = pathinfo($uri);
 $extension = isset($info["extension"]) ? $info["extension"] : null;
 if( $extension && in_array($extension,explode(",",web_config::CGI_EXTENSION))){
 return true;
 }
 return false;
 }
 /**
 * 404 返回
 * @return string
 */
 private function not_found(){
 $content = "<h1 id="File-nbsp-Not-nbsp-Found-nbsp">File Not Found </h1>";
 return "HTTP/1.1 404 File Not Found\r\nContent-Type: text/html\r\nContent-Length: ".strlen($content)."\r\n\r\n".$content;
 }
 /**
 * 加上头信息
 * @param $string
 * @return string
 */
 private function add_header($string){
 return "HTTP/1.1 200 OK\r\nContent-Length: ".strlen($string)."\r\nServer: mengkang\r\n\r\n".$string;
 }
}
$server = new server("127.0.0.1", web_config::PORT);
概要:

上記がこの内容の全体です。この記事が皆さんの学習に役立つことを願っています。

関連提案:

PHPでcurlを使ってIPを偽造する機能

phpMagickWandモジュールを使って画像を操作したりウォーターマークを追加したりする方法

賢い自己 定義されたリソースの定義と使用スキル

以上がPHPで動的Webサーバーを実装する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
PHPおよびPython:さまざまなパラダイムが説明されていますPHPおよびPython:さまざまなパラダイムが説明されていますApr 18, 2025 am 12:26 AM

PHPは主に手順プログラミングですが、オブジェクト指向プログラミング(OOP)もサポートしています。 Pythonは、OOP、機能、手続き上のプログラミングなど、さまざまなパラダイムをサポートしています。 PHPはWeb開発に適しており、Pythonはデータ分析や機械学習などのさまざまなアプリケーションに適しています。

PHPとPython:彼らの歴史を深く掘り下げますPHPとPython:彼らの歴史を深く掘り下げますApr 18, 2025 am 12:25 AM

PHPは1994年に発信され、Rasmuslerdorfによって開発されました。もともとはウェブサイトの訪問者を追跡するために使用され、サーバー側のスクリプト言語に徐々に進化し、Web開発で広く使用されていました。 Pythonは、1980年代後半にGuidovan Rossumによって開発され、1991年に最初にリリースされました。コードの読みやすさとシンプルさを強調し、科学的コンピューティング、データ分析、その他の分野に適しています。

PHPとPythonの選択:ガイドPHPとPythonの選択:ガイドApr 18, 2025 am 12:24 AM

PHPはWeb開発と迅速なプロトタイピングに適しており、Pythonはデータサイエンスと機械学習に適しています。 1.PHPは、単純な構文と迅速な開発に適した動的なWeb開発に使用されます。 2。Pythonには簡潔な構文があり、複数のフィールドに適しており、強力なライブラリエコシステムがあります。

PHPとフレームワーク:言語の近代化PHPとフレームワーク:言語の近代化Apr 18, 2025 am 12:14 AM

PHPは、多数のWebサイトとアプリケーションをサポートし、フレームワークを通じて開発ニーズに適応するため、近代化プロセスで依然として重要です。 1.PHP7はパフォーマンスを向上させ、新機能を紹介します。 2。Laravel、Symfony、Codeigniterなどの最新のフレームワークは、開発を簡素化し、コードの品質を向上させます。 3.パフォーマンスの最適化とベストプラクティスは、アプリケーションの効率をさらに改善します。

PHPの影響:Web開発などPHPの影響:Web開発などApr 18, 2025 am 12:10 AM

phphassiblasifly-impactedwebdevevermentandsbeyondit.1)itpowersmajorplatformslikewordpratsandexcelsindatabase interactions.2)php'sadaptableability allowsitale forlargeapplicationsusingframeworkslikelavel.3)

スカラータイプ、リターンタイプ、ユニオンタイプ、ヌル可能なタイプなど、PHPタイプのヒントはどのように機能しますか?スカラータイプ、リターンタイプ、ユニオンタイプ、ヌル可能なタイプなど、PHPタイプのヒントはどのように機能しますか?Apr 17, 2025 am 12:25 AM

PHPタイプは、コードの品質と読みやすさを向上させるためのプロンプトがあります。 1)スカラータイプのヒント:php7.0であるため、基本データ型は、int、floatなどの関数パラメーターで指定できます。 3)ユニオンタイプのプロンプト:PHP8.0であるため、関数パラメーターまたは戻り値で複数のタイプを指定することができます。 4)Nullable Typeプロンプト:null値を含めることができ、null値を返す可能性のある機能を処理できます。

PHPは、オブジェクトのクローニング(クローンキーワード)と__Clone Magicメソッドをどのように処理しますか?PHPは、オブジェクトのクローニング(クローンキーワード)と__Clone Magicメソッドをどのように処理しますか?Apr 17, 2025 am 12:24 AM

PHPでは、クローンキーワードを使用してオブジェクトのコピーを作成し、\ _ \ _クローンマジックメソッドを使用してクローン動作をカスタマイズします。 1.クローンキーワードを使用して浅いコピーを作成し、オブジェクトのプロパティをクローン化しますが、オブジェクトのプロパティはクローニングしません。 2。\ _ \ _クローン法は、浅いコピーの問題を避けるために、ネストされたオブジェクトを深くコピーできます。 3.クローニングにおける円形の参照とパフォーマンスの問題を避けるために注意し、クローニング操作を最適化して効率を向上させます。

PHP対Python:ユースケースとアプリケーションPHP対Python:ユースケースとアプリケーションApr 17, 2025 am 12:23 AM

PHPはWeb開発およびコンテンツ管理システムに適しており、Pythonはデータサイエンス、機械学習、自動化スクリプトに適しています。 1.PHPは、高速でスケーラブルなWebサイトとアプリケーションの構築においてうまく機能し、WordPressなどのCMSで一般的に使用されます。 2。Pythonは、NumpyやTensorflowなどの豊富なライブラリを使用して、データサイエンスと機械学習の分野で驚くほどパフォーマンスを発揮しています。

See all articles

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

このプロジェクトは osdn.net/projects/mingw に移行中です。引き続きそこでフォローしていただけます。 MinGW: GNU Compiler Collection (GCC) のネイティブ Windows ポートであり、ネイティブ Windows アプリケーションを構築するための自由に配布可能なインポート ライブラリとヘッダー ファイルであり、C99 機能をサポートする MSVC ランタイムの拡張機能が含まれています。すべての MinGW ソフトウェアは 64 ビット Windows プラットフォームで実行できます。

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

WebStorm Mac版

WebStorm Mac版

便利なJavaScript開発ツール

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

強力な PHP 統合開発環境

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター