Home >Backend Development >PHP Tutorial >PHP advanced programming examples: writing daemon process, programming example daemon process_PHP tutorial

PHP advanced programming examples: writing daemon process, programming example daemon process_PHP tutorial

WBOY
WBOYOriginal
2016-07-13 10:19:31997browse

PHP advanced programming examples: writing daemons, programming example daemons

1. What is a daemon process

A daemon is a process that is separated from the terminal and runs in the background. The daemon process is separated from the terminal to prevent information during the execution of the process from being displayed on any terminal and the process will not be interrupted by terminal information generated by any terminal.

For example, apache, nginx, and mysql are all daemon processes

2. Why develop daemon process

Many programs exist in the form of services. They do not have terminal or UI interaction. They may interact with other programs in other ways, such as TCP/UDP Socket, UNIX Socket, fifo. Once the program is started, it goes into the background and starts processing tasks until the conditions are met.

3. When to use daemon process to develop applications

Take my current needs as an example. I need to run a program, then listen to a certain port, continue to receive data initiated by the server, then analyze and process the data, and then write the results to the database; I use ZeroMQ to implement the data Send and receive.

If I do not use the daemon process to develop this program, once the program is run, it will occupy the current terminal window frame, and it may be affected by the current terminal keyboard input, and the program may exit accidentally.

4. Security issues of daemon process

We hope that the program will run as a non-superuser, so that once the program is controlled by a hacker due to a vulnerability, the attacker can only inherit the running permissions but cannot obtain the superuser permissions.

We hope that the program can only run one instance, and do not run more than two programs at the same time, because problems such as port conflicts will occur.

5. How to develop a daemon process

Example 1. Daemon process example

<&#63;php
class ExampleWorker extends Worker {

 #public function __construct(Logging $logger) {
 # $this->logger = $logger;
 #}

 #protected $logger;
 protected static $dbh;
 public function __construct() {

 }
 public function run(){
  $dbhost = '192.168.2.1';  // 数据库服务器
  $dbport = 3306;
   $dbuser = 'www';  // 数据库用户名
 $dbpass = 'qwer123';    // 数据库密码
  $dbname = 'example';  // 数据库名

  self::$dbh = new PDO("mysql:host=$dbhost;port=$dbport;dbname=$dbname", $dbuser, $dbpass, array(
   /* PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\'', */
   PDO::MYSQL_ATTR_COMPRESS => true,
   PDO::ATTR_PERSISTENT => true
   )
  );

 }
 protected function getInstance(){
 return self::$dbh;
  }

}

/* the collectable class implements machinery for Pool::collect */
class Fee extends Stackable {
 public function __construct($msg) {
  $trades = explode(",", $msg);
  $this->data = $trades;
  print_r($trades);
 }

 public function run() {
  #$this->worker->logger->log("%s executing in Thread #%lu", __CLASS__, $this->worker->getThreadId() );

  try {
   $dbh = $this->worker->getInstance();
   
   $insert = "INSERT INTO fee(ticket, login, volume, `status`) VALUES(:ticket, :login, :volume,'N')";
   $sth = $dbh->prepare($insert);
   $sth->bindValue(':ticket', $this->data[0]);
   $sth->bindValue(':login', $this->data[1]);
   $sth->bindValue(':volume', $this->data[2]);
   $sth->execute();
   $sth = null;
   
   /* ...... */
   
   $update = "UPDATE fee SET `status` = 'Y' WHERE ticket = :ticket and `status` = 'N'";
   $sth = $dbh->prepare($update);
   $sth->bindValue(':ticket', $this->data[0]);
   $sth->execute();
   //echo $sth->queryString;
   //$dbh = null;
  }
  catch(PDOException $e) {
   $error = sprintf("%s,%s\n", $mobile, $id );
   file_put_contents("mobile_error.log", $error, FILE_APPEND);
  }
 }
}

class Example {
 /* config */
 const LISTEN = "tcp://192.168.2.15:5555";
 const MAXCONN = 100;
 const pidfile = __CLASS__;
 const uid = 80;
 const gid = 80;
 
 protected $pool = NULL;
 protected $zmq = NULL;
 public function __construct() {
  $this->pidfile = '/var/run/'.self::pidfile.'.pid';
 }
 private function daemon(){
  if (file_exists($this->pidfile)) {
   echo "The file $this->pidfile exists.\n";
   exit();
  }
  
  $pid = pcntl_fork();
  if ($pid == -1) {
    die('could not fork');
  } else if ($pid) {
    // we are the parent
    //pcntl_wait($status); //Protect against Zombie children
   exit($pid);
  } else {
   // we are the child
   file_put_contents($this->pidfile, getmypid());
   posix_setuid(self::uid);
   posix_setgid(self::gid);
   return(getmypid());
  }
 }
 private function start(){
  $pid = $this->daemon();
  $this->pool = new Pool(self::MAXCONN, \ExampleWorker::class, []);
  $this->zmq = new ZMQSocket(new ZMQContext(), ZMQ::SOCKET_REP);
  $this->zmq->bind(self::LISTEN);
  
  /* Loop receiving and echoing back */
  while ($message = $this->zmq->recv()) {
   //print_r($message);
   //if($trades){
     $this->pool->submit(new Fee($message));
     $this->zmq->send('TRUE'); 
   //}else{
   // $this->zmq->send('FALSE'); 
   //}
  }
  $pool->shutdown(); 
 }
 private function stop(){

  if (file_exists($this->pidfile)) {
   $pid = file_get_contents($this->pidfile);
   posix_kill($pid, 9); 
   unlink($this->pidfile);
  }
 }
 private function help($proc){
  printf("%s start | stop | help \n", $proc);
 }
 public function main($argv){
  if(count($argv) < 2){
   printf("please input help parameter\n");
   exit();
  }
  if($argv[1] === 'stop'){
   $this->stop();
  }else if($argv[1] === 'start'){
   $this->start();
  }else{
   $this->help($argv[0]);
  }
 }
}

$cgse = new Example();
$cgse->main($argv);

5.1. Program startup

The following is the code to enter the background after the program is started

Judge the current process status through the process ID file. If the process ID file exists, it means that the program is running. This is achieved through the code file_exists($this->pidfile). However, if the process is killed, the file must be manually deleted before it can run.

private function daemon(){
  if (file_exists($this->pidfile)) {
   echo "The file $this->pidfile exists.\n";
   exit();
  }
  
  $pid = pcntl_fork();
  if ($pid == -1) {
    die('could not fork');
  } else if ($pid) {
   // we are the parent
   //pcntl_wait($status); //Protect against Zombie children
   exit($pid);
  } else {
   // we are the child
   file_put_contents($this->pidfile, getmypid());
   posix_setuid(self::uid);
   posix_setgid(self::gid);
   return(getmypid());
  }
 }

After the program starts, the parent process will be launched, the child process will run in the background, the child process permissions will be switched from root to the specified user, and the pid will be written to the process ID file.

5.2. Program stop

The program stops, just read the pid file, then call posix_kill($pid, 9); and finally delete the file.

private function stop(){

  if (file_exists($this->pidfile)) {
   $pid = file_get_contents($this->pidfile);
   posix_kill($pid, 9); 
   unlink($this->pidfile);
  }
 }

Will advanced PHP programming involve java

Very advanced ones will be involved. Because Java can do so much.

The production idea and application of PHP daemon is urgently needed. The team needs it. There is cocoa for long-term cooperation, but there is no money to get it. Only points

It is recommended to use ignore_user_abort for specific ideas. Private chat and long-term cooperation are also possible, but time is a bit tight

www.bkjia.comtruehttp: //www.bkjia.com/PHPjc/873340.htmlTechArticlePHP Advanced Programming Examples: Writing Daemon Processes, Programming Examples Daemon Process 1. What is a daemon process? The daemon process is separated from Terminal and a process running in the background. The daemon is detached from the terminal...
Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn