wake-up-neo.net

Relativer Pfad funktioniert nicht in cron PHP Skript

Wenn ein PHP -Skript als Cron-Skript ausgeführt wird, schlagen die Includes häufig fehl, wenn relative Pfade verwendet werden. Zum Beispiel, wenn Sie haben

require_once('foo.php');

die Datei foo.php wird gefunden, wenn sie in der Kommandozeile ausgeführt wird, aber nicht, wenn sie von einem cron-Skript aus ausgeführt wird.

Eine typische Problemumgehung besteht darin, zuerst in das Arbeitsverzeichnis zu wechseln oder absolute Pfade zu verwenden. Ich würde jedoch gerne wissen, was sich zwischen cron und Shell unterscheidet, was dieses Verhalten verursacht. Warum schlägt es fehl, wenn relative Pfade in einem Cron-Skript verwendet werden?

46
Sjoerd

Das Arbeitsverzeichnis des Skripts kann unterschiedlich sein, wenn es von einem Cron aus ausgeführt wird. Darüber hinaus gab es einige Verwirrung über PHPs requir () und include (), was Verwirrung darüber verursachte, dass das Arbeitsverzeichnis wirklich das Problem ist:

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
12
Sjoerd

Ändern Sie das Arbeitsverzeichnis in den laufenden Dateipfad. Benutz einfach

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

in der laufenden Datei. Sie müssen dann nicht auf jeder Seite alle relativen Pfade in absolute Pfade ändern.

95

Die einzige Chance, dass ich "demand_once" bekam, um gleichzeitig mit cron und Apache zu arbeiten, war

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

Da das "aktuelle Arbeitsverzeichnis" für cron-Jobs das Verzeichnis ist, in dem sich Ihre Crontab-Datei befindet, sind relative Pfade relativ zu diesem Verzeichnis.

Der einfachste Weg, dies zu handhaben, ist mit der Funktion dirname() und der Konstante PHP __FILE__. Andernfalls müssen Sie die Datei mit neuen absoluten Pfaden bearbeiten, wenn Sie die Datei in ein anderes Verzeichnis oder einen Server mit einer anderen Dateistruktur verschieben.

dirname( __FILE__ )

__FILE__ ist eine Konstante, die von PHP als vollständiger Pfad zu der Datei definiert wird, aus der sie aufgerufen wird. Selbst wenn die Datei enthalten ist, verweist __FILE__ IMMER auf den vollständigen Pfad der Datei selbst - nicht auf die Datei, die das Einschließen ausführt.

dirname( __FILE__ ) gibt also den vollständigen Verzeichnispfad an das Verzeichnis zurück, in dem sich die Datei befindet - unabhängig davon, wo sie enthalten ist, und basename( __FILE__ ) gibt den Dateinamen selbst zurück.

beispiel: Nehmen wir an, "/home/user/public_html/index.php" beinhaltet "/home/user/public_html/your_directory/your_php_file.php".

Wenn Sie dirname( __FILE__ ) in "your_php_file.php" aufrufen, wird "/ home/user/public_html/your_directory" zurückgegeben, obwohl sich das aktive Skript in "/ home/user/public_html" befindet (beachten Sie das Fehlen des nachstehenden Schrägstrichs).

Wenn Sie das Verzeichnis der INCLUDING-Datei benötigen, verwenden Sie: dirname( $_SERVER['PHP_SELF'] ), das "/ home/user/public_html" zurückgibt und mit dem Aufruf von dirname( __FILE__ ) in der Datei "index.php" identisch ist, da die relativen Pfade gleich sind.

beispielverwendungen:

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

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

Eine andere Möglichkeit ist, dass die CLI-Version eine andere php.ini-Datei verwendet. (Standardmäßig wird php-cli.ini verwendet und auf die Standard php.ini zurückgegriffen.)

Wenn Sie beispielsweise .htaccess-Dateien verwenden, um Ihren Bibliothekspfad usw. festzulegen, funktioniert dies offensichtlich nicht über cli.

3
John Parker

Zusätzlich zu der akzeptierten Antwort können Sie auch Folgendes verwenden:

chdir(__DIR__);
2
billynoah

Bei Ausführung durch einen cron-Job wird Ihr PHP -Skript wahrscheinlich in einem anderen Kontext ausgeführt, als wenn Sie es manuell von der Shell aus starten. Ihre relativen Pfade zeigen also nicht auf den richtigen Pfad.

1
Jan Hančič

Das DIR funktioniert, obwohl es auf meinem localhost nicht funktioniert, da es einen anderen Pfad hat als mein Live-Site-Server. Ich habe das verwendet, um das Problem zu beheben.

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