php动态网站搭建步骤(用php做一个简单的动态网页)

如果你想实现一个Web服务器,你需要对Web服务器的运行方式有一个大致的了解。我们先从静态文本服务器开始,以Web服务器的1.html为例。

1.客户端向服务器发送http请求。如果服务器监听的端口号是9002,那么在本机本身测试访问的地址是

php动态网站搭建步骤(用php做一个简单的动态网页)

2、服务器监听9002端口,因此收到请求后,可以从httpheader中获取请求中需要访问的uri资源在web目录中的位置。

3、服务器读取需要访问的资源文件,然后填充到http实体中返回给客户端。

示意图如下:

??phpclassweb_config{//监听端口号constPORT=9003;//项目根目录constWEB_ROOT='/Users/zhoumengkang/Documents/html';}classserver{private$ip;private$port;公共函数__construct($ip,$port){$this-ip=$ip;$this-port=$port;$this-await();}私有函数await(){$sock=socket_create(AF_INET,SOCK_STREAM,SOL_TCP);if($sock0){echo'Error:'.socket_strerror(socket_last_error())。'\n';}$ret=socket_bind($sock,$this-ip,$this-port);if(!$ret){echo'BINDFAILED:'。socket_strerror(socket_last_error())。'\n';exit;}echo'OK\n';$ret=socket_listen($sock);if($ret0){echo'LISTENFAILED:'。socket_strerror(socket_last_error())。'\n';}do{$new_sock=null;try{$new_sock=socket_accept($sock);}catch(Exception$e){echo$e-getMessage();echo'ACCEPTFAILED:'。socket_strerror(socket_last_error())。'\n';}尝试{$request_string=socket_read($new_sock,1024);$response=$this-output($request_string);socket_write($new_sock,$response);socket_close($new_sock);}catch(异常$e){echo$e-getMessage();echo'READFAILED:'。socket_strerror(socket_last_error())。'\n';}}while(TRUE);}/***@param$request_string*@returnstring*/私有函数输出($request_string){//静态GET/1.htmlHTTP/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();}}/***404return*@returnstring*/privatefunctionnot_found(){$content='h1FileNotFound/h1';return'HTTP/1.1404FileNotFound\r\nContent-Type:text/html\r\nContent-Length:'.strlen($content)。'\r\n\r\n'.$content;}/***添加头信息*@param$string*@returnstring*/privatefunctionadd_header($string){return'HTTP/1.1200OK\r\nContent-Length:'.strlen($string).'\r\nServer:mengkang\r\n\r\n'.$string;}}$server=newserver('127.0.0.1',web_config:PORT);如图上面的代码如上所述,只要在终端中执行该文件,就会启动一个静态Web服务器。

下图是我访问web目录中的1.jpg文件的屏幕截图。

简单的静态Web服务器已经完成。接下来的问题是如何使其支持动态内容的输出。我们只需要在Web服务器内部执行某个程序并将结果返回给客户端吗?但通过这种方式,Web服务器代码与业务代码耦合在一起。如何解决一个可以应用于各种业务场景的Web服务器?

CGI的出现解决了这个问题。那么什么是CGI?以下段落是复制的:

CGI是外部应用程序(CGI程序)和Web服务器之间的接口标准。它是在CGI程序和Web服务器之间传输信息的过程。CGI规范允许Web服务器执行外部程序并将其输出发送到Web浏览器。CGI将Web的简单静态超媒体文档集转变为全新的交互式媒体。

哇,举个具体的例子,比如我们现在使用的PHP全局变量$_SERVER['QUERY_STRING'是由Web服务器通过CGI协议传递过来的。例如,在Nginx中,也许你还记得这样的fastcgi配置

fastcgi_paramQUERY_STRING$query_string;

没错,nginx将其全局变量$query_string传递给了fastcgi_param的环境变量。

接下来我们还利用CGI的QUERY_STRING作为桥梁,将客户端请求的uri中的信息传递给cgi程序。通过putenv将QUERY_STRING存储在请求的环境变量中。

我们同意在Web服务器中访问的资源带有.cgi后缀以表示动态访问。这有点类似于在nginx中配置位置来查找php脚本。检查是否应该请求cgi程序都是一条规则。为了和Web服务器区别,我用C写了一个cgi程序来查询用户信息,根据用户ID查询用户信息。

粗略的访问逻辑如下图

演示代码地址:

如果您想运行演示,您需要执行以下操作:

1、修改config.php中项目根目录WEB_ROOT

2、编译cgi-demo\user.c,编译命令gcc-ouser.cgiuser.c,然后将user.cgi文件放到你配置的工程根目录下

3.在终端中执行phpstart.php,以便启动Web服务器。

4、可以通过访问,看到如下效果

其实我只是基于静态服务器做了一些cgi。我判断是请求的转发处理。我把github上三个文件的代码合并成一个文件供大家观看。

??phpclassweb_config{//监听端口号constPORT=9003;//项目根目录constWEB_ROOT='/Users/zhoumengkang/Documents/html';//系统支持的cgi程序的文件扩展名constCGI_EXTENSION='cgi';}类服务器{private$ip;private$port;publicfunction__construct($ip,$port){$this-ip=$ip;$this-port=$port;$this-await();}私有函数await(){$sock=socket_create(AF_INET,SOCK_STREAM,SOL_TCP);if($sock0){echo'Error:'.socket_strerror(socket_last_error())。'\n';}$ret=socket_bind($sock,$this-ip,$this-port);if(!$ret){echo'BINDFAILED:'。socket_strerror(socket_last_error())。'\n';exit;}echo'OK\n';$ret=socket_listen($sock);if($ret0){echo'LISTENFAILED:'.socket_strerror(socket_last_error())。'\n';}do{$new_sock=null;try{$new_sock=socket_accept($sock);}catch(Exception$e){echo$e-getMessage();echo'ACCEPTFAILED:'。socket_strerror(socket_last_error())。'\n';}尝试{$request_string=socket_read($new_sock,1024);$response=$this-output($request_string);socket_write($new_sock,$response);socket_close($new_sock);}catch(异常$e){echo$e-getMessage();echo'READFAILED:'。socket_strerror(socket_last_error())。'\n';}}while(TRUE);}/***@param$request_string*@returnstring*/私有函数输出($request_string){//staticGET/1.htmlHTTP/1.1.//动态GET/user.cgi?id=1HTTP/1.1.$request_array=explode('',$request_string);if(count($request_array)2){return'';}$uri=$request_array[1;回显'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*@returnbool*/privatefunctionset_env($query_string){if($query_string==null){returnfalse;}if(strpos($query_string,'=')){putenv('QUERY_STRING='.$query_string);}}/***判断请求的uri是否为合法的cgi资源*@param$uri*@returnbool*/private函数cgi_check($uri){$info=pathinfo($uri);$extension=isset($info['extension')?$info['extension':null;if($extensionin_array($extension,explode(',',web_config:CGI_EXTENSION))){returntrue;}returnfalse;}/***404return*@returnstring*/privatefunctionnot_found(){$content='h1FileNotFound/h1';return'HTTP/1.1404FileNotFound\r\nContent-Type:text/html\r\nContent-Length:'.strlen($content).'\r\n\r\n'.$content;}/***添加头信息*@param$string*@returnstring*/privatefunctionadd_header($string){return'HTTP/1.1200OK\r\nContent-Length:'.strlen($string).'\r\nServer:mengkang\r\n\r\n'.$string;}}$server=新服务器('127.0.0.1',web_config:PORT);

以上就是用PHP实现动态Web服务器的整个实现过程。希望对大家的学习有所帮助。