Buscar..


Sintaxis

  • int readfile (cadena $ nombre de archivo [, bool $ use_include_path = falso [, recurso $ contexto]])

Parámetros

Parámetro Descripción
nombre del archivo El nombre del archivo que se está leyendo.
use_include_path Puede usar el segundo parámetro opcional y establecerlo en VERDADERO, si desea buscar el archivo en la ruta de inclusión, también.
contexto Un recurso de flujo de contexto.

Observaciones

Sintaxis de nombre de archivo

La mayoría de los nombres de archivos pasados ​​a las funciones en este tema son:

  1. Cuerdas en la naturaleza.
    • Los nombres de los archivos se pueden pasar directamente. Si se pasan valores de otros tipos, se convierten en cadena. Esto es especialmente útil con SplFileInfo , que es el valor en la iteración de DirectoryIterator .
  2. Relativo o absoluto.
    • Pueden ser absolutos. En sistemas similares a Unix, las rutas absolutas comienzan con / , por ejemplo, /home/user/file.txt , mientras que en Windows, las rutas absolutas comienzan con la unidad, por ejemplo, C:/Users/user/file.txt
    • También pueden ser relativos, lo que depende del valor de getcwd y está sujeto a cambios por chdir .
  3. Aceptar protocolos.
    • Pueden comenzar con el scheme:// para especificar el envoltorio de protocolo para administrar. Por ejemplo, file_get_contents("http://example.com") recupera contenido de http://example.com .
  4. Slash-compatible.
    • Si bien DIRECTORY_SEPARATOR en Windows es una barra invertida y el sistema devuelve barras diagonales para las rutas de forma predeterminada, el desarrollador puede seguir utilizando / como el separador de directorios. Por lo tanto, por compatibilidad, los desarrolladores pueden usar / as separadores de directorio en todos los sistemas, pero tenga en cuenta que los valores devueltos por las funciones (por ejemplo, realpath ) pueden contener barras diagonales inversas.

Eliminar archivos y directorios

Borrando archivos

La función de unlink elimina un solo archivo y devuelve si la operación se realizó correctamente.

$filename = '/path/to/file.txt';

if (file_exists($filename)) {
    $success = unlink($filename);
    
    if (!$success) {
         throw new Exception("Cannot delete $filename");
    }
}

Eliminando directorios, con borrado recursivo.

Por otro lado, los directorios deben eliminarse con rmdir . Sin embargo, esta función solo borra los directorios vacíos. Para eliminar un directorio con archivos, elimine primero los archivos en los directorios. Si el directorio contiene subdirectorios, puede ser necesaria la recursión .

El siguiente ejemplo escanea archivos en un directorio, borra archivos / directorios miembros de forma recursiva y devuelve la cantidad de archivos (no directorios) eliminados.

function recurse_delete_dir(string $dir) : int {
    $count = 0;

    // ensure that $dir ends with a slash so that we can concatenate it with the filenames directly
    $dir = rtrim($dir, "/\\") . "/";

    // use dir() to list files
    $list = dir($dir);

    // store the next file name to $file. if $file is false, that's all -- end the loop.
    while(($file = $list->read()) !== false) {
        if($file === "." || $file === "..") continue;
        if(is_file($dir . $file)) {
            unlink($dir . $file);
            $count++;
        } elseif(is_dir($dir . $file)) {
            $count += recurse_delete_dir($dir . $file);
        }
    }

    // finally, safe to delete directory!
    rmdir($dir);

    return $count;
}

Funciones de conveniencia

Raw directo IO

file_get_contents y file_put_contents brindan la capacidad de leer / escribir desde / a un archivo a / desde una cadena PHP en una sola llamada.

file_put_contents también se puede usar con el FILE_APPEND máscara de bits FILE_APPEND para adjuntar, en lugar de truncar y sobrescribir, el archivo. Se puede usar junto con la máscara de bits LOCK_EX para adquirir un bloqueo exclusivo del archivo mientras se continúa con la escritura. Banderas de máscara de bits se pueden unir con el | operador en modo bit-OR.

$path = "file.txt";
// reads contents in file.txt to $contents
$contents = file_get_contents($path);
// let's change something... for example, convert the CRLF to LF!
$contents = str_replace("\r\n", "\n", $contents);
// now write it back to file.txt, replacing the original contents
file_put_contents($path, $contents);

FILE_APPEND es útil para LOCK_EX archivos de registro, mientras que LOCK_EX ayuda a prevenir la condición de carrera de la escritura de archivos desde múltiples procesos. Por ejemplo, para escribir en un archivo de registro sobre la sesión actual:

file_put_contents("logins.log", "{$_SESSION["username"]} logged in", FILE_APPEND | LOCK_EX);

CSV IO

fgetcsv($file, $length, $separator)

El fgetcsv analiza la línea desde el archivo abierto que comprueba los campos csv. Devuelve campos CSV en una matriz en caso de éxito o FALSE en caso de error.

Por defecto, solo leerá una línea del archivo CSV.

$file = fopen("contacts.csv","r");
print_r(fgetcsv($file));    
print_r(fgetcsv($file,5," "));
fclose($file); 

contacts.csv

Kai Jim, Refsnes, Stavanger, Norway
Hege, Refsnes, Stavanger, Norway

Salida:

Array
(
    [0] => Kai Jim
    [1] => Refsnes
    [2] => Stavanger
    [3] => Norway
)
Array
(
    [0] => Hege,
)

Leyendo un archivo a stdout directamente

readfile copia un archivo al búfer de salida. readfile () no presentará ningún problema de memoria, incluso al enviar archivos grandes, por su cuenta.

$file = 'monkey.gif';

if (file_exists($file)) {
    header('Content-Description: File Transfer');
    header('Content-Type: application/octet-stream');
    header('Content-Disposition: attachment; filename="'.basename($file).'"');
    header('Expires: 0');
    header('Cache-Control: must-revalidate');
    header('Pragma: public');
    header('Content-Length: ' . filesize($file));
    readfile($file);
    exit;
}

O desde un puntero de archivo

Alternativamente, para buscar un punto en el archivo para comenzar a copiar a la salida fpassthru , use fpassthru en fpassthru lugar. En el siguiente ejemplo, los últimos 1024 bytes se copian en la salida estándar:

$fh = fopen("file.txt", "rb");
fseek($fh, -1024, SEEK_END); 
fpassthru($fh);

Leyendo un archivo en una matriz

file devuelve las líneas en el archivo pasado en una matriz. Cada elemento de la matriz corresponde a una línea en el archivo, con la nueva línea aún adjunta.

print_r(file("test.txt"));

test.txt

Welcome to File handling
This is to test file handling

Salida:

Array 
( 
    [0] => Welcome to File handling 
    [1] => This is to test file handling 
)

Obteniendo información del archivo

Compruebe si una ruta es un directorio o un archivo

La función is_dir devuelve si el argumento es un directorio, mientras que is_file devuelve si el argumento es un archivo. Use file_exists para verificar si es cualquiera de los dos.

$dir  = "/this/is/a/directory";
$file = "/this/is/a/file.txt";

echo is_dir($dir) ? "$dir is a directory" : "$dir is not a directory", PHP_EOL,
    is_file($dir) ? "$dir is a file" : "$dir is not a file", PHP_EOL,
    file_exists($dir) ? "$dir exists" : "$dir doesn't exist", PHP_EOL,
    is_dir($file) ? "$file is a directory" : "$file is not a directory", PHP_EOL,
    is_file($file) ? "$file is a file" : "$file is not a file", PHP_EOL,
    file_exists($file) ? "$file exists" : "$file doesn't exist", PHP_EOL;

Esto da:

/this/is/a/directory is a directory
/this/is/a/directory is not a file
/this/is/a/directory exists
/this/is/a/file.txt is not a directory
/this/is/a/file.txt is a file
/this/is/a/file.txt exists

Comprobando el tipo de archivo

Use filetype para verificar el tipo de archivo, que puede ser:

  • fifo
  • char
  • dir
  • block
  • link
  • file
  • socket
  • unknown

Pasando el nombre del filetype directamente al tipo de filetype :

echo filetype("~"); // dir

Tenga en cuenta que el tipo de filetype devuelve false y activa un E_WARNING si el archivo no existe.

Comprobando legibilidad y capacidad de escritura

Al pasar el nombre del archivo a las funciones is_writable e is_readable , verifique si el archivo se puede escribir o leer respectivamente.

Las funciones devuelven false gracia si el archivo no existe.

Comprobando el acceso a los archivos / modificar el tiempo

El uso de filemtime y fileatime devuelve la marca de tiempo de la última modificación o acceso del archivo. El valor de retorno es una marca de tiempo de Unix; consulte Trabajar con fechas y hora para obtener más detalles.

echo "File was last modified on " . date("Y-m-d", filemtime("file.txt"));
echo "File was last accessed on " . date("Y-m-d", fileatime("file.txt"));

Obtener partes de ruta con fileinfo

$fileToAnalyze = ('/var/www/image.png');

$filePathParts = pathinfo($fileToAnalyze);

echo '<pre>';
   print_r($filePathParts);
echo '</pre>';

Este ejemplo dará como resultado:

Array
(
    [dirname] => /var/www
    [basename] => image.png
    [extension] => png
    [filename] => image
)

Que se puede utilizar como:

$filePathParts['dirname']
$filePathParts['basename']
$filePathParts['extension']
$filePathParts['filename']
Parámetro Detalles
$ camino La ruta completa del archivo a analizar
$ opción Una de las cuatro opciones disponibles [PATHINFO_DIRNAME, PATHINFO_BASENAME, PATHINFO_EXTENSION o PATHINFO_FILENAME]
  • Si no se pasa una opción (el segundo parámetro), se devuelve una matriz asociativa, de lo contrario se devuelve una cadena.
  • No valida que el archivo exista.
  • Simplemente analiza la cadena en partes. No se realiza ninguna validación en el archivo (sin verificación de tipo mime, etc.)
  • La extensión es simplemente la última extensión de $path La ruta para el archivo image.jpg.png sería .png incluso si técnicamente es un archivo .jpg . Un archivo sin una extensión no devolverá un elemento de extensión en la matriz.

Minimiza el uso de la memoria al tratar con archivos grandes

Si necesitamos analizar un archivo grande, por ejemplo, un CSV de más de 10 Mbytes que contiene millones de filas, algunos utilizan las funciones file o file_get_contents y terminan con la configuración de memory_limit con

Tamaño de memoria permitido de XXXXX bytes agotado

error. Considere la siguiente fuente (top-1m.csv tiene exactamente 1 millón de filas y tiene aproximadamente 22 Mbytes de tamaño)

var_dump(memory_get_usage(true));
$arr = file('top-1m.csv');
var_dump(memory_get_usage(true));

Esto produce:

int(262144)
int(210501632) 

porque el intérprete necesitaba mantener todas las filas en la matriz $arr , por lo que consumía ~ 200 Mbytes de RAM. Tenga en cuenta que ni siquiera hemos hecho nada con el contenido de la matriz.

Ahora considere el siguiente código:

var_dump(memory_get_usage(true));
$index = 1;
if (($handle = fopen("top-1m.csv", "r")) !== FALSE) {
    while (($row = fgetcsv($handle, 1000, ",")) !== FALSE) {
        file_put_contents('top-1m-reversed.csv',$index . ',' . strrev($row[1]) . PHP_EOL, FILE_APPEND);
        $index++;
    }
    fclose($handle);
}
var_dump(memory_get_usage(true));

que salidas

int(262144)
int(262144)

por lo tanto, no utilizamos un solo byte extra de memoria, sino que analizamos todo el CSV y lo guardamos en otro archivo invirtiendo el valor de la segunda columna. Esto se debe a que fgetcsv lee solo una fila y $row se sobrescribe en cada bucle.

Archivo basado en flujo IO

Abriendo un arroyo

fopen abre un identificador de flujo de archivos, que se puede usar con varias funciones para leer, escribir, buscar y otras funciones encima de él. Este valor es de tipo de resource y no se puede pasar a otros subprocesos que conservan su funcionalidad.

$f = fopen("errors.log", "a"); // Will try to open errors.log for writing

El segundo parámetro es el modo del flujo de archivos:

Modo Descripción
r Abrir en modo de solo lectura, comenzando desde el principio del archivo
r+ Abierto para lectura y escritura, comenzando desde el principio del archivo.
w Abierto solo para escritura, comenzando desde el principio del archivo. Si el archivo existe, vaciará el archivo. Si no existe intentará crearlo.
w+ Abierto para lectura y escritura, comenzando desde el principio del archivo. Si el archivo existe, vaciará el archivo. Si no existe intentará crearlo.
a abra un archivo solo para escritura, comenzando al final del archivo. Si el archivo no existe, intentará crearlo.
a+ abra un archivo para leer y escribir, comenzando al final del archivo. Si el archivo no existe, intentará crearlo.
x crear y abrir un archivo para escritura solamente. Si el archivo existe la llamada fopen fallará
x+ Crea y abre un archivo para leer y escribir. Si el archivo existe la llamada fopen fallará
c abrir el archivo para la escritura solamente. Si el archivo no existe, intentará crearlo. Comenzará a escribir al principio del archivo, pero no vaciará el archivo antes de escribir.
c+ Abre el archivo para leer y escribir. Si el archivo no existe, intentará crearlo. Comenzará a escribir al principio del archivo, pero no vaciará el archivo antes de escribir.

Al agregar una t detrás del modo (por ejemplo, a+b , wt , etc.) en Windows se traducirán los finales de línea "\n" a "\r\n" cuando se trabaje con el archivo. Agregue b detrás del modo si esto no está destinado, especialmente si es un archivo binario.

La aplicación PHP debe cerrar las secuencias utilizando fclose cuando ya no se utilizan para evitar el error Too many open files . Esto es particularmente importante en los programas CLI, ya que las transmisiones solo se cierran cuando se cierra el tiempo de ejecución, lo que significa que en los servidores web puede que no sea necesario (pero aún debería , como práctica para evitar la pérdida de recursos) cerrar las transmisiones. si no espera que el proceso se ejecute durante mucho tiempo y no abrirá muchas secuencias.

Leyendo

Usando fread leerá el número dado de bytes desde el puntero del archivo, o hasta que se cumpla un EOF.

Líneas de lectura

El uso de fgets leerá el archivo hasta que se alcance un EOL, o se lea la longitud dada.

Tanto fread como fgets moverán el puntero del archivo mientras lee.

Leyendo todo lo que queda

El uso de stream_get_contents hará que todos los bytes restantes en el flujo en una cadena y lo devuelvan.

Ajuste de la posición del puntero del archivo

Inicialmente, después de abrir el flujo, el puntero del archivo está al principio del archivo (o al final, si se usa el modo a ). El uso de la función fseek moverá el puntero del archivo a una nueva posición, en relación con uno de los tres valores:

  • SEEK_SET : este es el valor predeterminado; el desplazamiento de posición del archivo será relativo al principio del archivo.
  • SEEK_CUR : El desplazamiento de la posición del archivo será relativo a la posición actual.
  • SEEK_END : El desplazamiento de posición del archivo será relativo al final del archivo. Pasar un desplazamiento negativo es el uso más común para este valor; moverá la posición del archivo al número especificado de bytes antes del final del archivo.

rewind es un atajo de conveniencia de fseek($fh, 0, SEEK_SET) .

El uso de ftell mostrará la posición absoluta del puntero del archivo.

Por ejemplo, el siguiente script lee omite los primeros 10 bytes, lee los siguientes 10 bytes, omite 10 bytes, lee los siguientes 10 bytes y luego los últimos 10 bytes en file.txt:

$fh = fopen("file.txt", "rb");
fseek($fh, 10); // start at offset 10
echo fread($fh, 10); // reads 10 bytes
fseek($fh, 10, SEEK_CUR); // skip 10 bytes
echo fread($fh, 10); // read 10 bytes
fseek($fh, -10, SEEK_END); // skip to 10 bytes before EOF
echo fread($fh, 10); // read 10 bytes
fclose($fh);

Escritura

El uso de fwrite escribe la cadena proporcionada en el archivo comenzando en el puntero del archivo actual.

fwrite($fh, "Some text here\n");

Mover y copiar archivos y directorios

Copiando documentos

copy copia el archivo de origen en el primer argumento al destino en el segundo argumento. El destino resuelto debe estar en un directorio que ya esté creado.

if (copy('test.txt', 'dest.txt')) {
    echo 'File has been copied successfully';
} else {
    echo 'Failed to copy file to destination given.'
}

Copiando directorios, con recursion.

Copiar directorios es muy similar a eliminar directorios, excepto que para copy archivos en lugar de unlink se usa, mientras que para directorios, mkdir lugar de rmdir se usa al principio en lugar de estar al final de la función.

function recurse_delete_dir(string $src, string $dest) : int {
    $count = 0;

    // ensure that $src and $dest end with a slash so that we can concatenate it with the filenames directly
    $src = rtrim($dest, "/\\") . "/";
    $dest = rtrim($dest, "/\\") . "/";

    // use dir() to list files
    $list = dir($src);

    // create $dest if it does not already exist
    @mkdir($dest);

    // store the next file name to $file. if $file is false, that's all -- end the loop.
    while(($file = $list->read()) !== false) {
        if($file === "." || $file === "..") continue;
        if(is_file($src . $file)) {
            copy($src . $file, $dest . $file);
            $count++;
        } elseif(is_dir($src . $file)) {
            $count += recurse_copy_dir($src . $file, $dest . $file);
        }
    }

    return $count;
}

Renombrando / Moviendo

Renombrar / Mover archivos y directorios es mucho más simple. Se pueden mover o renombrar directorios completos en una sola llamada, usando la función de rename .

  • rename("~/file.txt", "~/file.html");

  • rename("~/dir", "~/old_dir");

  • rename("~/dir/file.txt", "~/dir2/file.txt");



Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow