相对路径在 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 脚本中不起作用的主要内容,如果未能解决你的问题,请参考以下文章