Подтвердить что ты не робот

Относительный путь не работает в cron PHP скрипт

Если PHP script запущен как cron script, то часто включает ошибки, если используются относительные пути. Например, если у вас есть

require_once('foo.php');

файл foo.php будет найден при запуске в командной строке, но не при запуске cron script.

Типичным обходным решением для этого является первый chdir для рабочего каталога или использование абсолютных путей. Я хотел бы знать, однако, что отличается между cron и shell, что вызывает это поведение. Почему это происходит при использовании относительных путей в cron script?

4b9b3361

Ответ 1

Рабочий каталог script может быть другим при запуске из 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

Ответ 2

Измените рабочий каталог на текущий путь к файлу. Просто используйте

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

в текущем файле. Тогда вам не нужно будет изменять все относительные пути к абсолютным путям на каждой странице.

Ответ 3

Единственный шанс, что я получил "require_once" для работы с cron и apache в то же время, был

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

Ответ 4

Другая возможность заключается в том, что версия CLI использует другой файл php.ini. (По умолчанию он будет использовать php-cli.ini и вернуться к стандартным php.ini)

Кроме того, если вы используете файлы .htaccess для установки пути к библиотеке и т.д., это явно не будет работать через cli.

Ответ 5

Поскольку "текущий рабочий каталог" для заданий cron будет каталогом, в котором существует ваш файл crontab, поэтому любые относительные пути должны относиться к каталогу THAT.

Самый простой способ справиться с функцией 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".

Если вы вызываете dirname( __FILE__ ) в "your_php_file.php", вы получите "/home/user/public_html/your_directory", даже если активный script находится в "/home/user/public_html" (обратите внимание на отсутствие конечной косой черты).

Если вам нужен каталог INCLUDING файла, используйте: dirname( $_SERVER['PHP_SELF'] ), который вернет "/home/user/public_html" и будет таким же, как вызов dirname( __FILE__ ) в файле "index.php", поскольку относительные пути то же самое.

пример использования:

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

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

Ответ 6

В дополнение к принятому ответу выше вы также можете использовать:

chdir(__DIR__);

Ответ 7

При выполнении задания cron ваш PHP script, вероятно, работает в другом контексте, чем при запуске вручную из оболочки. Поэтому ваши относительные пути не указывают на правильный путь.

Ответ 8

DIR работает, хотя он не будет работать на моем локальном хосте, поскольку он имеет другой путь, чем мой сервер в реальном времени. Я использовал это, чтобы исправить это.

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