简体   繁体   English

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

[英]Relative path not working in cron PHP script

If a PHP script is run as a cron script, the includes often fail if relative paths are used.如果 PHP 脚本作为 cron 脚本运行,则在使用相对路径时包含通常会失败。 For example, if you have例如,如果你有

require_once('foo.php');

the file foo.php will be found when run on the command line, but not when run from a cron script.在命令行上运行时会找到文件 foo.php,但在从 cron 脚本运行时不会找到。

A typical workaround for this is to first chdir to the working directory, or use absolute paths.一个典型的解决方法是首先 chdir 到工作目录,或者使用绝对路径。 I would like to know, however, what is different between cron and shell that causes this behavior.但是,我想知道导致这种行为的 cron 和 shell 之间有什么不同。 Why does it fail when using relative paths in a cron script?为什么在 cron 脚本中使用相对路径会失败?

Change the working directory to the running file path.将工作目录更改为运行文件路径。 Just use只需使用

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

in the running file.在运行文件中。 Then you won't need to change all the relative paths to absolute paths in every page.那么您就不需要将每个页面中的所有相对路径都更改为绝对路径。

The working directory of the script may be different when run from a cron.从 cron 运行时,脚本的工作目录可能不同。 Additionaly, there was some confusion about PHPs require() and include(), which caused confusion about the working directory really being the problem:此外,关于 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');

Because the "current working directory" for cron jobs will be the directory where your crontab file exists -- so any relative paths with be relative to THAT directory.因为 cron 作业的“当前工作目录”将是您的 crontab 文件所在的目录——因此任何相对路径都相对于该目录。

The simplest way to handle that is with dirname() function and PHP __FILE__ constant.最简单的处理方法是使用dirname()函数和 PHP __FILE__常量。 Otherwise, you will need to edit the file with new absolute paths whenever you move the file to a different directory or a server with a different file structure.否则,每当您将文件移动到不同目录或具有不同文件结构的服务器时,您都需要使用新的绝对路径编辑文件。

dirname( __FILE__ )

__FILE__ is a constant defined by PHP as the full path to the file from which it is called. __FILE__是一个常量,由 PHP 定义为调用它的文件的完整路径。 Even if the file is included, __FILE__ will ALWAYS refer to the full path of the file itself -- not the file doing the including.即使包含文件, __FILE__也将始终引用文件本身的完整路径——而不是执行包含的文件。

So dirname( __FILE__ ) returns the full directory path to the directory containing the file -- no matter where it is included from and basename( __FILE__ ) returns the file name itself.所以dirname( __FILE__ )返回包含文件的目录的完整目录路径——无论它包含在何处,而basename( __FILE__ )返回文件名本身。

example: Let's pretend "/home/user/public_html/index.php" includes "/home/user/public_html/your_directory/your_php_file.php".例如:假设“/home/user/public_html/index.php”包含“/home/user/public_html/your_directory/your_php_file.php”。

If you call dirname( __FILE__ ) in "your_php_file.php" you would get "/home/user/public_html/your_directory" returned even though the active script is in "/home/user/public_html" (note the absence of the trailing slash).如果您在“your_php_file.php”中调用dirname( __FILE__ ) ,即使活动脚本位于“/home/user/public_html”中,也会返回“/home/user/public_html/your_directory”(注意没有尾部斜杠)。

If you need the directory of the INCLUDING file use: dirname( $_SERVER['PHP_SELF'] ) which will return "/home/user/public_html" and is the same as calling dirname( __FILE__ ) in the "index.php" file since the relative paths are the same.如果您需要包含文件的目录,请使用: dirname( $_SERVER['PHP_SELF'] )它将返回“/home/user/public_html”并且与在“index.php”文件中调用dirname( __FILE__ )相同因为相对路径是一样的。

example usages:示例用法:

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

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

Another possibility is that the CLI version is using a different php.ini file.另一种可能性是 CLI 版本使用的是不同的 php.ini 文件。 (By default, it'll use php-cli.ini and fallback to the standard php.ini) (默认情况下,它将使用 php-cli.ini 并回退到标准的 php.ini)

Also, if you're using .htaccess files to set your library path, etc. this obviously won't work via the cli.此外,如果您使用 .htaccess 文件来设置库路径等,这显然无法通过 cli 工作。

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

chdir(__DIR__);

When executed trough a cron job your PHP script probably runs in different context than if you start it manually from the shell.当通过 cron 作业执行时,您的 PHP 脚本可能会在与您从 shell 手动启动不同的上下文中运行。 So your relative paths are not pointing to the right path.所以你的相对路径没有指向正确的路径。

The DIR works although it will not work on my localhost as it has a different path than my live site server.尽管 DIR 无法在我的本地主机上工作,但它可以工作,因为它的路径与我的实时站点服务器不同。 I used this to fix it.我用这个来修复它。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM