file_get_contents() y file_put_contents() son las funciones PHP para leer y escribir ficheros completos en una sola llamada. Para la mayoría de los casos donde el fichero cabe en memoria, son la opción más rápida y legible frente a la combinación de fopen(), fread() y fclose().
file_get_contents(): leer el contenido completo
<?php
// Leer un fichero de texto completo
$contenido = file_get_contents('/var/www/config/settings.json');
if ($contenido === false) {
throw new RuntimeException('No se pudo leer settings.json');
}
// Decodificar JSON directamente
$config = json_decode($contenido, true, 512, JSON_THROW_ON_ERROR);
echo $config['database']['host'];
?>
Devuelve false si no puede leer el fichero (permisos, ruta incorrecta, disco lleno). Comprueba siempre con === false, no con if (!$contenido), porque un fichero vacío devuelve una cadena vacía que es falsy.
Leer solo una parte del fichero
<?php
// Leer los primeros 1024 bytes
$cabecera = file_get_contents('/ruta/fichero.bin', false, null, 0, 1024);
// Leer desde el byte 512 en adelante (máximo 256 bytes)
$trozo = file_get_contents('/ruta/fichero.bin', false, null, 512, 256);
?>
file_put_contents(): escribir contenido completo
<?php
$datos = "Línea unonLínea dosn";
// Sobreescribe el fichero si existe, lo crea si no
$bytes = file_put_contents('/tmp/salida.txt', $datos);
if ($bytes === false) {
throw new RuntimeException('No se pudo escribir el fichero');
}
echo "Escritos $bytes bytes";
?>
FILE_APPEND y LOCK_EX para logs
FILE_APPEND añade al final del fichero en lugar de sobreescribirlo. LOCK_EX adquiere un bloqueo exclusivo antes de escribir, evitando corrupción por escrituras concurrentes:
<?php
function escribirLog(string $mensaje): void
{
$linea = date('[Y-m-d H:i:s]') . ' ' . $mensaje . "n";
file_put_contents(
'/var/log/app/app.log',
$linea,
FILE_APPEND | LOCK_EX
);
}
escribirLog('Usuario 42 ha iniciado sesión');
escribirLog('Pedido #1001 procesado');
?>
Peticiones HTTP sin cURL
file_get_contents() puede hacer peticiones HTTP si la opción allow_url_fopen está habilitada en php.ini (lo está por defecto en la mayoría de instalaciones):
<?php
// GET simple
$respuesta = file_get_contents('https://api.github.com/repos/php/php-src');
// GET con cabeceras personalizadas usando stream_context_create()
$ctx = stream_context_create([
'http' => [
'method' => 'GET',
'header' => implode("rn", [
'User-Agent: MiApp/1.0',
'Accept: application/json',
'Authorization: Bearer ' . getenv('API_TOKEN'),
]),
'timeout' => 10,
],
]);
$respuesta = file_get_contents('https://api.ejemplo.com/datos', false, $ctx);
if ($respuesta === false) {
// $http_response_header contiene las cabeceras de la respuesta
error_log('Error HTTP: ' . ($http_response_header[0] ?? 'sin respuesta'));
}
?>
Para peticiones POST o APIs complejas, cURL es más adecuado. file_get_contents() no sigue redirecciones por defecto ni gestiona bien los errores HTTP (devuelve el body incluso con 404 o 500).
Comprobación de errores: el patrón correcto
<?php
// MAL: un fichero vacío devuelve '' (falsy), esto falla
$contenido = file_get_contents('/ruta/fichero.txt');
if (!$contenido) { /* puede fallar con ficheros vacíos */ }
// BIEN: compara con === false
$contenido = file_get_contents('/ruta/fichero.txt');
if ($contenido === false) {
throw new RuntimeException('Error al leer el fichero');
}
// También útil: @ suprime el warning de PHP, pero no olvides comprobar el retorno
$contenido = @file_get_contents('/ruta/fichero.txt');
if ($contenido === false) {
// gestionar error
}
?>
Cuándo no usar estas funciones
- Ficheros grandes (más de unos pocos MB):
file_get_contents()los carga completos en memoria. Usafgets()oSplFileObjectpara leerlos línea a línea. - Ficheros binarios muy grandes: usa
fread()con chunks. - Escritura concurrente intensiva: aunque
LOCK_EXayuda, considera una solución de cola o un sistema de log dedicado.
La documentación de file_get_contents() y la de file_put_contents() detallan todos los parámetros, incluidos los flags disponibles y el uso con contextos de stream.
