How to Use PHP to implement a dynamic Web server and php Dynamic web Server
If a web server is used, you need to understand the operating principles of the web server. Start with a static text server. Take accessing 1.html of a web server as an example.
1. The client sends an http request to the server. If the port number listened to by the server is 9002, the access address tested on the local machine is http: // localhost: 9002/1. html.
2. The server listens to port 9002. After receiving the request, the server can obtain the position of the uri resource to be accessed in the request in the web directory from the http head header.
3. The server reads the resource file to be accessed, fills it in the http entity and returns it to the client.
As follows:
<? Phpclass web_config {// listening PORT number const PORT = 9003; // project root directory 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_err Or (). "\ 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) {// static 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"; // static file processing if (file_exists ($ filename) {return $ this-> add_header (file_get_contents ($ filename ));} else {return $ this-> not_found () ;}/ *** 404 returns * @ return string */private function not_found () {$ content = "
As described in the Code above, a static web server is started as long as the file is executed on the terminal.
For me to access the 1.jpg file under my web directory
The simple static web server has been completed. The following question is how to make it support dynamic content output. Do you only need to return the result to the client after executing a program on the web server? However, the web server code is coupled with the Business Code. How can a web server be used in various business scenarios?
CGI solves this problem. So what is CGI? The following section is copied:
CGI is the interface standard between external applications (CGI programs) and Web servers. It is the procedure for transmitting information between CGI programs and Web servers. CGI specifications allow the Web server to execute external programs and send their output to the Web browser. CGI converts a simple set of static hypermedia documents on the Web into a complete new interactive media.
For example, the global variable $ _ SERVER ['query _ string'] in PHP is passed over the CGI protocol by the Web SERVER. For example, in Nginx, you may remember the fastcgi configuration.
Fastcgi_param QUERY_STRING $ query_string;
Correct. nginx passed its global variable $ query_string to the environment variable fastcgi_param.
The following uses the QUERY_STRING of CGI as the bridge to transmit the information in the uri requested by the client to the cgi program. Putenv is used to store QUERY_STRING into the environment variable of the request.
We agree that the resource accessed by the Web server is a. cgi suffix, which indicates dynamic access, which is similar to configuring location in nginx to search for php scripts. It is a rule for checking whether the cgi program should be requested. To distinguish it from Web servers, I used C to write a cgi program to query user information and query user information based on user id.
The general access logic is as follows:
DEMO code address: https://github.com/zhoumengkang/php/tree/master/php-webserver/dynamic
To run this demo, You need to perform the following operations:
1. Modify the project root directory WEB_ROOT in config. php.
2. Compile cgi-demo \ user. c, compile the command gcc-o user. cgi user. c, and put the user. cgi file under the root directory of your configured project.
3. Execute php start. php on the terminal so that the web server starts
4. http: // localhost: 9003/user. cgi? Id = 1. You can see the following results.
In fact, we only made some cgi judgments on the basis of the static server, namely request forwarding. We combined the code of the three files on github into one file for you to watch.
<? Phpclass web_config {// The listening PORT number const PORT = 9003; // The project root directory const WEB_ROOT = "/Users/zhoumengkang/Documents/html "; // The file extension 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) {// static GET/1.html HTTP /1.1... // dynamic 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 );} // process static files if (file_exists ($ filename) {return $ this-> add_header (file_get_contents ($ filename ));} else {return $ this-> not_found ();}}/ * ** Set the environment variable to the cgi program using * @ 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) ;}}/*** determine whether the requested uri is a valid cgi resource * @ 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 returns * @ return string */private function not_found () {$ content = "
The above is the full implementation process of PHP to implement a dynamic Web server. I hope it will be helpful for your learning.