This afternoon in segmentfault.com to see a question, ask the title is "How To do PHP service", which asked whether PHP can only be called on the web. In fact, many people have misunderstood the use of PHP scenarios, that PHP can only be used to write web scripts, in fact, starting from PHP4, PHP's use of the scene has long been not limited to processing Web requests.
From the PHP architecture, PHP is divided into three levels: SAPI, PHP core and Zend engine. The PHP core itself is not coupled with the web, and PHP communicates with other applications via SAPI, such as mod_php, which is a SAPI implementation for Apache, and FPM is a fastcgi implementation based on the SAPI protocol, which is the SAPI of the Web Server to work with Web requests. But there are a lot of SAPI that are not web-like, such as the CLI SAPI can enable direct execution of php,embed in a command-line environment SAPI can embed PHP in other languages (such as LUA). I'm not going to discuss the architecture and SAPI of PHP in detail here, just to show that PHP is already designed to support a variety of environments, rather than web-specific, from the architecture perspective.
In addition to the support of the architecture system, PHP's rich extension modules also provide the backing for PHP to work in different environments, such as the Pcntl module and the POSIX module to implement basic process management, signal processing and other operating system-level functions. And the sockets module enables PHP to have socket communication capabilities. So PHP can be used to write tool scripts like Shell or Perl, even daemon process with a server nature.
To show how PHP writes daemon server, I wrote a simple HTTP server in PHP that runs in the form of a daemon process. Of course, in order to focus on how to write daemon in PHP, I did not implement the specific business logic for this HTTP server, but it can listen to the specified port, accept the HTTP request and return to the client a fixed text, the whole process through the socket implementation, all from PHP written. Code Instances
Here is the complete code for this program:
<?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 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 ($pid 1 = pcntl_fork () = = 0)//first child process {posix_setsid ();//set
Child process as the session leader.
if ($pid 2 = 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 the ' the '.
Pcntl_wait ($status);
}//entry point.
Run (); ?>
Here I assume that you have a better understanding of UNIX environment programming, so do not do too many details of the explanation, just comb it. In simple terms, this program consists of two parts, the Handle_http_request function is responsible for processing HTTP requests, which are written in the same way as TCP server written in C: creating sockets, binding, listening, Then through a loop to handle each connect over the client, once accept to a connection, then output the fixed text "PHP http Server" (Of course, HTTP headers need to be built first), here does not consider multiplexing and non-blocking, etc. Instead, it's just a simple synchronization blocking TCP server.
The run function is responsible for turning the entire program into a daemon process, which is similar to the C method in the UNIX environment, with a fork of two times, the first fork, and then the Setsid to turn subprocess 1 into session leader. This allows child process 2 to be detach with its ancestors, even if the ancestor process ends (Tuogu to the init process). Related details I will not repeat, the UNIX process-related unfamiliar friends can refer to the "Advanced programming in the UNIX Environment" book.
Note that here pcntl_fork corresponds to the fork,pcntl_wait in Unix and posix_setsid corresponds to SETSID, and more functions refer to Manual and Pcntl modules in the PHP fork. Inspection
This script starts at the command line below:
PHP httpserver.php
With the PS command we can see that we have started a daemon process:
Here I am bound is the domain name of my blog www.codinglabs.org, Port is 9999, can be changed as needed.
Let me first use the Curl command to see if this HTTP server is working correctly:
Seems to be no problem, and then go to the browser to see:
Conclusion
Of course, this program is not really HTTP server, even as a daemon process, is also imperfect, a lot of necessary things such as modify the execution directory (PHP can be implemented through chroot), signal binding, log functions, etc. are not done, But as a demo, it's enough to show that PHP is more than just a dynamic web-processing script. If some friends are interested, you can use PHP to add the features I said above to this HTTP server.
Another point to note is that the PCNTL and sockets modules are not installed by default, and if you do not specify the installation by parameter when you install PHP, you will need to install the two extension modules separately.