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
vBulletin HACK----显示话题大小和打开新窗口于论坛索引页
Oct 09 PHP
php 中的str_replace 函数总结
Apr 27 PHP
php Mysql日期和时间函数集合
Nov 16 PHP
php REMOTE_ADDR之获取访客IP的代码
Apr 22 PHP
PHP 飞信好友免费短信API接口开源版
Jul 22 PHP
PHP编码转换函数 自动转换字符集支持数组转换
Dec 16 PHP
完美实现wordpress禁止文章修订和自动保存的方法
Nov 03 PHP
PHP简单创建压缩图的方法
Aug 24 PHP
Centos 6.5下PHP 5.3安装ffmpeg扩展的步骤详解
Mar 02 PHP
php实现购物车产品删除功能(2)
Jul 23 PHP
Yii框架中用response保存cookie,用request读取cookie的原理解析
Sep 04 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
如何取得中文字符串中出现次数最多的子串
2013/08/08 PHP
PHP5.3以上版本安装ZendOptimizer扩展
2015/03/27 PHP
ThinkPHP数据操作方法总结
2015/09/28 PHP
php实现跨域提交form表单的方法【2种方法】
2016/10/17 PHP
php实现微信发红包功能
2018/07/13 PHP
javascript限制文本框只允许输入数字(曾经与现在的方法对比)
2013/01/18 Javascript
解决jquery submit()提交表单提示:f[s] is not a function
2013/01/23 Javascript
node.js中的fs.fsyncSync方法使用说明
2014/12/15 Javascript
javascript中Date对象的getDay方法使用指南
2014/12/22 Javascript
JavaScript数据类型之基本类型和引用类型的值
2015/04/01 Javascript
浅谈JavaScript字符串与数组
2015/06/03 Javascript
Javascript的表单与验证-非空验证
2016/03/18 Javascript
JavaScript中用let语句声明作用域的用法讲解
2016/05/20 Javascript
基于jQuery和hwSlider实现内容左右滑动切换效果附源码下载(一)
2016/06/22 Javascript
javascript类型系统——日期Date对象全面了解
2016/07/13 Javascript
jQuery中fadein与fadeout方法用法示例
2016/09/16 Javascript
VUE多层路由嵌套实现代码
2017/05/15 Javascript
Easyui在treegrid添加控件的实现方法
2017/06/23 Javascript
JS中call和apply函数用法实例分析
2018/06/20 Javascript
取消Bootstrap的dropdown-menu点击默认关闭事件方法
2018/08/10 Javascript
浅谈VUE单页应用首屏加载速度优化方案
2018/08/28 Javascript
Vue CLI3创建项目部署到Tomcat 使用ngrok映射到外网
2019/05/16 Javascript
Python开发实例分享bt种子爬虫程序和种子解析
2014/05/21 Python
python中enumerate的用法实例解析
2014/08/18 Python
matplotlib绘图实例演示标记路径
2018/01/23 Python
Python从使用线程到使用async/await的深入讲解
2018/09/16 Python
详解python项目实战:模拟登陆CSDN
2019/04/04 Python
不到20行代码用Python做一个智能聊天机器人
2019/04/19 Python
Python3实现配置文件差异对比脚本
2019/11/18 Python
基于python及pytorch中乘法的使用详解
2019/12/27 Python
一组SQL面试题
2016/02/15 面试题
入党积极分子思想汇报
2014/01/02 职场文书
2014年幼儿园安全工作总结
2014/11/10 职场文书
2015年重阳节活动主持词
2015/07/30 职场文书
vue实现水波涟漪效果的点击反馈指令
2021/05/31 Vue.js
攻击最高的10只幽灵系神奇宝贝,坚盾剑怪排第一,第五最为可怕
2022/03/18 日漫