不使用CRON安排脚本

时间:2010-01-27 00:31:12

标签: php scripting cron command-line-interface

我知道有很多关于使用CRON运行php文件的帖子。但是,在共享托管的世界中,以及为用户设置的简便性,我不想惹这个。

我在网上发现了另一个与套接字有关的解决方案。只是想让每个人都接受这个,并告诉我这是一个好主意还是坏主意。听起来效果很好。

思想?

//Open socket connection to cron.php
$socketcon = fsockopen($_SERVER['HTTP_HOST'],80,$errorno,$errorstr,10);
if($socketcon) {
$socketdata = "GET /cron.php HTTP 1.1\r\nHost: ".$_SERVER['HTTP_HOST']."\r\nConnection: Close\r\n\r\n";
fwrite($socketcon,$socketdata);
//Normally you would get all the data back with fgets and wait until $socketcon reaches feof.
//In this case, we just do this:
fclose($socketcon);
} else {
//something went wrong. Put your error handler here.
}

cron.php:

//This script does all the work.
sleep(200);
//To prove that this works we will create an empty file here, after the sleep is done.
//Make sure that the webserver can write in the directory you're testing this file in.
$handle = fopen('test.txt','w');
fclose($handle);

从博文中找到该脚本:http://syn.ac/tech/13/creating-php-cronjobs-without-cron-and-php-cli/

7 个答案:

答案 0 :(得分:4)

这不是一个糟糕的方法,但你需要确保通过关闭套接字不仅仅是在脚本完成之前终止它。您可以将套接字设置为非阻塞。

我仍然会使用cron工作,即使它有点痛苦。

答案 1 :(得分:4)

一个cron工作基本上是一个cron工作。你设置它,操作系统为你运行工作。我不确定你从网站获得的PHP脚本是如何工作的,但是如果它需要人工干预,那么它并不真正称为cron作业。如果您不想使用cron,可以使用循环,然后使用PHP的日期函数来设置日期和时间。伪代码

while (1) {
    $d=date("d");
    if ( $d == "01" ){
        //run every 1st of month
        //code to run here
    }
}

答案 2 :(得分:2)

这会产生与cron不同的效果。

cron作业在您提前设定的某些时间运行。

您的方法基本上是对PHP脚本的一种“分叉”或“异步调用”。像你在这里通过HTTP这样做是一种便宜又简单的技术。我自己用它。它与cron的不同之处在于它立即启动了“后台进程”。

但是有一些评论:

  1. 首先,您应该在“后台”脚本中调用ignore_user_abort()。否则,在许多环境中,当“调用”脚本关闭套接字时,您的脚本将被中止。

  2. 其次,您可以实际检查“后台”脚本中的$_SERVER['HOST']变量,这样您就可以拥有未向互联网公开的脚本(基本上向{{1}发出请求并在后台脚本中检查它)。然后,您可以信任来自您自己的计算机的请求,并跳过所有安全检查,会话等。

  3. 第三,谁说“背景”脚本必须用PHP运行?如果你打算将它用作“后台”进程,那么PHP有许多缺点。主要的缺点是它阻塞了I / O.因此,如果您要发送电子邮件,更新数据库行或其他任何内容,则每次发送请求时基本上都会暂停脚本。例如,对于Node.js,您可以异步启动I / O命令并继续运行。如果你打算使用PHP,至少要确保一次发送10封电子邮件,或者一次更新10行,或者其他东西。

  4. 最后,如果后台脚本正在执行某些操作,您可能希望在浏览器上显示进度条。因此,您将需要使用公共数据存储(如数据库)来记录任务的进度。

答案 3 :(得分:1)

这是一个功能性但奇怪的解决方案,可确保您需要在运行第一个脚本的同时连接机器。如果你想要,我建议你使用wget或curl的shell脚本来实现这个目的。

例如:

#!/bin/sh

curl -O http://www.myserver.com/cron.php 2>&1 > /var/log/remote.cron.log

但我认为如果你不必同步运行你想要实现的解决方案是检查index.php的最后一次,以查看它最后一次运行脚本,如果它超过两个小时之前,然后是include('cron.php')。您还可以存储在环境变量中运行脚本的时间戳,以避免性能损失。

答案 4 :(得分:1)

据我所知,通过阅读该博客帖子并查看代码,这并不是一种无法获得cron访问权限的方法,这是一种避免某人等待服务器对长查询做出响应的方法。如果你绝对必须每10分钟左右执行某个脚本,那么你需要使用cron。如果您只是想避免让用户等待长查询完成,那么这个hack可能会起作用。即使使用这种方法,如果你的脚本花费的时间超过PHP允许的时间,我仍然认为你会达到时间限制。

回顾wp-cron.php(在博客链接中提到),看起来它完全依赖于访问该站点的用户触发对带时间戳的作业集的检查。

除非您以特定间隔ping另一台服务器,否则这些技术不会非常可靠。该技术的主要目标是避免用户等待15秒钟清理或维护脚本每隔一段时间运行一次,而不是真正替代cron的所有用途。

答案 5 :(得分:0)

如果我理解得很清楚,你会从远程计算机上运行第一个脚本,对你的cron禁用主机上托管的第二个脚本进行点击?那么,感谢php / webserver交互的错误或奇怪的功能,当你立即关闭连接时,脚本不会超时?

第一部分是相当普遍的做法,甚至有公司提供这种服务(例如http://www.webcron.org/index.php?lang=english会在您要求的任何时候自动戳出您想要的任何脚本,但需要付费)。

第二部分对我来说不了解。这似乎是php / webserver与我交互的一个错误,但我可能错了。无论如何,我会仔细检查它是否是一个错误(等等,这就是你现在正在做的事情吗?)如果它被证明是合法的行为,那就去吧。如果它似乎是一个错误,那么不要依赖它,因为它可以随时修复

答案 6 :(得分:0)

我花了几天的时间才找到一个没有竞争条件和/或充斥我自己的服务器的工作解决方案,但最后我认为这应该有效:
http://www.programmierer-forum.de/phpcron-cronjobs-ohne-crontab-t348377.htm