Proposal for "Daemon"

出てた。
PEAR_Serverと違うところは、ネットの通信とかの処理がないところ。

まだ詳しくソース読んでないんだけど、chmod('/')とか標準入出力が閉じられてないような気がする。
実は先週くらいから似たようなのを作ってて結構気になってるライブラリです。

自分の肝のところさらしておくけど、まだ完全に思索段階(誤字じゃなて仕様を模索している段階)いくつかメソッドがなかったり複数のプロセスに対応してないとか、本当に標準入出力閉じられてるか確認してなかったりだめだめです。

class Holo_Daemon
{
    const PERFORM = 'perform';
    private $thread_num = 1;
    private  $handlers = array();
 
    static public function daemonize()
    { 
        declare(ticks = 1);
        ini_set("max_execution_time", "0");
        ini_set("max_input_time", "0");
        set_time_limit(0);

        $pid = pcntl_fork();
        if($pid) {
            exit(); 
        }
     
        posix_setsid();
     
        $pid = pcntl_fork();
        if($pid) {
            exit(); 
        }

        chdir('/');
        umask(0);
        fclose(STDOUT); 
        fclose(STDIN); 
        fclose(STDERROR); 
    }

    public function run()
    {
        self::daemonize();
        
        pcntl_signal(SIGTERM, array($this, 'signal_handler'));
        pcntl_signal(SIGHUP, array($this, 'signal_handler'));
        while (true) {
            $this->handler(self::PERFORM);
        }
    }

   
    private function __constractor($thread_num = 1)
    {
      $this->tread_num = $thread_num;
    }

    //todo removeHandler or clearHanler
    public function addHandler($key, $function)
    {
        if (isset($this->handlers[$key]) === false) {
            $this->handlers[$key] = array();
        }
        $this->handlers[$key][] = $function;
    }

    private function signal_handler($signo)
    {
         $this->handler($signo);
         if ($signo === SIGTERM) {
              exit;
         }

    }
    
    private function handler($handler)
    {
        if (isset($this->handlers[$handler]) === true ) {
            foreach ($this->handlers[$handler] as $function) {
                $function($this);
            }
        }
    }    
}

使い方

  require_once('lib/Daemon.php');

  $Daemons = new Holo_Daemon(1);
  $Daemons->addHandler(Holo_Daemon::PERFORM, 'testecho'); 
  $Daemons->addHandler(SIGTERM, 'testend'); 
  $Daemons->run();
 
 
  function testecho($obj) {
      echo posix_getpid() . "\n";
      sleep(2);
  }
  function testend($obj) {
      error_log("test\n",3,'/tmp/test.log'); 
  }