代码之家  ›  专栏  ›  技术社区  ›  dzm

在现场仅执行一次php脚本

php
  •  1
  • dzm  · 技术社区  · 14 年前

    我有一个脚本可以实时执行更新功能。我会把它移到cron作业中,但是由于一些限制,我更希望在页面加载时实时调用它。

    问题是,当流量很大时,它不太起作用,因为它使用了一些随机和加权的数字,所以如果它达到了很多次,结果就不是我们想要的。

    所以,问题是。有没有办法知道某个脚本被访问了多少次?一次只限一次?

    谢谢您!

    3 回复  |  直到 14 年前
        1
  •  3
  •   Brad Westness    14 年前

    您可以这样做(需要PHP 5):

    if(file_get_contents("lock.txt") == "unlocked"){
      // no lock present, so place one
      file_put_contents("lock.txt", "locked");
    
      // do your processing
      ...
    
      // remove the lock
      file_put_contents("lock.txt", "unlocked", LOCK_EX);
    }
    

    file_put_contents()

    显然,正如@Pekka在他的回答中提到的,如果在放置锁和删除锁之间发生致命错误(或PHP崩溃,或服务器崩溃等),这可能会导致问题,因为文件将保持锁定状态。

        2
  •  5
  •   Community CDub    8 年前

    您正在寻找的技术称为锁定。

    最简单的方法是创建一个临时文件,并在操作完成后将其删除。其他进程将查找该临时文件,查看它是否已存在并消失。

    但是,您还需要考虑锁的所有者进程崩溃以及未能移除锁的可能性。这就是这个简单的任务似乎变得复杂的地方。

    基于文件的锁定解决方案

    PHP有一个内置的 flock() 函数,该函数承诺提供一个独立于操作系统的基于文件的锁定功能。 This question 对如何使用它有一些实用的提示。但是,手册页警告说,在某些情况下, 弗洛克() 多个PHP脚本实例试图同时获取锁时出现问题。 This question 在这个问题上似乎有更高级的答案,但它们都不是很容易实现的。

    基于数据库的锁定

    this question -可能被周围的复杂情况吓跑了 -要求其他非基于文件的锁定技术,并提出了MySQL的 GET_LOCK() . 我从未使用过它,但它看起来非常简单——如果你无论如何使用mySQL,它可能值得一试。

    该死,这个问题是 复杂的

        3
  •  1
  •   naugtur    14 年前

    使用sql查询启动脚本,该查询测试数据库中的timestamp字段是否在1天前。 如果是-写入当前时间戳并执行脚本。

    伪sql来展示这个想法:

    UPDATE runs SET lastrun=NOW() WHERE lastrun<NOW()-1DAY
    

    (不同的sql服务器需要对上述内容进行不同的更改)

    不要使用两个查询-SELECT和UPDATE,因为它不再是原子的了。

    推荐文章