相对path不能在cron PHP脚本中工作

如果PHP脚本作为cron脚本运行,则使用相对path时,包含通常会失败。 例如,如果你有

require_once('foo.php'); 

在命令行上运行时会findfoo.php文件,但是在从cron脚本运行时不会运行。

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

将工作目录更改为正在运行的文件path。 只是使用

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

在运行的文件中。 那么你不需要在每个页面中改变所有相对path到绝对path。

从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 

我得到“require_once”与cron和apache同时工作的唯一机会是

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

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

另外,如果你使用.htaccess文件来设置你的库path,这显然不会通过cli工作。

因为cron作业的“当前工作目录”将是你的crontab文件所在的目录 – 所以任何相对path都与THAT目录有关。

最简单的方法是使用dirname()函数和PHP __FILE__常量。 否则,无论何时将文件移动到其他目录或具有不同文件结构的服务器,都需要使用新的绝对path来编辑该文件。

 dirname( __FILE__ ) 

__FILE__是由PHP定义的一个常量,作为从中调用的文件的完整path。 即使包含文件, __FILE__也会始终引用文件本身的完整path – 而不是包含文件。

所以dirname( __FILE__ )返回包含文件的目录的完整目录path – 无论它包含在哪里, 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”(注意不存在斜线)。

如果你需要INCLUDING文件的目录,使用: dirname( $_SERVER['PHP_SELF'] ) ,它将返回“/ home / user / public_html”,和在“index.php”文件中调用dirname( __FILE__ )相同因为相对path是相同的。

示例用法:

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

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

 chdir(__DIR__); 

当通过cron作业执行时,您的PHP脚本可能运行在不同的环境中,而不是从shell手动启动它。 所以你的相对path不是指向正确的道路。

DIR工作,虽然它不会在我的本地主机,因为它有一个不同的path比我的现场服务器。 我用这个来修复它。

  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'; }