The PHP daemon class, the daemon (Daemon) is a special process that runs in the background. It is independent of the control terminal and periodically performs some sort of task or waits to handle certain occurrences. Daemons are a very useful process. PHP can also implement the Daemon function, the need for friends can refer to the following
The daemon class implemented in PHP. You can implement a queue on a server or a scheduled task that is out of crontab.
When used, it inherits from this class and overrides the _dotask method, which is executed through main initialization.
_logmessage (' starting daemon '); if (! $this->_daemonize ()) {$this->_logmessage (' Could not start daemon ', self::D log_error); return false; } $this->_logmessage (' Running ... '); $this->_isrunning = true; while ($this->_isrunning) {$this->_dotask (); } return true; }/** * Stops the process * * @return void */Public Function Stop () {$this->_logmessage (' stoping daemon '); $this->_isrunning = false; }/** * Do task * * @return void */protected function _dotask () {//override this method}/** * _log Message * Logging * * @param string message * @param integer level * @return void */protected function _logmessage ($msg , $level = self::D log_notice) {//override this method}/** * daemonize * * Several rules or characteristics That most daemons possess: * 1) Check was daemon already running * 2) Fork child process * 3) sets identity * 4) M Ake current Process a session Laeder *5) Write Process ID to file * 6) Change Home path * 7) umask (0) * * @access Private * @since 1.0 * @return Voi d */Private function _daemonize () {Ob_end_flush (); if ($this->_isdaemonrunning ()) {//Deamon is already running. Exiting return false; } if (! $this->_fork ()) {//Coudn ' t fork. Exiting. return false; } if (! $this->_setidentity () && $this->requiresetidentity) {//Required identity set failed. Exiting return false; } if (!posix_setsid ()) {$this->_logmessage (' Could not make the current process a session leader ', self::D log_ ERROR); return false; } if (! $fp = fopen ($this->pidfilelocation, ' W ')) {$this->_logmessage (' Could not write to PID file ', Self:: DLOG_ERROR); return false; } else {fputs ($fp, $this->_pid); Fclose ($FP); }//write to the monitoring log $this->writeprocess (); ChDir ($this->homepath); Umask (0); DECLARE (ticks = 1); Pcntl_signal (SIGCHLD, Array (& $this, ' Sighandler ')); Pcntl_signal (SIGTERM, Array (& $this, ' Sighandler ')); Pcntl_signal (SIGUSR1, Array (& $this, ' Sighandler ')); Pcntl_signal (SIGUSR2, Array (& $this, ' Sighandler ')); return true; }/** * Cheks is daemon already running * * @return BOOL */Private Function _isdaemonrunning () {$oldPid = File_get_contents ($this->pidfilelocation); if ($oldPid!== false && Posix_kill (Trim ($oldPid), 0)) {$this->_logmessage (' Daemon already running with PID: '. $oldPid, (self::D log_to_console | self::D log_error)); return true; } else {return false; }}/** * Forks process * * @return BOOL */Private Function _fork () {$this->_logmessage (' forking ... ') ; $pid = Pcntl_fork (); if ($pid = =-1) {//Error $this->_logmessage (' Could not fork ', self::D log_error); return false; } elseif ($pid) {//parent process $this->_LOGMESSAGE (' Killing parent '); Exit (); } else {//fork of child process $this->_ischildren = true; $this->_pid = Posix_getpid (); return true; }}/** * Sets identity of a daemon and returns result * * @return BOOL */Private Function _setidentity () { if (!posix_setgid ($this->groupid) | |!posix_setuid ($this->userid)) {$this->_logmessage (' Could not set Identity ', self::D log_warning); return false; } else {return true; }}/** * Signals handler * * @access Public * @since 1.0 * @return void */Public function Sighandler ($si GNo) {switch ($sigNo) {case SIGTERM://Shutdown $this->_logmessage (' Shutdown signal '); Exit (); Break Case SIGCHLD://Halt $this->_logmessage (' Halt signal '); while (Pcntl_waitpid ( -1, $status, Wnohang) > 0); Break Case SIGUSR1://user-defined $this->_logmessage (' user-defined signal 1 '); $this->_sighandleruser1 (); Break Case SIGUSR2://user-defined $this->_logmessage (' user-defined signal 2 '); $this->_sighandleruser2 (); Break }}/** * Signals HANDLER:USR1 * is primarily used to periodically clean up DNS resolution records for cached domain names in each process * * @return void */protected function _sighand LerUser1 () {apc_clear_cache (' user '); }/** * Signals HANDLER:USR2 * For writing heartbeat package file * * @return void */protected function _sighandleruser2 () {$th Is->_initprocesslocation (); File_put_contents ($this->processheartlocation, Time ()); return true; }/** * Releases daemon pid file * This method was called on exit (destructor like) * * @return void */Public function Releasedaemon () {if ($this->_ischildren && is_file ($this->pidfilelocation)) {$this _logmessage (' releasing Daemon '); Unlink ($this->pidfilelocation); }}/** * Writeprocess * Writes the current process information to the monitoring log, the other script scans the data sending signal of the monitoring log and restarts the process if there is no response * * @return void */Public Function writeprocess () {//Initialize proc $this->_initprocesslocation (); $command = Trim (implode (' ', $_server[' argv ')); Specifies the directory of the process $processDir = $this->processlocation. '/' . $this->_pid; $processCmdFile = $processDir. '/cmd '; $processPwdFile = $processDir. '/pwd '; The directory where all processes are located if (!is_dir ($this->processlocation)) {mkdir ($this->processlocation, 0777); chmod ($processDir, 0777); }//Query duplicate process record $pDirObject = Dir ($this->processlocation); while ($pDirObject && ($pid = $pDirObject->read ())!== false) {if ($pid = = '. ' | | $pid = = ' ... ' | | intva L ($pid)! = $pid) {continue; } $pDir = $this->processlocation. '/' . $pid; $pCmdFile = $pDir. '/cmd '; $pPwdFile = $pDir. '/pwd '; $pHeartFile = $pDir. '/heart '; The process of starting the same parameter according to the CMD check if (Is_file ($pCmdFile) && trim (file_get_contents ($pCmdFile)) = = $command) {unlink ($pCmdFile); Unlink ($pPwdFile); Unlink ($pHeartFile); Delete Directory has cache usleep (1000); RmDir ($pDir); }}//New process directory if (!is_dir ($processDir)) {mkdir ($processDir, 0777); chmod ($processDir, 0777); }//write command parameter file_put_contents ($processCmdFile, $command); File_put_contents ($processPwdFile, $_server[' PWD '); Write files have cache usleep (1000); return true; }/** * _initprocesslocation * Initialize * * @return void */protected function _initprocesslocation () {$this- >processlocation = Root_path. '/app/data/proc '; $this->processheartlocation = $this->processlocation. '/' . $this->_pid. '/heart '; }}