How can I prevent PHP from executing code multiple times?
I have a WordPress plugin with a backup script that runs on a schedule. The trick is if someone hits the page multiple times, it can backup the script multiple times. Any thoughts on how to prevent multiple executions?
global $bwpsoptions;
if ( get_transient( 'bit51_bwps_backup' ) === false ) {
set_transient( 'bit51_bwps_backup', '1', 300 );
if ( $bwpsoptions['backup_enabled'] == 1 ) {
$nextbackup = $bwpsoptions['backup_next']; //get next schedule
$lastbackup = $bwpsoptions['backup_last']; //get last backup
switch ( $bwpsoptions['backup_interval'] ) { //schedule backup at appropriate time
case '0':
$next = 60 * 60 * $bwpsoptions['backup_time'];
break;
case '1':
$next = 60 * 60 * 24 * $bwpsoptions['backup_time'];
break;
case '2':
$next = 60 * 60 * 24 * 7 * $bwpsoptions['backup_time'];
break;
}
if ( ( $lastbackup == '' || $nextbackup < time() ) && get_transient( 'bit51_bwps_backup' ) === false ) {
$bwpsoptions['backup_last'] = time();
if ( $lastbackup == '' ) {
$bwpsoptions['backup_next'] = ( time() + $next );
} else {
$bwpsoptions['backup_next'] = ( $lastbackup + $next );
}
update_option( $this->primarysettings, $bwpsoptions );
$this->execute_backup(); //execute backup
}
}
}
source to share
If your site is very busy and the main blocking mechanism isn't working (I personally can't imagine it, but good!), You can try the solution from the PHP session garbage collector.
Just randomly pick a number between 0 and 10, and if the number is 0, make a backup. If now 10 users call your backup script at about the same time, statistically only one will actually be backing up.
define("BACKUP_PROBABILITY", 10);
if (mt_rand(0, BACKUP_PROBABILITY) == 0)
doBackup();
You can increase the maximum (10) if your site is visited very often.
If in these 10 visits none got 0, the next 10 visitors will get their chance.
You will need some kind of locking mechanism, of course, and it is still possible (albeit implausible) that you will have more than one or even 10 backups.
I found this question about mutexes (locks) in PHP. May be useful: PHP mutual exclusion (mutex)
source to share