() translation by (you can also view the original English article)
En este tutorial aprenderás varias funciones importantes en PHP, que son suficientes para todas tus necesidades básicas de lectura y escritura en archivos. Aprenderás cómo leer un archivo, escribir en un archivo, escribir en un archivo de texto y verificar si un archivo existe.
Afortunadamente, PHP proporciona muchas funciones para leer y escribir datos en archivos. En este tutorial te mostraré las formas más sencillas de leer datos a partir de un archivo local o remoto y cómo usar banderas para escribir en archivos exactamente como queramos.
Verificando si un archivo existe
Tu primer paso al intentar leer datos de un archivo o escribir algo en él debe ser verificar si el archivo ya existe. Intentar leer datos de un archivo que no existe ocasionará que PHP muestre una advertencia y probablemente hará que tu código deje de funcionar.
La manera más sencilla de comprobar si un archivo existe es usando la función file_exists($filename)
de PHP. Esta devolverá true
(verdadero) si un archivo o directorio con el nombre $filename
dado existe y false
(falso) de lo contrario. Quizá esto sea obvio, pero me gustaría señalar que $filename
no tiene que ser solamente el nombre de un archivo. También puede ser una ruta absoluta o relativa. Por ejemplo, podemos usar prime_numbers.txt o science/project/periodic_table.txt.
Además es importante recordar que esta función también devolverá false
en el caso de archivos a los que no se pueda acceder debido a restricciones de modo seguro.
Otra función que puedes usar para comprobar la existencia de un archivo es is_file()
. A diferencia de file_exists()
, esta función solamente devolverá true
si la ruta especificada apunta a un archivo y no a un directorio.
Asegúrate de que el archivo realmente exista
Si el código que estás escribiendo lleva a cabo muchas operaciones en un archivo en particular, es posible que recibas resultados incorrectos usando las funciones anteriores. Esto es debido a que los resultados de la ejecución de file_exists()
y is_file()
se guardan en caché para mejorar el desempeño. PHP también guarda en caché los valores devueltos por otras funciones del sistema de archivos como filesize()
, filemtime()
, etc.
Puedes invocar a la función clearstatcache()
para asegurarte de que cualquier información a la que estés accediendo para un archivo esté actualizada.
Por lo general esto es un problema solamente si se está accediendo al mismo archivo múltiples veces en una sola secuencia de comandos para conocer su estado. Además, los datos en caché se limpian si eliminas el archivo dentro de la secuencia de comandos usando la función unlink()
. Esto básicamente significa que probablemente no te encontrarás con ningún problema relacionado con el almacenamiento en caché, pero aún así es bueno saber que puedes limpiar la memoria caché en caso de que la información se vuelva obsoleta o si estás obteniendo resultados inesperados al intentar acceder a información relacionada con un archivo.
Leyendo datos de un archivo en PHP
Una de las maneras más sencillas de leer datos de un archivo en PHP es con la ayuda de la función file_get_contents($filename, $use_include_path, $context, $offset, $maxlen)
. Esta simplemente leerá el archivo completo y te lo dará en forma de cadena. Todos los parámetros son opcionales, excepto el primero.
El segundo parámetro acepta un valor booleano para determinar si deben buscar un archivo en la ubicación especificada por la ruta incluida, que puede establecerse usando la función set_include_path()
.
Puedes usar el tercer parámetro para especificar diversas opciones y así refinar la manera en la que se accede a los archivos. Puedes usarlo para especificar valores de encabezado, como Cookies
y Host
, así como el método HTTP.
El parámetro $offset
determina el punto en el que comienza la lectura en el archivo original. Si se proporciona un valor negativo, comenzará a contar desde el final. El soporte para desplazamientos negativos fue agregado hasta PHP 7.1.0. Vale la pena mencionar que el desplazamiento solamente funciona en archivos locales y no es compatible con archivos remotos.
La función file_get_contents()
lee todo el archivo completo de forma predeterminada. Puedes cambiar este comportamiento proporcionando un valor para el parámetro $maxlen
. La longitud de los caracteres a leer se cuenta a partir del valor del desplazamiento.
Esta función devolverá false
si no pudo leer los datos del archivo que especificaste. Sin embargo, también puede devolver valores que se evalúan como false
, así que asegúrate de revisar si de verdad devolvió false usando el operador ===
.
Puedes usar esta función para abrir archivos remotos, pero eso sería posible solamente si el valor de la opción allow-url-fopen
en php.ini es true
o 1
.
Escribiendo datos en un archivo en PHP
Una de las maneras más sencillas de escribir datos en un archivo en PHP es con la ayuda de la función file_put_contents($filename, $data, $flags, $context)
.
El parámetro $filename
determina el archivo en el que será escrita la información. El segundo parámetro son los datos que quieras escribir en el archivo. La mayoría de las veces será una cadena, pero también puede ser un arreglo o un recurso de tipo stream (flujo).
Recuerda que PHP creará un archivo automáticamente por ti con el nombre dado si aún no existe. Sin embargo no creará ningún directorio. Esto significa que puedes almacenar un archivo con el nombre Del Origen de las Especies [Charles Darwin].txt sin errores. Sin embargo, si se establece el valor Biología/Evolución/Del Origen de las Especies [Charles Darwin].txt en $filename
y Biología/Evolución/ aún no existe, esto causará un error.
El parámetro $flags
determina la manera en la que se escribirá el contenido en un archivo. Puede tener uno o todos los siguientes tres valores:
-
FILE_USE_INCLUDE_PATH
— Esto le indica a PHP que debe buscar el nombre del archivo dado en el directorio incluide. -
FILE_APPEND
— Esto le indicará a PHP que agregue los datos que le pasaste a la función a los datos existentes en el archivo. Puede ser útil si estás almacenando datos en un archivo como un registro o un diario personal. Guardar nuevos datos como la temperatura o eventos que te ocurrieron a ti hoy no sobrescribirá lo que grabaste ayer. -
LOCK_EX
— Esto le dirá a PHP que obtenga un bloqueo en el archivo antes de comenzar a escribir contenido en él. Puede evitar que ocurran cosas inesperadas cuando dos secuencias de comandos diferentes están leyendo o escribiendo datos en el mismo archivo. Con este valor en particular conseguirás un bloqueo exclusivo en el archivo. Puedes leer más acerca de estos bloqueos en la documentación de PHP para la funciónflock()
.
Esta función devuelve el número de bytes que fueron escritos en el archivo si el procedimiento fue exitoso, y false
si falló. Sin embargo, aún debes usar el operador de igualdad estricta para verificar si tuvo éxito al escribir el contenido en el archivo. Esto es debido a que el código que escribe 0 bytes en el archivo aún será evaluado como false.
Leyendo y escribiendo datos en archivos
Puedes dirigirte al sitio web del Proyecto Gutenberg e intentar descargar archivos usando la función file_get_contents()
. Una vez que tengas los datos en una cadena, también puedes almacenarlos simplemente en un archivo local usando la función file_put_contents()
. El siguiente ejemplo aclarará esto:
1 |
<?php
|
2 |
|
3 |
$filename = 'http://www.gutenberg.org/cache/epub/1228/pg1228.txt'; |
4 |
|
5 |
$book_content = file_get_contents($filename); |
6 |
file_put_contents('Biology/Evolution/On the Origin of Species [Charles Darwin].txt', $book_content, LOCK_EX); |
7 |
|
8 |
?>
|
Puedes guardar páginas web o contenido de sitios web como Wikipedia de manera similar. Si necesitas entender el HTML o analizar el contenido HTML que acabas de guardar localmente, puedes seguir un tutorial como Analizando HTML con PHP usando DiDOM, que te ayudará a obtener automáticamente vínculos, archivos de tipo imagen o cualquier otra información similar de la página web.
Ahora regresemos a los archivos locales. Considera una situación en la que tiengas muchos archivos de texto y quieras analizar sus contenidos para ver cosas como las palabras más comunes en ellos. Esto puede lograrse fácilmente usando diversas funciones integradas en PHP.
1 |
<?php
|
2 |
|
3 |
$filename = 'On the Origin of Species [Charles Darwin].txt'; |
4 |
$book_content = file_get_contents($filename); |
5 |
|
6 |
$book_content_lowercase = strtolower($book_content); |
7 |
|
8 |
$individual_words = explode(' ', $book_content_lowercase); |
9 |
echo "There are about ".count($individual_words)." words in the book: ".substr($filename, 0, -4).".\n"; |
10 |
|
11 |
$word_frequency = array_count_values($individual_words); |
12 |
echo "Total number of unique words in the book are ".count($word_frequency).".\n"; |
13 |
echo "The word 'Elephant' occurs ".$word_frequency["elephant"]." times in the book.\n"; |
14 |
echo "The word 'Ant' occurs ".$word_frequency["ant"]." times in the book.\n"; |
15 |
|
16 |
if(isset($word_frequency["evolution"])) { |
17 |
echo "The word 'Evolution' occurs ".$word_frequency["evolution"]." times in the book.\n"; |
18 |
} else { |
19 |
echo "The word 'Evolution' does not occur even once in the book.\n"; |
20 |
}
|
21 |
|
22 |
arsort($word_frequency); |
23 |
echo "The most used word in the book is: '".key($word_frequency)."'.\n"; |
24 |
|
25 |
/* Output of all the code above |
26 |
|
27 |
There are about 147520 words in the book: On the Origin of Species [Charles Darwin]. |
28 |
Total number of unique words in the book are 22758. |
29 |
The word 'Elephant' occurs 3 times in the book. |
30 |
The word 'Ant' occurs 6 times in the book. |
31 |
The word 'Evolution' does not occur even once in the book. |
32 |
The most used word in the book is: 'the'. |
33 |
?>
|
Convertimos todo el texto a minúsculas y asumimos que cada una de las palabras está delimitada por espacios. Después el texto es convertido a un arreglo usando explode()
para facilitar el análisis de palabras individuales. Sorprendentemente, la palabra "evolution" ("evolución") no es usada ni una sola vez en el libro completo que dio origen a la teoría de la evolución.
Este fue solamente un ejemplo de un análisis automático de una gran cantidad de texto. Puedes hacer algo similar con cualquier tipo de texto almacenado en un archivo.
Registrando datos con FILE_APPEND
Otro ejemplo útil sería registrar información durante cortos períodos de tiempo. Puede ser tu rutina de ejercicios, datos del clima o de una colonia de abejas que estés observando. Una vez que tengas los datos en una cadena, puedes almacenarla fácilmente en un archivo y agregarla a los datos existentes usando la bandera FILE_APPEND
con file_put_contents()
.
1 |
<?php
|
2 |
|
3 |
$filename = "bee-colony.txt"; |
4 |
|
5 |
$present = date('l | jS \of F Y h:i:s A', time()); |
6 |
$entry = $present."\n"; |
7 |
|
8 |
// A pseudo function which could be replaced with something real.
|
9 |
$bee_information = gather_bee_data(); |
10 |
$entry .= "$bee_information.\n\n"; |
11 |
|
12 |
file_put_contents($filename, $entry, FILE_APPEND|LOCK_EX); |
13 |
|
14 |
?>
|
Es posible usar un código similar para algo como almacenar el artículo destacado del día de Wikipedia en un archivo todos los días o llevar un registro de los artículos y titulares de las noticias durante el transcurso de semanas o meses. Todo lo que necesitas hacer es escribir código para obtener datos y luego almacenarlos usando algo similar al fragmento de código anterior. Un tutorial como Analizando HTML con PHP usando DiDOM puede ayudarte con la parte de la obtención.
En vez de escribir el texto en formato plano, puedes envolverlo en un poco de HTML para que sea más sencillo leerlo en navegadores. Las posibilidades son infinitas.
Consideraciones finales
Existen muchas otras maneras de leer y escribir datos en archivos con PHP. Sin embargo, file_get_contents()
y file_put_contents()
abordarán casi todas tus necesidades básicas sin añadir complicaciones innecesarias.
La única vez en la que podrías enfrentarte a un problema con file_get_contents()
es cuando el archivo que estés leyendo sea muy grande, por ejemplo de un tamaño de 2 GB o más. Esto es debido a que file_get_contents()
carga el archivo completo en la memoria al mismo tiempo, y hay muchas posibilidades de quedarse sin memoria con archivos tan grandes. En ese caso tendrás que confiar en funciones como fgets()
y fread()
para leer una pequeña parte del archivo a la vez.