15

我知道有很多关于使用 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/

4

7 回答 7

4

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

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

于 2010-01-27T00:41:32.267 回答
4

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

while (1) {
    $d=date("d");
    if ( $d == "01" ){
        //run every 1st of month
        //code to run here
    }
}
于 2010-01-27T00:42:48.293 回答
2

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

cron 作业在您提前设置的特定时间运行。

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

不过有几点评论:

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

  2. 其次,您实际上可以$_SERVER['HOST']在“后台”脚本中检查变量,这样您就可以拥有不暴露在互联网上的脚本(基本上localhost是向后台脚本发出请求并检查它)。然后,您大概可以信任来自您自己机器的请求,并跳过所有安全检查、会话等。

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

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

于 2010-11-20T22:47:15.020 回答
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'). 您还可以将脚本运行时间的时间戳存储在环境变量中,以避免性能损失。

于 2010-01-27T00:46:33.467 回答
1

据我从阅读该博客文章和查看代码中了解到,这并不是没有 cron 访问权限的真正方法,这是一种避免有人等待服务器响应长查询的方法。如果您绝对必须每隔 10 分钟左右执行一次某个脚本,那么您将需要使用 cron 。如果您只是想避免让用户等待很长的查询完成,那么这个 hack 可能会起作用。即使使用这种方法,我仍然认为如果您的脚本花费的时间超过 PHP 允许完成的时间,您将达到时间限制。

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

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

于 2010-01-27T01:53:57.107 回答
0

如果我理解得很好,您会从远程机器上运行第一个脚本,然后点击将托管在您的 cron 禁用主机上的第二个脚本?然后,当您立即关闭连接时,由于 php/webserver 交互的错误或奇怪特性,脚本不会超时?

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

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

于 2010-01-27T00:45:23.787 回答
0

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

于 2015-02-12T09:33:51.427 回答