background image

其实很多人对

PHP 的使用场景都有误解,认为 php 只能用于编写 web 脚本,实际上,从

PHP4 开始,php 的使用场景早已不限于处理 web 请求。

php 的架构体系来说,php 分为三个层次:sapi、php core 和 zend engine。php core 本身和

web 没有任何耦合,php 通过 sapi 与其它应用程序通信,例如 mod_php 就是为 apache 编写

sapi 实现,同样,fpm 是一个基于 fastcgi 协议的 sapi 实现,这些 sapi 都是与 web server

配合用于处理

web 请求的。但是也有许多 sapi 与 web 无关,例如 cli sapi 可以使得在命令行

环境下直接执行

php,embed sapi 可以将 php 嵌入其它语言(如 Lua)那样。这里我并不打

算详细讨论

php 的架构体系和 sapi 的话题,只是说明从架构体系角度目前的 php 早已被设

计为支持各种环境,而非为

web 独有。

除了架构体系的支持外,

php 丰富的扩展模块也为 php 在不同环境发挥作用提供了后盾,

例如本文要提到的

pcntl

 

     

模块

 

 

posix

 

     

模块

 

 

配合可以实现基本的进程管理、信号处理等操作系

统级别的功能,而

sockets

 

     

模块

 

 

可以使

php 具有 socket 通信的能力。因此 php 完全可以用于

编写类似于

shell 或 perl 常做的工具性脚本,甚至是具有 server 性质的 daemon process。

为了展示

php 如何编写 daemon server,我用 php 编写了一个简单的 http server,这个 server

daemon process 的形式运行。当然,为了把重点放在如何使用 php 编写 daemon,我没有

为这个

http server 实现具体业务逻辑,但它可以监听指定端口,接受 http 请求并返回给客

户端一条固定的文本,整个过程通过

socket 实现,全部由 php 编写而成。

代码实例

下面是这个程序的完整代码:

<?php

//Accpet the http client request and generate response content.//As a demo, this function just send 
"PHP HTTP Server" to client.function handle_http_request($address, $port){    $max_backlog = 
16;    $res_content = "HTTP/1.1 200 OK

        Content-Length: 15

        Content-Type: text/plain; charset=UTF-8

        PHP HTTP Server";    $res_len = strlen($res_content);

    //Create, bind and listen to socket    if(($socket = socket_create(AF_INET, SOCK_STREAM, 
SOL_TCP)) === FALSE)    {        echo "Create socket failed!\n";        exit;    }