2011-03-01 21 views
12

Como parte del registro de la aplicación, intento abrir un archivo local y, si ese archivo aún no existe, crear el nuevo. Aquí es lo que tengo:PHP fopen() no crea el archivo si no existe

$path = '/home/www/phpapp/logs/myawesome_logfile.txt'; 
$f = (file_exists($path))? fopen($path, "a+") : fopen($path, "w+"); 
fwrite($f, $msg); 
fclose($f); 
chmod($path, 0777); 

He comprobado doble, y el directorio /logs es chmod 0777, e incluso fui el paso adicional de chown'ing a Apache: Apache para una buena medida. Aún así, cuando el script va a abrir el archivo, me da la advertencia de que el archivo no existe y sale disparado. No se crea ningún archivo.

¿Debo eliminar la advertencia fopen() para que cree el archivo?

+0

Nota: Agregué la lógica con 'file_exists()' en caso de que 'a +' me pusiera al día por cualquier razón. –

+2

¿Realmente quiere que su camino comience desde la raíz? Ese no será el directorio raíz de su aplicación, será el directorio raíz de su sistema. –

+0

¿Por qué crees que la supresión de errores te ayudará a abrir un archivo? –

Respuesta

16

Cuando trabaje con rutas en PHP, el contexto puede importar mucho. Si está trabajando con urls en un contexto de redirección, entonces el directorio raíz ('/') se refiere a la raíz de su dominio. Lo mismo ocurre con las rutas para vincular archivos o imágenes y para incluir y requerir directivas.

Sin embargo, cuando se trata de comandos del sistema de archivos como fopen, el directorio raíz ('/') es la raíz del sistema. No es la raíz de tu dominio.

Para solucionar esto, intente dar la ruta completa al archivo de registro que desea abrir desde la raíz del sistema. Por ejemplo: /var/www/phpapplication/logs/myLogFile.txt

O puede usar $_SERVER['DOCUMENT_ROOT'] como se sugiere en otras respuestas para acceder al valor almacenado de su servidor para la ruta a la raíz del documento. La parte /var/www.

Editado para aclarar.

+0

"Cuando se trata de comandos de manejo de archivos como fopen(), php funciona desde el directorio raíz, no desde el directorio raíz de la aplicación". er ... no, cuando pones un '/' al comienzo de la ruta se inicia desde el directorio raíz. si pone '' phpapp/logs/myawesome_logfile.txt'' lo verificará desde el directorio de trabajo, lo que también es incorrecto a juzgar por el contexto. – Powerlord

+0

Hay ciertos momentos en los que al colocar un/delante se lo dirigirá al directorio raíz del dominio, como con la redirección de url. El contexto determina si hablamos de directorio raíz o dominio raíz. Sin embargo, es fácil confundirlos, ya que los caminos son similares. –

+0

Está recibiendo la ruta completa. (Eliminé el/home/www/parte de la ruta en mi publicación para abreviar). –

15

¿Has probado esto?

$msg = "I'm a line that is a message.\n"; 
$path = $_SERVER['DOCUMENT_ROOT'] . '/logs/myawesome_logfile.txt'; 
$f = fopen($path, "a+"); 
fwrite($f, $msg); 
fclose($f); 
chmod($path, 0777); 

El servidor que está trabajando que podría haber encarcelado para trabajar solamente en el directorio del phpapp y sus subdirectorios.

+0

+1: DOCUMENT_ROOT es casi seguro que es la solución necesaria aquí. – Powerlord

1

Siempre puede abrir su archivo con solo "a", también creará un nuevo archivo.
No es necesario que realice una condición.

Sin embargo, el problema principal con su código es entender la diferencia entre el sistema de archivos físico y el servidor web virtual, que ya se han explicado perfectamente.

Tenga en cuenta que debe proporcionar su pregunta con la copia exacta del mensaje de error. Contiene una tonelada de información extremadamente útil, no es como un juramento "No crearé tu archivo, ¡vete!" pero es a través de la explicación de qué y por qué está yendo mal. Si no le interesa esa información útil, debe proporcionársela a quienes lo soliciten.

+0

No hay servidores virtuales involucrados, y la secuencia de comandos obtiene la ruta completa al archivo. No tengo el error a mano, pero lo publicaré cuando pueda obtenerlo. –

+0

@b. mi. hollenbeck, un mensaje de error se vuelve aún más importante. –

0

La ruta del archivo debe estar en la raíz del servidor. Pude lograr esto usando el método phpinfo() dentro del documento que quería saber. Entonces, cuando use phpinfo(), verá un documento de información. Si encuentra para _SERVER ["SCRIPT_FILENAME"], verá la ruta absoluta de su archivo.

Espero que esto ayude a alguien.

0

No olvides asegurarte de que SELinux no te está bloqueando.

[root @ yourbox] # audit2allow < /var/log/audit/audit.log
# ============= ========= httpd_t =====
# !!!! Esta avc se puede permitir mediante el booleano 'httpd_unified' que permite httpd_t httpd_sys_content_t: dir {write add_name};
# !!!! Esta avc se puede permitir mediante el booleano 'httpd_unified' que permite httpd_t httpd_sys_content_t: archivo {write create}; [root @ yourbox] # audit2allow -a -M my_httpd

Nota:

para hacer de este paquete de política activa, ejecute:

semodule -i my_httpd.pp

[root @ yourbox] # semodule -i my_httpd.pp
[root @ yourbox] # systemctl restart httpd

2

Una forma de solucionar este problema en UBUNTU 14.04 fue haciendo clic derecho en el directorio donde se encuentra el archivo y cambiando los permisos de "otros" para "crear y eliminar archivos".