PHP编写daemon process 实例详解


Posted in PHP onNovember 13, 2016

PHP编写daemon process

今天下午在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 相关文章推荐
Smarty安装配置方法
Apr 10 PHP
ajax实现无刷新分页(php)
Jul 18 PHP
深入理解PHP原理之错误抑制与内嵌HTML分析
May 02 PHP
解析php取整的几种方式
Jun 25 PHP
PHP实现指定字段的多维数组排序函数分享
Mar 09 PHP
Yii2前后台分离及migrate使用(七)
May 04 PHP
yii2超好用的日期组件和时间组件
May 05 PHP
php微信开发之自定义菜单完整流程
Oct 08 PHP
php 时间time与日期date之间的使用详解及区别
Nov 07 PHP
PHP读取文本文件并逐行输出该行使用最多的字符与对应次数的方法
Nov 25 PHP
thinkPHP中volist标签用法示例
Dec 06 PHP
JS中彻底删除JSON对象组成的数组中的元素
Sep 22 PHP
php版微信小店API二次开发及使用示例
Nov 12 #PHP
PHP Mysqli 常用代码集合
Nov 12 #PHP
PHP版微信小店接口开发实例
Nov 12 #PHP
PHP错误和异常处理功能模块示例
Nov 12 #PHP
php版微信小店调用api示例代码
Nov 12 #PHP
php实用代码片段整理
Nov 12 #PHP
php中strlen和mb_strlen用法实例分析
Nov 12 #PHP
You might like
FCKeditor添加自定义按钮
2008/03/27 PHP
php xml实例 留言本
2009/03/20 PHP
PHP常用的排序和查找算法
2015/08/06 PHP
PHP中empty和isset对于参数结构的判断及empty()和isset()的区别
2015/11/15 PHP
yii2中LinkPager增加总页数和总记录数的实例
2017/08/28 PHP
PHP中isset、empty的用法与区别示例详解
2020/11/05 PHP
基于jQuery的前端数据通用验证库
2011/08/08 Javascript
JavaScript实现16进制颜色值转RGB的方法
2015/02/09 Javascript
JS中call/apply、arguments、undefined/null方法详解
2016/02/15 Javascript
jQuery无刷新上传之uploadify简单代码
2017/01/17 Javascript
js canvas实现QQ拨打电话特效
2017/05/10 Javascript
vuejs手把手教你写一个完整的购物车实例代码
2017/07/06 Javascript
vue项目中使用百度地图的方法
2018/06/08 Javascript
vue axios数据请求及vue中使用axios的方法
2018/09/10 Javascript
解决vuejs 使用value in list 循环遍历数组出现警告的问题
2018/09/26 Javascript
详解vuex 渐进式教程实例代码
2018/11/27 Javascript
详解Vue用cmd创建项目
2019/02/12 Javascript
Python中实现结构相似的函数调用方法
2015/03/10 Python
python读取oracle函数返回值
2016/07/18 Python
python实现八大排序算法(2)
2017/09/14 Python
python生成n个元素的全组合方法
2018/11/13 Python
Python模块、包(Package)概念与用法分析
2019/05/31 Python
python3 正则表达式基础廖雪峰
2020/03/25 Python
Pycharm修改python路径过程图解
2020/05/22 Python
Keras—embedding嵌入层的用法详解
2020/06/10 Python
python导入库的具体方法
2020/06/18 Python
通过Python实现Payload分离免杀过程详解
2020/07/13 Python
html5实现canvas阴影效果示例
2014/05/07 HTML / CSS
Canvas波浪花环的示例代码
2020/08/21 HTML / CSS
波兰灯具、照明和LED购物网站:Lampy.pl
2019/03/11 全球购物
Rhone官方网站:男士运动服装、健身服装和高级运动服
2019/05/01 全球购物
电气工程及其自动化专业求职信
2014/06/23 职场文书
2014年小班保育员工作总结
2014/12/23 职场文书
2016大学迎新晚会开场白
2015/11/24 职场文书
python实现简单的井字棋
2021/05/26 Python
Java 多线程协作作业之信号同步
2022/05/11 Java/Android