2012-03-18 54 views
3

我有一个WordPress插件和一个按计划执行的备份脚本。值得注意的是,如果有人连续多次访问该页面,它可以多次执行备份脚本。有关如何防止多次执行的任何想法?如何防止PHP多次执行代码?

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 

       } 

      } 

     } 
+3

在数据库中设置一个表示时间的字段并进行计算,以便如果上次运行脚本和当前时间之间的差值大于't',则不要运行脚本。 – 2012-03-18 18:05:40

+0

你在哪里填充'$ bwpsoptions'?如果它不是来自外部来源,如数据库,文件,会话等,那么它将在下一页加载时被遗忘。 – 2012-03-18 18:08:48

回答

1

将最近的备份日期/时间存储在服务器上的某个外部文件或数据库中,并使用对该值的检查!

+0

试过了。在繁忙的网站上,文件锁定机制不够快... – 2012-03-18 18:09:14

+0

为什么不在单独的页面上备份此备份脚本?只要条件满足,就打电话开始/包含页面! – hjpotter92 2012-03-18 18:12:11

+1

@ChrisWiegman,** A **是“服务器上的外部文件或*到数据库*中”。如果在D/B中使用batchQ行/表,则不会出现此问题。只需更新time = requested_time的备份时间戳记行上的时间即可。如果此更新执行的受影响行数为1,那么此过程会执行备份,否则其他进程会将其剔除。 – TerryE 2012-03-18 18:43:29

2
  • 在代码的开头创建一个文件。
  • 代码运行完毕后删除文件。
  • 在代码的开头,确保该文件在运行之前不存在。

有点像Linux中的apt-get锁定。

+0

我已经尝试过了,但它在繁忙的网站上速度不够快。 – 2012-03-18 18:09:38

+0

这个脚本被请求的速度有多快? – 2012-03-18 18:17:29

0

我假设这个备份在某处做了备份。

因此,检查最新备份的元数据,如果创建时间不够远,请不要执行备份。

我认为这不是一个cron工作有一个很好的理由?

+0

是的,这不是一个cron工作,因为太多的人不能处理它。我必须在实际的cron作业不可用并且wp-cron不够灵活的环境中使用它。 – 2012-03-18 18:12:51

3

如果您的网站非常繁忙,并且基本的锁定机制无法正常工作(我个人无法想象,但是哦!),您可以尝试PHP会话的垃圾回收器的解决方案。

只需随机选择一个介于0和10之间的数字,如果数字为0,请执行备份。如果现在有10个用户几乎同时调用您的备份脚本,统计上只有一个用户会真正执行备份。

define("BACKUP_PROBABILITY", 10); 
if (mt_rand(0, BACKUP_PROBABILITY) == 0) 
    doBackup(); 

如果您的网站非常频繁地出现,您可以增加最大值(10)。

如果在这10次访问中没有得到0,则接下来的10个访问者将获得他们的机会。

您当然需要某种锁定机制,并且仍然有可能(尽管不可信)您最终将拥有多个甚至10个备份。

我发现这个关于互斥锁(锁)在PHP中的问题。可能有帮助:PHP mutual exclusion (mutex)