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

相对路径在cron PHP脚本中不起作用,php,cron,Php,Cron,如果PHP脚本作为cron脚本运行,那么如果使用相对路径,则include通常会失败。例如,如果你有 require_once('foo.php'); 文件foo.php在命令行上运行时会找到,但在从cron脚本运行时不会找到 一个典型的解决方法是首先chdir到工作目录,或者使用绝对路径。然而,我想知道cron和shell之间有什么不同导致了这种行为。为什么在cron脚本中使用相对路径时失败?当通过cron作业执行时,您的PHP脚本可能在不同的上下文中运行,而不是从shell手动启动。因此,

如果PHP脚本作为cron脚本运行,那么如果使用相对路径,则include通常会失败。例如,如果你有

require_once('foo.php');
文件foo.php在命令行上运行时会找到,但在从cron脚本运行时不会找到


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

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

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


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

从cron运行脚本时,脚本的工作目录可能不同。此外,PHPs 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

将工作目录更改为正在运行的文件路径。只用

chdir(dirname(__FILE__));
include_once '../your_file_name.php'; //we can use relative path after changing directory
在运行文件中。这样,您就不需要将每个页面中的所有相对路径都更改为绝对路径。

同时使用cron和apache的唯一机会是

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

DIR可以工作,但它不会在本地主机上工作,因为它的路径与我的live site server不同。我用这个来修好它

    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';
    }
因为cron作业的“当前工作目录”将是crontab文件所在的目录,所以任何具有的相对路径都将是相对于该目录的

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

dirname( __FILE__ )
\uuuuu FILE\uuuu
是一个常量,由PHP定义为调用它的文件的完整路径。即使包含了该文件,
\uuuuuuuuuuuuuuuuuuu
也将始终引用该文件本身的完整路径,而不是执行包含操作的文件

因此
dirname(\uuuuu FILE\uuuuu)
返回包含该文件的目录的完整目录路径——无论它从何处包含,并且
basename(\uuuu FILE\uuuuu)
返回文件名本身

例如: 让我们假设“/home/user/public_html/index.php”包括“/home/user/public_html/your_directory/your_php_file.php”

如果在“your\u php\u FILE.php”中调用
dirname(\uuuu FILE\uuuu)
,即使活动脚本位于“/home/user/public\u html”中,也会返回“/home/user/public\u html/your\u目录”(注意,后面没有斜杠)

如果需要包含文件的目录,请使用:
dirname($\u SERVER['PHP\u SELF'])
,它将返回“/home/user/public\u html”,并且与在“index.PHP”文件中调用
dirname(\uu file\uu)
相同,因为相对路径相同

示例用法:

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

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

除上述公认答案外,您还可以使用:

chdir(__DIR__);

这是正确的。事实上,脚本的工作目录就是shell的工作目录。应该使用绝对路径名。在移动文件时,绝对路径名是一个难以管理的噩梦。。。只需使用
dirname(\uuuu FILE\uuuu)
这也是一个很好的资源:不要仅仅为了让PHP文件在cron作业中工作而更改它们,而是更改cron作业行上的当前目录。检查我的答案。这让我发疯。这很好地解决了问题,您还可以使用
chdir(\uuuu DIR\uuuu)更为简洁。只有在您的环境中执行
chdir()
时,这才有效
include/require dirname(\uuuu FILE\uuu)
更可靠。我不想更改PHP代码,而是更改cron选项卡上的目录,仍然使用条件语句进行检查,只有在允许执行
chdir()时,才可以用
dirname(\uu FILE\uuu)
替换
在您所处的环境中,这有多普遍?我从未在任何不允许使用该函数的环境中工作过。我体验过与PHP安全模式相关的工作,但这一点遭到了反对已弃用但未删除的。。。也就是说,它仍然可能被遇到。