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环境配置 php5 mysql5 apache2 phpmyadmin安装与配置
Nov 17 PHP
Windows2003 下 MySQL 数据库每天自动备份
Dec 21 PHP
php不用正则采集速度探究总结
Mar 24 PHP
php摘要生成函数(无乱码)
Feb 04 PHP
深入php多态的实现详解
Jun 09 PHP
单点登录 Ucenter示例分析
Oct 29 PHP
php随机显示图片的简单示例
Feb 15 PHP
浅析PHP程序设计中的MVC编程思想
Jul 28 PHP
PHP清除字符串中所有无用标签的方法
Dec 01 PHP
php实现递归的三种基本方式
Jul 04 PHP
PHP框架Laravel学习心得体会
Oct 28 PHP
PDO操作MySQL的基础教程(推荐)
Aug 18 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获取url字符串截取路径的文件名和扩展名的函数
2010/01/22 PHP
PHP中3种生成XML文件方法的速度效率比较
2012/10/06 PHP
PHP判断是否连接上网络的方法
2015/07/01 PHP
PHP封装的字符串加密解密函数
2015/12/18 PHP
如何用PHP做到页面注册审核
2017/03/02 PHP
centos7上编译安装php7以php-fpm方式连接apache
2018/11/08 PHP
laravel 获取某个查询的查询SQL语句方法
2019/10/12 PHP
网页前台通过js非法字符过滤代码(骂人的话等等)
2010/05/26 Javascript
基于jquery实现的上传图片及图片大小验证、图片预览效果代码
2011/04/12 Javascript
用最通俗易懂的代码帮助新手理解javascript闭包 推荐
2012/03/01 Javascript
快速解决jquery.touchSwipe左右滑动和垂直滚动条冲突
2016/04/15 Javascript
Jquery基础之事件操作详解
2016/06/14 Javascript
JS比较两个数值的大小实例
2016/11/25 Javascript
ng-options和ng-checked在表单中的高级运用(推荐)
2017/01/21 Javascript
微信小程序 网络通信实现详解
2019/07/23 Javascript
使用jQuery实现掷骰子游戏
2019/10/24 jQuery
JS实现的雪花飘落特效示例
2019/12/03 Javascript
环形加载进度条封装(Vue插件版和原生js版)
2019/12/04 Javascript
基于vue+echarts 数据可视化大屏展示的方法示例
2020/03/09 Javascript
[04:44]DOTA2 2017全国高校联赛视频回顾
2017/08/21 DOTA
Python元组操作实例分析【创建、赋值、更新、删除等】
2017/07/24 Python
使用pandas读取csv文件的指定列方法
2018/04/21 Python
对numpy Array [: ,] 的取值方法详解
2018/07/02 Python
Python实现的爬取百度贴吧图片功能完整示例
2019/05/10 Python
使用python实现unix2dos和dos2unix命令的例子
2019/08/13 Python
Python列表list常用内建函数实例小结
2019/10/22 Python
Python 实现判断图片格式并转换,将转换的图像存到生成的文件夹中
2020/01/13 Python
HTML5调用手机摄像头拍照的实现思路及代码
2014/06/15 HTML / CSS
旅游管理专业学生求职信
2013/09/28 职场文书
毕业生个人求职的自我评价
2013/10/28 职场文书
仓库班组长岗位职责
2013/12/12 职场文书
校园之声广播稿
2014/01/31 职场文书
财务审计整改报告
2014/11/06 职场文书
送给客户微信问候语!
2019/07/04 职场文书
解决springboot druid数据库连接失败后一直重连的方法
2022/04/19 Java/Android
MySql按时,天,周,月进行数据统计
2022/08/14 MySQL