$_SERVER['DOCUMENT_ROOT']在通过cron运行的php脚本中无法工作

30

我使用 $_SERVER['DOCUMENT_ROOT']."/lib/sft_required.php"; 在 PHP 脚本中包含 'sft_required' 文件。当我在浏览器中运行此文件时,它可以正常工作,但是当我将其作为定时任务运行时,它无法工作。似乎当我们通过 cron 运行脚本时,文件没有被包含。

10个回答

75

你可以自己填写 $_SERVER['DOCUMENT_ROOT']。

$_SERVER['DOCUMENT_ROOT'] = dirname(__FILE__);

如果cron文件在文档根目录中

$_SERVER['DOCUMENT_ROOT'] = dirname(dirname(__FILE__));

如果cron文件在文档根目录的上层目录


7
这个答案应该被标记为已被采纳,因为它提供了一个实际的解决方案来回答问题。 - Paras Shah
2
在PHP7中,dirname(dirname(__FILE__))可以重写为dirname(__FILE__, 2) - Nick

29

假设您直接通过cron运行脚本(而不是通过由cron运行wget触发的HTTP请求访问的Web服务器),那么它当然不起作用。

没有服务器,因此未设置$_SERVER


12
实际上,$_SERVER 超全局变量已经被设置,但其中包含不同的值。 - Savas Vedova
2
“当然”?为什么服务器会“忘记”DOCUMENT_ROOT是什么?这并不明显(实际上,几年过去了我仍然不明白为什么DOC_ROOT是空的(REMOTE_ADDR等更明显) - Martijn
2
@Martijn — 服务器不会遗漏任何东西。PHP并不是由Web服务器运行的,而是由cron运行的。 - Quentin

7

$_SERVER在使用CLI解释器运行PHP脚本时不能包含任何正常值。要么将路径放入环境变量中,要么将其作为命令行参数传递给脚本。


4

我在这里回答了一个类似的问题。正如其他人所提到的,超全局变量 $_SERVER 在 CLI 环境下未定义。链接中提供了一种(目前为止)可靠的方法来获取 DOCUMENT_ROOT 的位置。希望它能够证明有用。


2

例子1:
/var/www/site.com/ - DOCUMENT_ROOT(网站根目录);
/var/www/site.com/cron/script.php - CRON PHP脚本(定时任务);

<?php
/** DOCUMENT_ROOT -> /var/www/site.com/ */
$_SERVER['DOCUMENT_ROOT'] = realpath(dirname(__FILE__).'/../');
?>

示例 2:
/var/www/site.com/ - 文档根目录;
/var/www/site.com/sub_dir/cron/script.php - CRON PHP脚本;

<?php
/** DOCUMENT_ROOT -> /var/www/site.com/ */
$_SERVER['DOCUMENT_ROOT'] = realpath(dirname(__FILE__).'/../../');
?>

2
define('DOCROOT', substr(str_replace(pathinfo(__FILE__, PATHINFO_BASENAME), '', __FILE__), 0, -1));

这将为您获取与cron作业的$_SERVER['DOCUMENT_ROOT']相同的数据。


1
这是我处理过的类似问题的解决方案。
在我的情况下,我运行一个定时任务,执行我的主题中的文件。(我不为corn加载WordPress,所以我无法访问像ABSPATH这样的东西。)
这样我就可以使用根目录中指向我的脚本的第一个子文件夹,而不是从脚本目录往回工作,来获取我的'根目录'。
这意味着我不必担心移动我的脚本,因为它总是在第一个子文件夹下的某个位置。

0

我也遇到了同样的问题。我在网上找到的解决方案不能与我的网络服务器计划任务一起使用,所以我需要找到另一种简单更改路径的方法。

这通常不是什么大问题,如果你只有1-2个cron文件(如果需要,可以轻松编辑文件路径),但我有20个cron文件,当我需要更改服务器或路径时,我必须更改所有这些文件,在它们上面更改文件路径...

所以我至少为自己找到了一个很好的解决方案:我在cron文件夹中创建了一个文件path.php,并且因为它与cron文件在同一个文件夹中,所以您可以在没有错误的情况下包含它。

path.php中,我有$path = '/server/root/path';

然后我将该path.php包含到我的cron文件中(我有大约20个cron文件)

现在我在我的cron文件中使用该$path,如下所示:

include 'path.php';
include $path.'/includes/db.php';

现在如果我需要更改路径,那么我只需打开path.php文件,进行更改,然后一切都能正常工作。

希望我能帮助到某些人,因为这些解决方案让我的生活变得更加轻松!虽然它还不完美,因为完美的情况是所有东西都可以自动工作,但对我来说,这比以前的系统要容易得多,所以我想分享我的经验,也许我能帮助到某些人 :)!


0

这个解决方案对我很有用:

$site_root_directory = substr( __DIR__, 0, strpos( __DIR__, "public_html" ) ).'public_html';

0
在我的情况下,这个问题是由于在正常网站操作期间$_SERVER['DOCUMENT_ROOT']路径带有尾随斜杠,在cron作业期间没有尾随斜杠所导致的。
我不确定是什么原因导致了这种情况,但作为一种解决方法,我将我的代码改为使用ABSPATH,因为它似乎返回了一个一致的值。
换句话说,我将这个改成了:
$private_folder = realpath($_SERVER['DOCUMENT_ROOT'] . "../private_html");

转换为:

$private_folder = realpath(ABSPATH . "../private_html");

还有其他几种解决该问题的方法,例如使用str_replacertrim


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接