Jump to content

max of 1 instance of a PHP script


1RV34

Recommended Posts

I have seen a lot of ways to determen if a PHP script is already running but I wonder which solution is the best.Currently I'm using this:

<?php  $run = basename($_SERVER['PHP_SELF'], '.php') . '.run';   if (!file_exists($run) {	touch($run);  }  else {	echo "Already running!";	exit;  }   // ... (rest of code)?>

But I already have seen a lot examples using pid's & sid's and everything. I'm sure my solution is not the best at all and so I'm asking you all to discuss your solutions with me.

Link to comment
Share on other sites

I am not sure about your purpose. what is your objective? if you run the code it will show already running but that does not mean it is runing when you are reading. php page processed and served after that output has produced in browser.

Link to comment
Share on other sites

I am not sure about your purpose. what is your objective? if you run the code it will show already running but that does not mean it is runing when you are reading. php page processed and served after that output has produced in browser.
What do you mean?There is a long script on the position of
  // ... (rest of code)

and I only want one instance of that script running at a time.It is a script that can run from 4 seconds to 15 minutes and I want to make sure it can't be run twice at the same time.

Link to comment
Share on other sites

you can use a file where the file execution timestamp will be stored in another file using fopen() after that you can lock that file using flock(). when you use lock on the file it wont let you paralaly open the file.now it can be used as flag. so in the script check the file is unlocked or not. if it is locked it means one process is runing. if it is open do the heavy stuff or show the errors. there would be more better way solving this. but thats what i can think of now.

Link to comment
Share on other sites

The way I do it is to use a text file like you are, but I set the contents of the file to "true" or "false" depending on whether the script is running. So when the script starts it reads that file, and if the contents of the file equals "true" then the script ends because it's already running. If the file contains "false" then it writes "true" to the file and starts running. The key is to use register_shutdown_function to define a function that runs when the script ends to set the file back to "false". This will even execute if the script contains a fatal runtime error, so even if the script dies because of an error the shutdown function will still run and will still set the file back to false so that the next time the script runs it knows that it's not already running. http://www.php.net/m...wn-function.php

$mail_file = 'path/to/' . 'mail_check.log';$check = trim(file_get_contents($mail_file)); if ($check == 'true') exit('already running'); register_shutdown_function('reset_mail_file', $mail_file);file_put_contents($mail_file, 'true');  // do the work  echo 'done'; function reset_mail_file($fname){  file_put_contents($fname, 'false');}

Link to comment
Share on other sites

  • 2 weeks later...

Combined the shutdown function & timestamp method a bit and came up with this:

<?php  $run = basename($_SERVER['PHP_SELF'], '.php') . '.run';  if (!file_exists($run) {    touch($run);    register_shutdown_function('shutdown', $run);    $microtime = microtime();    file_put_contents($run, $microtime);  }  else {    echo "Already running!";    exit;  }  // ... (some code)  sleep($waitForFirstStartup);// dynamic calculated value  while (file_exists($run) && file_get_contents($run) == $microtime) {    // ... (rest of code)    sleep($waitBetweenStuffToDo);// dynamic calculated value  }  function shutdown($run) {    unlink($run);  }?>

I think it's pretty fail-proof now :D

Link to comment
Share on other sites

Using a code like that will be slow due to disk I/O.It is much appropriate that you use APC or Wincache - those extensions maintain locks, as well as data, in memory, and ensure locks are obtained and released on a per request basis (as opposed to file locking, which works on per-process basis, thus making the writing of a value in the file necessary).I happen to be working on an abstraction layer for that so that you can use either extension. With it, you can do what you want with something like:

<?phpnamespace PEAR2\Cache;require_once 'PEAR2/Autoload.php';$shm = new SHM(basename($_SERVER['PHP_SELF'], '.php'));if ($shm->lock('run')) {    /*    Everything that needs to be done one at a time.    This will still be done the number of times the page was requested,    but each next request will only be executed once this section is finished by the previous one.    If you need to ensure something happens only once (in total), you may    have to check up with a database or something while being in this section.    */     $shm->unlock('run');}?>

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...