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 相关文章推荐
杏林同学录(九)
Oct 09 PHP
定制404错误页面,并发信给管理员的程序
Oct 09 PHP
在php MYSQL中插入当前时间
Apr 06 PHP
基于PHP遍历数组的方法汇总分析
Jun 08 PHP
php基于str_pad实现卡号不足位数自动补0的方法
Nov 12 PHP
为百度UE编辑器上传图片添加水印功能
Apr 16 PHP
php编写批量生成不重复的卡号密码代码
May 14 PHP
基于php的CMS中展示文章类实例分析
Jun 18 PHP
php函数mkdir实现递归创建层级目录
Oct 27 PHP
使用Yii2实现主从数据库设置
Nov 20 PHP
php往mysql中批量插入数据实例教程
Dec 12 PHP
PHP实现的杨辉三角求解算法分析
Mar 11 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
PHP Stream_*系列函数
2010/08/01 PHP
php打造智能化的柱状图程序,用于报表等
2015/06/19 PHP
PHP判断手机是IOS还是Android
2015/12/09 PHP
javascript动态改变img的src属性图片不显示的解决方法
2010/10/20 Javascript
数组方法解决JS字符串连接性能问题有争议
2011/01/12 Javascript
js使用html()或text()方法获取设置p标签的显示的值
2014/08/01 Javascript
ECMAScript6块级作用域及新变量声明(let)
2015/06/12 Javascript
jQuery实现hover合成事件的方法
2015/08/06 Javascript
json定义及jquery操作json的方法
2016/09/29 Javascript
jQuery 局部div刷新和全局刷新方法总结
2016/10/05 Javascript
canvas雪花效果核心代码分享
2017/02/19 Javascript
jQuery实现贪吃蛇小游戏(附源码下载)
2017/03/04 Javascript
Angular2之二级路由详解
2018/08/31 Javascript
Vue 2.0 侦听器 watch属性代码详解
2019/06/19 Javascript
koa2 从入门到精通(小结)
2019/07/23 Javascript
微信小程序组件传值图示过程详解
2019/07/31 Javascript
Layui之table中的radio在切换分页时无法记住选中状态的解决方法
2019/09/02 Javascript
Vue 实现从小到大的横向滑动效果详解
2019/10/16 Javascript
javascript实现贪吃蛇小练习
2020/07/05 Javascript
vue $router和$route的区别详解
2020/12/02 Vue.js
[48:20]OpTic vs Serenity 2018国际邀请赛小组赛BO2 第二场 8.18
2018/08/19 DOTA
Python构造函数及解构函数介绍
2015/02/26 Python
Python HTMLParser模块解析html获取url实例
2015/04/08 Python
约瑟夫问题的Python和C++求解方法
2015/08/20 Python
利用selenium 3.7和python3添加cookie模拟登陆的实现
2017/11/20 Python
django Serializer序列化使用方法详解
2018/10/16 Python
Python实例方法、类方法、静态方法的区别与作用详解
2019/03/25 Python
Python re 模块findall() 函数返回值展现方式解析
2019/08/09 Python
python实发邮件实例详解
2019/11/11 Python
Python 日期与时间转换的方法
2020/08/01 Python
J2EE相关知识面试题
2013/08/26 面试题
保护环境建议书
2014/03/12 职场文书
竞选文艺委员演讲稿
2014/04/28 职场文书
小学数学继续教育研修日志
2015/11/13 职场文书
go mod 安装依赖 unkown revision问题的解决方案
2021/05/06 Golang
使用RedisTemplat实现简单的分布式锁
2021/11/20 Redis