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到一个连接...

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

时间: 2024-09-14 00:38:07

PHP编写daemon process详解及实例代码的相关文章

PHP编写daemon process详解及实例代码_php实例

今天下午在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编写的

php mysql insert into 结合详解及实例代码_Mysql

php mysql insert into 结合详解 ySQL INSERT INTO语句在实际应用中是经常使用到的语句,所以对其相关的内容还是多多掌握为好. 向数据库表插入数据 INSERT INTO 语句用于向数据库表添加新记录. 语法 INSERT INTO table_name VALUES (value1, value2,....) 您还可以规定希望在其中插入数据的列: INSERT INTO table_name (column1, column2,...) VALUES (valu

MySQL MEM_ROOT详解及实例代码_Mysql

MySQL MEM_ROOT详解 这篇文章会详细解说MySQL中使用非常广泛的MEM_ROOT的结构体,同时省去debug部分的信息,仅分析正常情况下,mysql中使用MEM_ROOT来做内存分配的部分. 在具体分析之前我们先例举在该结构体使用过程中用到的一些宏: #define MALLOC_OVERHEAD 8 //分配过程中,需要保留一部分额外的空间 #define ALLOC_MAX_BLOCK_TO_DROP 4096 //后续会继续分析该宏的用途 #define ALLOC_MAX_

Android ViewPagerIndicator详解及实例代码

Android ViewPagerIndicator详解及实例代码 关于自定义View的属性零碎知识 自定义View和自定义属性的知识不再此提及,这里着重说的是属性在自定义View中的获取方式,自定义的属性如下: <?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="Wisely"> <attr name=&

Android Dialog详解及实例代码

Android Dialog详解及实例代码 概述: Android开发中最常用的就是Dialog类,除了自定义dialog布局,最多的就是用在弹出对话框.进度条.输入框.单选.复选框. 1.选择对话框: AlertDialog.Builder dialog = new AlertDialog.Builder(this); dialog.setTitle("选择对话框"); dialog.setMessage("请选择确认或取消"); dialog.setCancel

ReactNative Alert详解及实例代码_Android

Alert顾名思义一就是一个警告框,一般使用情况比如:退出登录,清楚缓存,提示修改密码等等...ReactNative中的Alert只有一个静态方法alert()其中有四个参数:标题,信息,按钮和按钮类型 在Android按钮至多有三个 下面是使用情况: 实例代码: /** * Created by Administrator on 2016/9/12. */ import React, {Component} from 'react'; import { StyleSheet, View, T

C++函数重载详解及实例代码_C 语言

C++函数的重载 定义 在同一个作用域中,函数名相同,函数的参数列表不同的函数之间构成重载关系,在不同作用域中的同名函数遵循标识符隐藏的原则 ATTENTION:重载与函数的返回值类型无关,因为声明一个函数不需要返回类型,所以无法用来区分哪个函数 常函数和普通成员函数之间构成重载,重载时常对象调用常成员函数,一般对象调用一般成员函数 class A{ - public: void getVal()const{-} void getVal(){-} }; int main(){ const A a

php array_multisort 对数组进行排序详解及实例代码_php实例

php 中array_multisort() 函数可以用来一次对多个数组进行排序,或者根据某一维或多维对多维数组进行排序.本文章向大家讲解array_multisort函数的使用方法.  array_multisort() 函数返回排序数组.您可以输入一个或多个数组.函数先对第一个数组进行排序,接着是其他数组,如果两个或多个值相同,它将对下一个数组进行排序. 注释:字符串键名将被保留,但是数字键名将被重新索引,从 0 开始,并以 1 递增. 注释:您可以在每个数组后设置排序顺序和排序类型参数.如

OpenStack Heat AutoScaling详解及实例代码_OpenStack

OpenStack Heat AutoScaling 一.背景 Openstack的Heat是在H版之后加入的组件,旨在创建一套业务流程,更轻松的管理一个集群.集群内的虚拟机可以作为一个整体,统一的为客户提供服务.Heat中把功能定义成资源,在Heat中会用到Nova,Neutron,Ceilometer等组件,这些都可以看成是资源,通过模板文件来描述,模板文件可以是yaml格式,也可以是json格式,一般是yaml格式. AutoScaling的概念最早出现在AWS,AutoScaling是一