file_get_contents('notes.txt') lee el archivo entero y lo devuelve como una cadena. Si el archivo no se puede leer, devuelve false. Para escribir, usa file_put_contents('notes.txt', $text), que crea el archivo o sustituye lo que había en él.
Salida:
Buy milk
Call Ada
Write docs
29 bytes
3 lines
El bloque escribe primero notes.txt y luego lo vuelve a leer, así que tiene un archivo con el que trabajar. Una ruta como 'notes.txt' es relativa al directorio de trabajo actual; en una aplicación web, construye la ruta a partir de la carpeta del propio script con __DIR__ . '/notes.txt'.
Escribir y añadir con file_put_contents()
file_put_contents() devuelve el número de bytes escritos, o false si falla. Por defecto sobrescribe el archivo. La opción FILE_APPEND añade al final en su lugar, que es como funcionan los logs sencillos, y LOCK_EX impide que dos peticiones escriban en el mismo momento:
Salida:
Wrote 8 bytes
started
step 1 done
step 2 done
replaced
abc
5 bytes
Para guardar un array y recuperarlo como array, escríbelo como JSON con json_encode() y léelo con json_decode().
Leer un archivo línea a línea con file()
file() lee un archivo en un array con una línea por elemento. Cada línea conserva su salto de línea al final salvo que pases FILE_IGNORE_NEW_LINES, y FILE_SKIP_EMPTY_LINES descarta las líneas en blanco (solo funciona junto con FILE_IGNORE_NEW_LINES):
Salida:
string(9) "Buy milk
"
1. Buy milk
2. Call Ada
3. Write docs
3 tasks
file() y file_get_contents() cargan el archivo entero en memoria. Eso está bien para archivos de configuración y logs de unos pocos megabytes. Para un archivo de cientos de megabytes, léelo línea a línea con fopen() y fgets().
Comprobar si un archivo existe antes de leerlo
Cuando falta el archivo, file_get_contents() devuelve false y PHP imprime un warning:
Warning: file_get_contents(missing.txt): Failed to open stream: No such file or directory in /home/index.php on line 2
Comprueba antes con is_file() (un archivo que existe y no es un directorio) o file_exists() (un archivo o un directorio), y compara siempre el resultado con === false, porque un archivo vacío devuelve "", que también es falsy:
Salida:
empty.txt exists file
missing.txt missing
. exists directory
Cannot read missing.txt, using defaults
bool(false)
bool(true)
0 bytes
No ocultes el warning con @file_get_contents(). Comprobar antes, o manejar el false, mantiene visible el error cuando falla otra cosa.
Leer una parte de un archivo
El cuarto y el quinto argumento son el desplazamiento en bytes desde el que empezar y el número de bytes que leer. Un desplazamiento negativo cuenta desde el final del archivo. Los argumentos con nombre te permiten saltarte los dos argumentos intermedios:
Salida:
HEADER
line 2
last line
Los desplazamientos cuentan bytes, no caracteres. En UTF-8 un carácter japonés ocupa 3 bytes, así que un desplazamiento en mitad de uno lo parte por la mitad. Para trabajar con caracteres, lee la cadena entera y usa mb_substr().
Mostrar un archivo de texto en una página web
El contenido de un archivo es texto, y el texto que se imprime en HTML debe escaparse, o un < del archivo se convierte en una etiqueta. htmlspecialchars() lo escapa y nl2br() convierte los saltos de línea en etiquetas <br>. Ejecútalo y mira la pestaña Página:
Quita htmlspecialchars() y vuelve a ejecutarlo: ahora la página termina en "v1.2: Fixed", porque el navegador lee <title> como una etiqueta real y se traga todo lo que va después como título de la página. La página de htmlspecialchars() explica por qué eso importa con cualquier cosa que pueda escribir un usuario.
Leer una URL con file_get_contents()
Con allow_url_fopen activado (el valor por defecto en php.ini), file_get_contents() también lee URLs y devuelve el cuerpo de la respuesta. Un contexto de stream añade un método, cabeceras, un cuerpo y un timeout:
<?php
$html = file_get_contents('https://example.com/');
$context = stream_context_create([
'http' => [
'method' => 'POST',
'header' => "Content-Type: application/json\r\n",
'content' => json_encode(['name' => 'Ada']),
'timeout' => 5,
'ignore_errors' => true, // return the body of 4xx/5xx responses too
],
]);
$response = file_get_contents('https://api.example.com/users', false, $context);
if ($response === false) {
// DNS failure, timeout, or a refused connection
}
Para reintentos, redirecciones con límites y códigos de error claros, cURL o una librería cliente HTTP como Guzzle es la mejor herramienta.
file_get_contents vs file() vs fopen()
| Quieres | Usa | Memoria |
|---|---|---|
| El archivo entero como una cadena | file_get_contents() | El archivo entero |
| Las líneas como array | file($path, FILE_IGNORE_NEW_LINES) | El archivo entero |
| Escribir o sustituir un archivo en una llamada | file_put_contents() | Los datos que escribes |
| Añadir una línea a un log | file_put_contents($path, $line, FILE_APPEND | LOCK_EX) | Una línea |
| Leer un archivo grande línea a línea, o filas CSV | fopen() con fgets() o fgetcsv() | Una línea |
| Leer y escribir el mismo archivo abierto | fopen() con r+, a+ o c+ | Lo que lees |
Las funciones de una sola llamada abren, leen o escriben y cierran el archivo por ti, así que son la opción por defecto adecuada. Recurre a fopen() cuando el archivo sea demasiado grande para tenerlo en memoria o necesites mantenerlo abierto entre operaciones.
Preguntas frecuentes
¿Cómo leo un archivo en una cadena en PHP?
Llama a file_get_contents('path/to/file.txt'). Devuelve el archivo entero como cadena, o false si no se puede leer, así que compara el resultado con === false antes de usarlo.
¿Cómo añado contenido al final de un archivo en PHP?
Pasa la opción FILE_APPEND: file_put_contents('log.txt', "new line\n", FILE_APPEND);. Sin ella, file_put_contents() sustituye el archivo entero. Añade LOCK_EX (FILE_APPEND | LOCK_EX) cuando varias peticiones puedan escribir a la vez.
¿Cómo leo un archivo línea a línea en PHP?
Para archivos pequeños, file('data.txt', FILE_IGNORE_NEW_LINES) devuelve un array con una línea por elemento. Para archivos grandes, ábrelo con fopen() y lee una línea cada vez con fgets() en un bucle while, que solo guarda una línea en memoria.
¿Por qué file_get_contents devuelve false?
El archivo no existe, la ruta es relativa a un directorio distinto del que crees, o PHP no tiene permiso para leerlo. PHP además imprime un warning como Failed to open stream: No such file or directory. Compruébalo con is_file() e is_readable(), y construye las rutas a partir de __DIR__.
¿file_get_contents puede leer una URL?
Sí, cuando allow_url_fopen está activado en php.ini: file_get_contents('https://example.com/') devuelve el cuerpo de la respuesta. Para cabeceras, datos POST o un timeout, pasa un contexto de stream_context_create(); para algo más complejo, cURL maneja mejor los errores.