2011-03-14 14 views
17

En PHP, ¿cómo puedo verificar si un recurso de flujo (o puntero de archivo, manejar, o lo que sea que quiera llamar) es legible o escribible? Por ejemplo, si se encuentra en una situación en la que no sabe nada sobre cómo se abrió o creó el recurso, ¿cómo verifica si es legible? ¿Y cómo verifica si se puede escribir?¿Cómo comprobar si un recurso de secuencia de PHP es legible o escribible?

Según las pruebas que he realizado (solo con archivos de texto normales que usan PHP 5.3.3), fread() no arroja ningún error en ningún nivel cuando el recurso no es legible. Simplemente devuelve una cadena vacía, pero también lo hace para un archivo vacío. E idealmente, sería mejor tener una verificación que no modifique el recurso en sí. Probar si un recurso es legible tratando de leer de él cambiará la posición del puntero.

Por el contrario, fwrite() no arroja ningún error en ningún nivel cuando el recurso no se puede escribir. Simplemente devuelve cero. Esto es un poco más útil, porque si estaba tratando de escribir una cierta cantidad de bytes en un archivo y fwrite() devuelve cero, sabrá que algo salió mal. Pero aún así, este no es un método ideal, porque sería mucho mejor saber si se puede escribir antes de escribir en lugar de tratar de escribir y ver si falla.

Además, idealmente, la comprobación debería funcionar en cualquier tipo de recurso de flujo, no solo en archivos.

¿Esto es posible? ¿Existe algo como esto? No he podido encontrar nada útil. Gracias de antemano por sus respuestas.

+0

Por supuesto, tanto [ ' fread() '] (http://php.net/fread) y [' fwrite() '] (http://php.net/fwrite) devuelve' bool (false) 'en caso de falla según su página de documentación respectiva .... Pero eso no sucede en PHP 5.3.5. –

Respuesta

24

bastante simple. Sólo tiene que llamar stream_get_meta_data($resource) de la secuencia de comandos, a continuación, comprobar el elemento mode gama del valor de retorno:

$f = fopen($file, 'r'); 
$meta = stream_get_meta_data($f); 
var_dump($meta['mode']); // r 

Y si quieres saber si los datos subyacentes se puede escribir:

var_dump(is_writable($meta['uri'])); // true if the file/uri is writable 
+1

'La secuencia puede ser cualquier secuencia creada por fopen(), fsockopen() y pfsockopen(). '¿No funciona en ningún archivo abierto con fwrite? ¿Fread? Mejor que mi solución en algunos casos, mucho, mucho peor en otros ... ** editar ** no importa, fread y fwrite USE maneja abierto por fopen. Soy un idiota. – rockerest

+1

@rock: no puede abrir un archivo con 'fwrite' o' fread'. Esas funciones solo funcionan en transmisiones abiertas. Esta función funcionará en todos los recursos de flujo en PHP. Así que no veo cómo podría ser * mucho, mucho peor *. De hecho, esto es 100% independiente de la plataforma y también funcionará con contenedores de flujo. Entonces, en realidad es la solución correcta ... – ircmaxell

+0

Creo que me gusta esto. ¿Sabes si la tabla de modos en la página ['fopen()' en el manual] (http://www.php.net/manual/en/function.fopen.php) es una lista completamente exhaustiva? – jnrbsn

1

De acuerdo, esta puede no ser la mejor solución, pero creo que es suficiente, dado que no hay nada en PHP que haga esto de forma automática.

Para el primer paso, obtendrá el nodo-i del recurso desde el archivo, y después lee el nombre del archivo:

$stat = fstat($fp); 
$inode = $stat['ino']; 
system("find -inum $inode", $result); 

toman directamente de this question about finding the filename from a filehandle.

Ahora que tiene el nombre de archivo (en $result) puede hacer una fileperms($result) para obtener los permisos.

Tenga en cuenta que fileperms() devuelve un int, y la documentación hace la magia (en realidad solo trata el int como un octal) de mantener ese 0 inicial (por ejemplo, 0755).

También tenga en cuenta que la documentación que hace la magia de convertir ese int en una cadena agradable como -rw-r--r--

+0

Suponiendo que el recurso es un archivo para comenzar. Podría ser un socket, o 'php: // stdin'. –

+0

... y el sistema es * nix. No es perfecto de ninguna manera, pero creo que es lo mejor que PHP puede hacer. – rockerest

+0

También es muy posible que el archivo pueda ser editable, pero que el identificador de archivo esté abierto solo para su lectura.Aunque esto es bastante inteligente. – Charles

Cuestiones relacionadas