web-dev-qa-db-fra.com

Le chemin relatif ne fonctionne pas dans cron PHP scénario

Si un script PHP est exécuté en tant que script cron, les inclusions échouent souvent si des chemins d'accès relatifs sont utilisés. Par exemple, si vous avez

require_once('foo.php');

le fichier foo.php sera trouvé lorsqu'il sera exécuté sur la ligne de commande, mais pas à partir d'un script cron.

Une solution de contournement typique consiste à se connecter d’abord au répertoire de travail ou à utiliser des chemins absolus. J'aimerais toutefois savoir ce qui différencie cron et Shell de ce comportement. Pourquoi cela échoue-t-il lors de l'utilisation de chemins relatifs dans un script cron?

46
Sjoerd

Le répertoire de travail du script peut être différent lorsqu'il est exécuté à partir d'un cron. De plus, il y a eu une certaine confusion à propos des PHP require () et include (), ce qui a entraîné une confusion quant au problème réel du répertoire de travail:

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

Remplacez le répertoire de travail par le chemin du fichier en cours. Juste utiliser

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

dans le fichier courant. Vous n'aurez alors pas besoin de changer tous les chemins relatifs en chemins absolus dans chaque page.

95
Withfriendship Hiox

La seule chance que j'ai "require_once" pour travailler avec cron et Apache en même temps

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

Parce que le "répertoire de travail en cours" pour les tâches cron sera le répertoire dans lequel se trouve votre fichier crontab - ainsi, tous les chemins relatifs avec seront relatifs au répertoire THAT.

La méthode la plus simple consiste à utiliser la fonction dirname() et la constante PHP __FILE__. Sinon, vous devrez éditer le fichier avec de nouveaux chemins absolus chaque fois que vous déplacerez le fichier dans un autre répertoire ou un serveur avec une structure de fichier différente.

dirname( __FILE__ )

__FILE__ est une constante définie par PHP en tant que chemin d'accès complet au fichier à partir duquel il est appelé. Même si le fichier est inclus, __FILE__ fera TOUJOURS référence au chemin complet du fichier lui-même, et non au fichier faisant l'inclusion.

Donc, dirname( __FILE__ ) renvoie le chemin d'accès complet au répertoire contenant le fichier, quel que soit son origine et basename( __FILE__ ) renvoie le nom du fichier lui-même.

exemple: Supposons que "/home/user/public_html/index.php" inclut "/home/user/public_html/votre_répertoire/votre_php_fichier.php".

Si vous appelez dirname( __FILE__ ) dans "your_php_file.php", vous obtiendrez "/ home/user/public_html/your_directory", même si le script actif est dans "/ home/user/public_html" (notez l'absence de la barre oblique finale).

Si vous avez besoin du répertoire du fichier INCLUDING, utilisez: dirname( $_SERVER['PHP_SELF'] ) qui retournera "/ home/user/public_html" et correspond à l’appel de dirname( __FILE__ ) dans le fichier "index.php" car les chemins relatifs sont identiques.

exemples d'usages:

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

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

Une autre possibilité est que la version de la CLI utilise un fichier php.ini différent. (Par défaut, il utilisera php-cli.ini et se repliera sur le php.ini standard)

De plus, si vous utilisez des fichiers .htaccess pour définir votre chemin de bibliothèque, etc., cela ne fonctionnera évidemment pas via le cli.

3
John Parker

Outre la réponse acceptée ci-dessus, vous pouvez également utiliser:

chdir(__DIR__);
2
billynoah

Lorsqu'il est exécuté via un travail cron, votre script PHP s'exécute probablement dans un contexte différent de celui que vous lancez manuellement à partir du shell. Donc, vos chemins relatifs ne pointent pas vers le bon chemin.

1
Jan Hančič

Le répertoire DIR fonctionne bien que cela ne fonctionnera pas sur mon hôte local car il a un chemin différent de celui de mon serveur de site actif. J'ai utilisé ceci pour le réparer.

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