如何检查服务器是否正在执行PHP脚本?

问题描述:

我正在运行需要将数据写入缓存的cronjob。我想把这个cronjob放在我的私人文件夹中,但是,即使在CHMODding私人文件夹中的缓存文件夹之后,它也没有写入权限。这似乎是一些plesk功能。如何检查服务器是否正在执行PHP脚本?

因此,现在我已将cronjob放置在公用文件夹中。但是,我需要确保只有服务器才能执行脚本。在cronjob顶部的以下内容呢?

if ($_SERVER['SERVER_ADDR'] != $_SERVER['REMOTE_ADDR']) die(); 

这似乎工作。然而,它不是可以利用的,例如。用户可以操纵他的remote_addr到我的服务器?还是有更好的方法来检查这个?

另一个问题我有是,上面的代码返回2个警告,尽管它似乎工作:

PHP Notice: Undefined index: SERVER_ADDR in ... on line 2 
PHP Notice: Undefined index: REMOTE_ADDR in ... on line 2 

任何想法什么的的原因是什么?

通过控制台而不是Web服务器执行脚本。

这个cron看起来是这样的:

*/5 * * * * php -f /path/to/cron.php 

然后文件可以这样做:

cron.php: 
<?php 

if (array_key_exists('REMOTE_ADDR', $_SERVER)) 
    die("Can only be run from the command line!"); 

,这将保证它的唯一服务器上运行。

编辑回应评论

你不能得到一个公用文件夹的私人文件夹内,一般来说,如果你不能在网站根目录外添加新的目录,缓存目录会必须以另一种方式加以保护。

我打算假设你的所有文件都在web根目录下,即:/home/site/publichtml。用你的目录替换它。

创建一个新目录/home/site/publichtml/.cache。将以下内容添加为。htaccess文件:

Deny from all 

现在你的脚本应该能够从文件系统访问该文件夹,但它是通过Web服务器访问。

如果您可以在服务器上设置cron作业(通过web管理员或其他方式,听起来可以),如下所示:即使用php -f /home/site/publichtml/cron.php作为命令,并包括阵列检查键。

或者,你可以检查这样的:

if (!isset($_SERVER['argc'])) 
    die("Must be run from the command line!\n"); 

$_SERVER['argc']当脚本在命令行中执行时,才设置。

如果您可以将cron脚本保留在Web根目录之外,那很好。如果不是,那应该是安全的。

最后,摆脱E_NOTICES的,这增加了cron.php的顶部:

error_reporting(E_ALL^E_NOTICE); // Turn off notices 

error_reporting(0); // Hide all error reporting 
+0

不幸的是我无法访问控制台。这是一个共享的网络主机。 – Tom 2009-02-17 17:01:53

+0

如果您可以设置cron作业(通过管理面板),您仍然应该可以做到这一点,但是您可能会失去一些安全性(例如:需要将缓存目录移到web根目录中)。 – 2009-02-17 17:25:51

首先,我会将可执行PHP脚本保存在一个只能由特权用户执行的私有目录中 - 并在该用户的cron中安排它。执行脚本应该没有问题。

其次,您可以更改将缓存数据写入公共目录的位置。最好把它保存在一个非公开的目录中,但是如果你不知道如何去做,那么数据可以公开,那么它可能是好的。

最后,使用$ _SERVER ['SERVER_ADDR']和$ _SERVER ['REMOTE_ADDR']可能不是检查服务器是否正在运行脚本的最佳方法。首先,我相信在运行命令行PHP脚本时不会设置$ _SERVER ['REMOTE_ADDR']。这是从HTTP头获取的,因为没有,它将是空的。事实上,这就是为什么你会收到警告 - 这些都没有设置。 (编辑:查看PHP文档,可能不会为非浏览器脚本设置'SERVER_ADDR'变量)

+0

我将如何在共享虚拟主机上创建这样的目录? – Tom 2009-02-17 17:03:21

我想答案就藏在您的第一个答复乔恩。

所以,如果你只想要这个脚本通过cron访问,请检查会话超全局变量的存在:

if (is_array($_SESSION)) die(); 

而且,仅仅因为它很容易,创造一个.htaccess文件,做一个全部拒绝。

我错误地将$ _SESSION设置为$ _SERVER,这很糟糕。这符合您的需求。