2009-12-28 26 views
40

Si una secuencia de comandos PHP se ejecuta como una secuencia de comandos cron, las opciones a menudo fallan si se utilizan rutas relativas. Por ejemplo, si usted tieneLa ruta relativa no funciona en la secuencia de comandos cron PHP

require_once('foo.php'); 

el archivo foo.php se encontrará cuando se ejecuta en la línea de comandos, pero no cuando se ejecuta desde un script cron.

Una solución típica para esto es dirigirse primero al directorio de trabajo, o usar rutas absolutas. Me gustaría saber, sin embargo, qué es diferente entre cron y shell que causa este comportamiento. ¿Por qué falla al usar rutas relativas en un script cron?

+0

Este es un gran recurso, así: http://stackoverflow.com/questions/2857712/enable-proper-relative-path-in-cron – Webnet

Respuesta

11

El directorio de trabajo del script puede ser diferente cuando se ejecuta desde un cron. Adicionalmente, hubo cierta confusión acerca de los PHP require() y include(), lo que causó confusión sobre el directorio de trabajo es realmente el problema:

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 
1

Cuando se ejecuta a través de un trabajo cron, su script PHP probablemente se ejecuta en un contexto diferente que si lo inicia manualmente desde el shell. Entonces tus caminos relativos no están apuntando al camino correcto.

+0

eso es correcto. De hecho, el directorio de trabajo del script es el directorio de trabajo del shell. Debe usar nombres de ruta absolutos. – mauris

+1

Los nombres de ruta absolutos son una pesadilla para gestionar mientras mueve archivos ... solo use 'dirname (__FILE__)' – aequalsb

3

Otra posibilidad es que la versión CLI esté usando un archivo php.ini diferente. (De manera predeterminada, usará php-cli.ini y se volverá a usar el php.ini estándar)

Además, si está utilizando archivos .htaccess para configurar la ruta de su biblioteca, etc. obviamente esto no funcionará a través del cli.

86

Cambiar el directorio de trabajo a la ruta del archivo en funcionamiento. Solo use

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

en el archivo ejecutando. Entonces no necesitará cambiar todas las rutas relativas a rutas absolutas en cada página.

+1

Esto me estaba volviendo loco. Esto lo solucionó perfectamente – Andy

+1

Esto debe marcarse como el correcto – axelbrz

+1

También puede usar 'chdir (__ DIR __);' que es un poco más conciso. – billynoah

7

La única oportunidad que tengo "require_once" para trabajar con cron y Apache, al mismo tiempo era

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

El DIR funciona a pesar de que no va a funcionar en mi localhost ya que tiene un camino diferente al de mi vida servidor del sitio Usé esto para arreglarlo.

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

sigue usando una declaración condicional que puede ser reemplazada por 'dirname (__FILE__)' – aequalsb

3

Debido a que el "directorio de trabajo actual" para los trabajos de cron será el directorio donde existe el archivo crontab - por lo que cualquier rutas relativas con estar en relación con ese directorio.

La forma más sencilla de manejarlo es con la función dirname() y la constante PHP __FILE__. De lo contrario, deberá editar el archivo con nuevas rutas absolutas cada vez que mueva el archivo a un directorio diferente o a un servidor con una estructura de archivos diferente.

dirname(__FILE__) 

__FILE__ es una constante definida por PHP como la ruta completa del archivo desde el que se llama. Incluso si el archivo está incluido, __FILE__ se referirá SIEMPRE a la ruta completa del archivo en sí, no al archivo que lo incluye.

Así que dirname(__FILE__) devuelve la ruta completa del directorio al directorio que contiene el archivo, sin importar de dónde se incluya y basename(__FILE__) devuelve el nombre del archivo.

ejemplo: Vamos a suponer "/home/user/public_html/index.php" incluye "/home/user/public_html/your_directory/your_php_file.php".

Si llama dirname(__FILE__) en "your_php_file.php" que se obtendría "/ home/usuario/public_html/your_directory" devolvió a pesar de que la secuencia de comandos activa está en "/ home/usuario/public_html" (nótese la ausencia del arrastre barra oblicua).

Si necesita el directorio de la utilización de archivos incluyendo: dirname($_SERVER['PHP_SELF']) que devolverá "/ home/usuario/public_html" y es lo mismo que llamar dirname(__FILE__) en el archivo "index.php", ya que las rutas relativas son las mismas.

ejemplo: usos

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

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

Además de la respuesta aceptada anteriormente, también se pueden utilizar:

chdir(__DIR__); 
+0

solo si se le permite ejecutar 'chdir()' en el entorno en el que se encuentra – aequalsb

+0

¿es así de común? Nunca he trabajado en ningún entorno donde esa función no estaba permitida. – billynoah

+0

lo he experimentado relacionado con PHP safe_mode. http://php.net/manual/en/features.safe-mode.functions.php, pero esto ha quedado en desuso http://php.net/manual/en/features.safe-mode.php. - Eso está en desuso, no se eliminó ... lo que significa que aún podría encontrarse. – aequalsb

Cuestiones relacionadas