Call us Toll-Free:
1-800-218-1525
Live ChatEmail us

 Sponsors

How to create a PHP Daemon

Mike Peters, 04-14-2010
A daemon is a Linux program that runs in the background.

Most daemons are written in C. While C is faster and more robust than PHP, looking at development time and cost, PHP generally scores a lot better than C.

Converting your C daemons to PHP where applicable, makes the code more accessible to a wider percentage of your development force and allows better re-use and connecting of existing code.

To Facebook, keeping all code accessible to all developers was so important, that they've decided to come up with a way to compile PHP to C in real time. So you get PHP speed of development with C speed. The HipHop toolkit is available on an open source license.

The simple PHP4 functions included here, will let you easily create PHP daemons.

Features:
* Daemon will not start if another instance is already running
* Daemon PID saved to /var/run/
* Daemon log messages saved to /var/log/
* Run in foreground mode with the "-f" flag

Sample daemon:


require_once("common_daemon.php");

// Get parameters from command line
foreach ($argv as $parameter)
{
 
$run_in_foreground = Strcasecmp($parameter,"-f")==0;
}

// Start our daemon
if (!PHPDaemonStart("mydaemon", $run_in_foreground))
{
 
// Already running
 
return;
}

// Do something useful
while (1)
{
 
PHPDaemonLog("Hello, the time is ".date("h:i:s", time()));
 
sleep(1);
}

// Never here

The common_daemon.php functions:


// Give us eternity to execute the script.
ini_set("max_execution_time", "0");
ini_set("max_input_time", "0");
set_time_limit(0);

function
PHPDaemonStart($name, $run_in_foreground=0)
{
 
// This must be global so that the handle is kept alive
  // after this function exits
 
global $handle_lockfile;

 
// Remember the daemon name
 
global $phpdaemon_name;
 
$phpdaemon_name = $name;

 
// Remember if we're running in foreground mode
 
global $phpdaemon_run_in_foreground;
 
$phpdaemon_run_in_foreground = $run_in_foreground;

 
// Open PID file
 
$tmpfilename = "/var/run/$name.pid";
  if (!(
$handle_lockfile = @fopen($tmpfilename,"a+")))
  {
   
// Script already running - abort
   
return 0;
  }

 
// Obtain an exlcusive lock on file
  // (If script is running this will fail)
 
if (!@flock( $handle_lockfile, LOCK_EX | LOCK_NB, &$wouldblock) || $wouldblock)
  {
   
// Script already running - abort
   
@fclose($handle_lockfile);
    return
0;
  }

 
// Write our PID
 
@ftruncate($handle_lockfile,0);
  @
fseek($handle_lockfile, 0, 0);
  @
fwrite($handle_lockfile, getmypid());
  @
fflush($handle_lockfile);

 
// If we need to run in foreground, we're done
 
if ($run_in_foreground)
  {
    return
1;
  }

 
// If we're up to here we need to fork our process
 
$pid = pcntl_fork();
  if (
$pid==-1)
  {
   
// Can't fork
   
return 0;
  }

 
// If we are the parent
 
if ($pid)
  {
   
// Sleep for 2 seconds, letting the forked process wake up
    // and attempt to grab our lock
   
sleep(2);

   
// Release the lock
   
@flock($handle_lockfile, LOCK_UN);

   
// Close file
   
fclose($handle_lockfile);

   
// Kill parent process
    // By now the child has the lock
   
die;
  }
 
// (Else - we are the child)
 
else
  {
   
// Open file
   
while (!($handle_lockfile = @fopen($tmpfilename, "a+")))
    {
     
// Try again
     
usleep(100);
    }

   
// Re-establish lock on file
   
while (!@flock($handle_lockfile, LOCK_EX, &$wouldblock))
    {
     
// Try again
     
usleep(100);
    }

   
// Write pid into file
   
@ftruncate($handle_lockfile,0);
    @
fseek($handle_lockfile, 0, 0);
    @
fwrite($handle_lockfile, getmypid());
    @
fflush($handle_lockfile);
  }

 
// We have a lock - all good
 
return 1;
}

function
PHPDaemonLog($str)
{
 
// This is the daemon name
 
global $phpdaemon_name;

 
// This indicates whether or not we are running in foreground mode
 
global $phpdaemon_run_in_foreground ;

 
// Open log file
 
$handle = @fopen("/var/log/$phpdaemon_name.log", "a");

 
// Obtain an exclusive lock (so that this is thread safe)
 
flock($handle, LOCK_EX, &$wouldblock);

 
// Write
 
$output = date("Y-m-d h:i:s", time())." $str\r\n";
  @
fwrite($handle, $output);

 
// If we are running in foreground mode, output to screen as well
 
if ($phpdaemon_run_in_foreground) echo $output;

 
// Release lock
 
flock($handle, LOCK_UN);

 
// Close file
 
fclose($handle);
}

function
IsPHPDaemonRunning($name)
{
 
// Open PID file
 
$tmpfilename = "/var/run/$name.pid";
  if (!(
$tmpfile = @fopen($tmpfilename,"r")))
  {
   
// Script not running
   
return 0;
  }

 
// Obtain an exlcusive lock on file
  // (If script is running this will fail)
 
$not_running = flock( $tmpfile, LOCK_EX | LOCK_NB, &$wouldblock);

 
// Release lock if successful
 
if ($not_running) flock($tmpfile, LOCK_UN);

 
// Close file
 
@fclose($tmpfile);

 
// Return result
 
return !$not_running || $wouldblock;
}

Szyszeja Leonidas, 08-02-2010
Hi, how can i stop the deaemon?
Thanks!
Enjoyed this post?

Subscribe Now to receive new posts via Email as soon as they come out.

 Comments
Post your comments












Note: No link spamming! If your message contains link/s, it will NOT be published on the site before manually approved by one of our moderators.



About Us  |  Contact us  |  Privacy Policy  |  Terms & Conditions