PHP编写daemon process详解及实例代码


Posted in PHP onSeptember 30, 2016

今天下午在segmentfault.com看到一个提问,提问标题是“PHP怎么做服务化”,其中问道php是不是只能以web方式调用。其实很多人对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;
  }  
 
  if((socket_bind($socket, $address, $port)) === FALSE)
  {
    echo "Bind socket failed!\n";
    exit;
  }
   
  if((socket_listen($socket, $max_backlog)) === FALSE)
  {
    echo "Listen to socket failed!\n";
    exit;
  }
 
  //Loop
  while(TRUE)
  {
    if(($accept_socket = socket_accept($socket)) === FALSE)
    {
      continue;
    }
    else
    {
      socket_write($accept_socket, $res_content, $res_len);  
      socket_close($accept_socket);
    }
  }
}
 
//Run as daemon process.
function run()
{
  if(($pid1 = pcntl_fork()) === 0)
  //First child process
  {
    posix_setsid(); //Set first child process as the session leader.
     
    if(($pid2 = pcntl_fork()) === 0)
    //Second child process, which run as daemon.
    {
      //Replaced with your own domain or address.
      handle_http_request('www.codinglabs.org', 9999); 
    }
    else
    {
      //First child process exit;
      exit;
    }
  }
  else
  {
    //Wait for first child process exit;
    pcntl_wait($status);
  }
}
 
//Entry point.
run();
 
?>

这里我假设各位对Unix环境编程都比较了解,所以不做太多细节的解释,只梳理一下。简单来看,这个程序主要由两个部分组成,handle_http_request函数负责处理http请求,其编写方法与用C编写的tcp server类似:创建socket、绑定、监听,然后通过一个循环处理每个connect过来的客户端,一旦accept到一个连接...

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

PHP 相关文章推荐
Discuz! Passport 通行证整合
Mar 27 PHP
JS中encodeURIComponent函数用php解码的代码
Mar 01 PHP
php加水印的代码(支持半透明透明打水印,支持png透明背景)
Jan 17 PHP
如何用C语言编写PHP扩展的详解
Jun 13 PHP
CodeIgniter框架过滤HTML危险代码
Jun 12 PHP
php 模拟 asp.net webFrom 按钮提交事件实例
Oct 13 PHP
CodeIgniter使用smtp服务发送html邮件的方法
Jun 10 PHP
php精确的统计在线人数的方法
Oct 21 PHP
ThinkPHP路由机制简介
Mar 23 PHP
静态html文件执行php语句的方法(推荐)
Nov 21 PHP
ThinkPHP实现分页功能
Apr 28 PHP
PHP后端银联支付及退款实例代码
Jun 23 PHP
PHP 极验验证码实例讲解
Sep 29 #PHP
php自定义函数转换html标签示例
Sep 29 #PHP
php自定义函数实现汉字转换utf8编码的方法
Sep 29 #PHP
php自定义函数实现二维数组按指定key排序的方法
Sep 29 #PHP
分享一个漂亮的php验证码类
Sep 29 #PHP
你不知道的文件上传漏洞php代码分析
Sep 29 #PHP
PHP的Json中文处理解决方案
Sep 29 #PHP
You might like
php引用返回与取消引用的详解
2013/06/08 PHP
PHP递归遍历指定目录的文件并统计文件数量的方法
2015/03/24 PHP
浅谈PHP array_search 和 in_array 函数效率问题
2019/10/15 PHP
PHP7 windows支持
2021/03/09 PHP
javascript 设为首页与加入收藏兼容多浏览器代码
2011/01/11 Javascript
js有序数组的连接问题
2013/10/01 Javascript
js 用CreateElement动态创建标签示例
2013/11/20 Javascript
Perl Substr()函数及函数的应用
2015/12/16 Javascript
在JavaScript中对HTML进行反转义详解
2016/05/18 Javascript
AngularJS中比较两个数组是否相同
2016/08/24 Javascript
原生JS实现简单放大镜效果
2017/02/08 Javascript
JS实现数组去重方法总结(六种方法)
2017/07/14 Javascript
vue2.0 资源文件assets和static的区别详解
2018/04/08 Javascript
解决webpack+Vue引入iView找不到字体文件的问题
2018/09/28 Javascript
微信小程序结合Storage实现搜索历史效果
2019/05/18 Javascript
jQuery--遍历操作实例小结【后代、同胞及过滤】
2020/05/22 jQuery
[02:44]完美大师赛主赛事淘汰赛第二日观众采访
2017/11/24 DOTA
python定时器使用示例分享
2014/02/16 Python
Python数据集切分实例
2018/12/08 Python
Python连接HDFS实现文件上传下载及Pandas转换文本文件到CSV操作
2020/06/06 Python
如何用Python徒手写线性回归
2021/01/25 Python
CSS3的column-fill属性对齐列内容高度的用法详解
2016/07/01 HTML / CSS
HTML5在IE10、火狐下中文乱码问题的解决方法
2013/11/18 HTML / CSS
海蓝之谜(LA MER)澳大利亚官方商城:全球高端奢华护肤品牌
2017/10/27 全球购物
Linux常见面试题
2016/10/04 面试题
正隆泰信息技术有限公司上机题
2012/06/14 面试题
会计实习生工作总结的自我评价
2013/10/07 职场文书
俞敏洪北大演讲稿
2014/05/22 职场文书
工程学毕业生自荐信
2014/06/14 职场文书
分居协议书范本(律师见证版)
2014/11/26 职场文书
2014会计年终工作总结
2014/12/20 职场文书
毕业实习证明范本
2015/06/16 职场文书
2015年国培研修感言
2015/08/01 职场文书
刚学完怎么用Python实现定时任务,转头就跑去撩妹!
2021/06/05 Python
Java并发编程必备之Future机制
2021/06/30 Java/Android
MySQL数据库Innodb 引擎实现mvcc锁
2022/05/06 MySQL