相对路径在 cron PHP 脚本中不起作用

Posted

技术标签:

【中文标题】相对路径在 cron PHP 脚本中不起作用【英文标题】:Relative path not working in cron PHP script 【发布时间】:2010-12-30 11:23:35 【问题描述】:

如果 php 脚本作为 cron 脚本运行,如果使用相对路径,则包含通常会失败。例如,如果您有

require_once('foo.php');

文件 foo.php 在命令行运行时会被找到,但从 ​​cron 脚本运行时不会。

一个典型的解决方法是首先 chdir 到工作目录,或者使用绝对路径。但是,我想知道导致这种行为的 cron 和 shell 之间有什么不同。为什么在 cron 脚本中使用相对路径会失败?

【问题讨论】:

这也是一个很好的资源:@​​987654321@ 不要仅仅为了让它们在 cron 作业中工作而更改您的 PHP 文件,而是更改 cron 作业行上的当前目录。检查我的答案here。 【参考方案1】:

将工作目录更改为运行文件路径。只需使用

chdir(dirname(__FILE__));
include_once '../your_file_name.php'; //we can use relative path after changing directory

在运行文件中。这样您就不需要在每个页面中将所有相对路径更改为绝对路径。

【讨论】:

这把我逼疯了。这样就完美解决了 你也可以使用chdir(__DIR__);,更简洁一些。 这仅在您可以在您的环境中执行chdir() 时才有效。 include/require dirname( __FILE__ ) 更可靠。 我不喜欢更改PHP代码,而是在cron选项卡中更改目录,检查my answer【参考方案2】:

从 cron 运行时,脚本的工作目录可能不同。另外,关于 PHP 的 require() 和 include() 存在一些混淆,这导致混淆了工作目录确实是问题所在:

include('foo.php') // searches for foo.php in the same directory as the current script
include('./foo.php') // searches for foo.php in the current working directory
include('foo/bar.php') // searches for foo/bar.php, relative to the directory of the current script
include('../bar.php') // searches for bar.php, in the parent directory of the current working directory

【讨论】:

【参考方案3】:

我获得“require_once”同时使用 cron 和 apache 的唯一机会是

require_once(dirname(__FILE__) . '/../setup.php');

【讨论】:

【参考方案4】:

因为 cron 作业的“当前工作目录”将是您的 crontab 文件所在的目录 - 所以任何相对路径都与该目录相关。

最简单的处理方法是使用 dirname() 函数和 PHP __FILE__ 常量。否则,每当您将文件移动到不同的目录或具有不同文件结构的服务器时,都需要使用新的绝对路径编辑文件。

dirname( __FILE__ )

__FILE__ 是一个常量,由 PHP 定义为调用它的文件的完整路径。即使包含该文件,__FILE__ 也将始终引用文件本身的完整路径——而不是执行包含的文件。

所以dirname( __FILE__ ) 返回包含该文件的目录的完整目录路径——无论它是从哪里包含的,basename( __FILE__ ) 返回文件名本身。

示例: 让我们假设“/home/user/public_html/index.php”包含“/home/user/public_html/your_directory/your_php_file.php”。

如果您在“your_php_file.php”中调用dirname( __FILE__ ),即使活动脚本位于“/home/user/public_html”中,也会返回“/home/user/public_html/your_directory”(注意没有斜杠)。

如果您需要包含文件的目录,请使用:dirname( $_SERVER['PHP_SELF'] ),它将返回“/home/user/public_html”,并且与在“index.php”文件中调用dirname( __FILE__ ) 相同,因为相对路径是一样的。

示例用法:

@include dirname( __FILE__ ) . '/your_include_directory/your_include_file.php';

@require dirname( __FILE__ ) . '/../your_include_directory/your_include_file.php';

【讨论】:

【参考方案5】:

另一种可能是 CLI 版本使用了不同的 php.ini 文件。 (默认情况下,它将使用 php-cli.ini 并回退到标准 php.ini)

另外,如果您使用 .htaccess 文件来设置库路径等,这显然无法通过 cli 工作。

【讨论】:

【参考方案6】:

除了上面接受的答案,你还可以使用:

chdir(__DIR__);

【讨论】:

只有当你被允许在你所在的环境中执行chdir() 这很常见吗?我从未在不允许该功能的任何环境中工作过。 我经历过与 PHP safe_mode 相关的事情。 php.net/manual/en/features.safe-mode.functions.php,但这已被弃用 php.net/manual/en/features.safe-mode.php。 -- 不推荐使用,没有删除...意思是,它仍然可以遇到。【参考方案7】:

当通过 cron 作业执行时,您的 PHP 脚本可能在不同于从 shell 手动启动它的上下文中运行。所以你的相对路径没有指向正确的路径。

【讨论】:

没错。其实脚本的工作目录就是shell的工作目录。应该使用绝对路径名。 绝对路径名是您在移动文件时管理的噩梦......只需使用dirname( __FILE__ )【参考方案8】:

虽然 DIR 无法在我的 localhost 上工作,但它可以工作,因为它的路径与我的实时站点服务器不同。我用它来修复它。

    if(__DIR__ != '/home/absolute/path/to/current/directory') // path for your live server
        require_once '/relative/path/to/file';
    else
        require_once '/absolute/path/to/file';
    

【讨论】:

仍在使用可以替换为dirname( __FILE__ )的条件语句

以上是关于相对路径在 cron PHP 脚本中不起作用的主要内容,如果未能解决你的问题,请参考以下文章

Linux:gsutil 在 cron 中不起作用

PHP:要求路径不适用于 cron 作业?

Bash + Expect脚本在cron RHEL 7中不起作用

require_once 不起作用(相对路径)

打字稿路径在 Express 项目中不起作用

@reboot 在 CRON 中不起作用