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 相关文章推荐
php 无限级 SelectTree 类
May 19 PHP
PHP使用GIFEncoder类生成的GIF动态图片验证码
Jul 01 PHP
CodeIgniter错误mysql_connect(): No such file or directory解决方法
Sep 06 PHP
20个2014年最优秀的PHP框架回顾
Oct 22 PHP
详解PHP中的mb_detect_encoding函数使用方法
Aug 18 PHP
一个简单至极的PHP缓存类代码
Oct 23 PHP
PHP操作MySQL的mysql_fetch_* 函数的常见用法教程
Dec 25 PHP
PHP经典算法集锦【经典收藏】
Sep 14 PHP
浅谈PHP中new self()和new static()的区别
Aug 11 PHP
Laravel5.5新特性之友好报错以及展示详解
Aug 13 PHP
laravel excel 上传文件保存到本地服务器功能
Nov 14 PHP
基于PHP实现堆排序原理及实例详解
Jun 19 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 cdata 处理(详细介绍)
2013/07/05 PHP
PHP动态生成javascript文件的2个例子
2014/04/11 PHP
LaravelS通过Swoole加速Laravel/Lumen详解
2018/03/02 PHP
PHP 获取客户端 IP 地址的方法实例代码
2018/11/11 PHP
Laravel Eloquent分表方法并使用模型关联的实现
2019/11/25 PHP
PHP 对象继承原理与简单用法示例
2020/04/21 PHP
JavaScript实现将UPC转换成ISBN的方法
2015/05/26 Javascript
微信小程序 解决swiper不显示图片的方法
2017/01/04 Javascript
通过jsonp获取json数据实现AJAX跨域请求
2017/01/22 Javascript
原生javascript实现读写CSS样式的方法详解
2017/02/20 Javascript
JS实现身份证输入框的输入效果
2017/08/21 Javascript
基于vue v-for 循环复选框-默认勾选第一个的实现方法
2018/03/03 Javascript
使用react实现手机号的数据同步显示功能的示例代码
2018/04/03 Javascript
解决axios发送post请求返回400状态码的问题
2018/08/11 Javascript
关于node-bindings无法在Electron中使用的解决办法
2018/12/18 Javascript
vue-router命名路由和编程式路由传参讲解
2019/01/19 Javascript
微信小程序实现多选框全选与反全选及购物车中删除选中的商品功能
2019/12/17 Javascript
Nodejs文件上传、监听上传进度的代码
2020/03/27 NodeJs
使用Python的Flask框架构建大型Web应用程序的结构示例
2016/06/04 Python
python flask 多对多表查询功能
2017/06/25 Python
Python企业编码生成系统之主程序模块设计详解
2019/07/26 Python
Python3实现将一维数组按标准长度分隔为二维数组
2019/11/29 Python
Pytorch中Tensor与各种图像格式的相互转化详解
2019/12/26 Python
Python3实现监控新型冠状病毒肺炎疫情的示例代码
2020/02/13 Python
Django使用Profile扩展User模块方式
2020/05/14 Python
如何使用python记录室友的抖音在线时间
2020/06/29 Python
Ubuntu16安装Python3.9的实现步骤
2020/12/15 Python
深入解析HTML5的IndexedDB索引数据库
2015/09/14 HTML / CSS
详解html5页面 rem 布局适配方法
2018/01/12 HTML / CSS
优衣库英国官网:UNIQLO英国
2016/12/25 全球购物
毕业生简历自我评价范文
2014/04/09 职场文书
2014幼儿园保育员工作总结
2014/11/10 职场文书
廉洁自律个人总结
2015/02/14 职场文书
入党宣誓仪式主持词
2015/06/29 职场文书
MySQL 十大常用字符串函数详解
2021/06/30 MySQL
一文搞懂Golang 时间和日期相关函数
2021/12/06 Golang