Funciones para abrir archivos
file_get_contents y fopen
Hoy voy hablar sobre dos funciones bastante utilizadas en PHP para abrir archivos. Cuando conviene usar una y otra y, ventajas y desventajas que tiene cada una de ellas.
Cuando aprendemos PHP, o bueno, cualquier lenguaje de programación, uno de los temas básicos que se enseña es a abrir y leer archivos. En PHP, siempre se enseña la función fopen() para abrir un archivo y leerlo. También escribirlo. Sin embargo, la función file_get_contents() digamos que queda en un segundo plano e incluso hay libros y manuales que ni la mencionan.
Es cierto que cuando tratamos con archivos, es correcto aprender primero a usar fopen() porque es más completa y nos permite un control total sobre el archivo.
¿Pero qué sucede con la función file_get_contents? ¿Para qué existe?
Como he dicho al principio, también podemos hacer lo mismo, pero con algunas limitaciones y diferencias importantes.
¡Empecemos!
Abriendo archivos con fopen()
La función fopen() permite abrir un archivo y leerlo, escribir sobre él en algún punto exacto, crearlo desde cero y escribirlo sino existe, etc. Como he dicho antes, proporciona un control total sobre el archivo.
Dependiendo del modo de apertura podremos hacer una cosa u otra.
La sintaxis de la función es:
fopen(string $filename, string $mode, bool $use_include_path = false, ?resource $context = null)
Pero la forma típica de usarla es pasándole solo dos parámetros: por un lado, el nombre del archivo y por otro, el modo de apertura que queremos.
fopen(“nombre_archivo”, “modo apertura”);
$archivo = fopen("archivo.txt", "w"); fwrite($archivo, "Esto es un contenido de prueba bla bla bla"); fclose($archivo);
Como acabamos de ver, este ejemplo es muy sencillo.
Abrimos un archivo en modo escritura (w) y usamos dos funciones más, fwrite() para escribir contenido en el archivo y fclose() para cerrar el archivo.
Es importante tener en cuenta que siempre que abramos un archivo, sea para lo que sea, lo cerremos con la funcion fclose().
Otro ejemplo:
$archivo = fopen("archivo.txt", "r"); if ($archivo) { while (($linea = fgets($archivo)) !== false) { echo $linea; // Muestra el contenido línea por línea. } fclose($archivo); } else { echo "Error al abrir el archivo."; }
Aquí usamos el modo de solo lectura (r) para leer el archivo. Creamos un bucle y usamos la función fgets() para leer el archivo. Mientras esta función no devuelva false leeremos línea por línea, cuando devuelva false, saldremos del bucle y, una vez más, cerraremos el archivo.
Modos de apertura
Respecto a los modos de apertura más usados, tenemos:
Modo | ¿Qué hace? |
---|---|
r (Solo lectura) | Lee el archivo situando el puntero al principio del mismo. Si el archivo no existe genera un error. |
r+ (Lectura y escritura) | Permite leer y escribir situando el puntero al principio del mismo. Si el archivo no existe genera un error. |
w (Escritura) | Sobrescribe el contenido de un archivo. Si el archivo no existe, crea uno nuevo. |
w+ (Lectura y escritura) | Permite leer y escribir. Si el archivo ya existe, sobrescribe en él, sino existe lo crea. |
a (Escritura al final) | Abre un archivo y escribe en él añadiendo el nuevo contenido al final. Si el archivo no existe lo crea. |
a+ (Lectura y escritura al final) | Abre un archivo para leer y escribir en él. Sitúa el puntero al final del archivo para añadir el nuevo contenido. Si el archivo no existe, crea uno nuevo. |
x (Creación para escritura) | Crea un archivo para escribir él. Si el archivo ya existe, dará error. |
x+ (Creación para lectura y escritura) | Crea un archivo para leer y escribir. Si el archivo ya existe, dará error. |
Puntero
Por si no lo sabes, vamos a intentar aclarar esto “del puntero”.
Como has visto en la tabla anterior, en la definición del modo, por ejemplo, en el modo ‘r’, he dicho que: “Lee el archivo situando el puntero al principio del mismo…”.
Pues bien, “el puntero” para que nos entendamos es algo así como “un marcador” o “posición” que se mueve a lo largo del archivo. El puntero nos indica dónde está ubicado el siguiente byte que se leerá o escribirá en el archivo. Es decir, es “un marcador” que indica la posición actual donde se leerá o escribirá el siguiente dato.
Cada vez que leemos o escribimos en un archivo, el puntero se sitúa al inicio o al final, dependiendo del modo de apertura. El puntero también nos permite leer o escribir solo en partes específicas de un archivo moviéndolo con funciones como fseek(), rewind()…
¿Aclarado? 😉
Funciones de fopen()
Aparte de los modos de apertura, fopen() tiene algunas funciones que son las que nos permiten tener un control total sobre el archivo.
fread(): Lee un archivo hasta el número de bytes especificado.
Suponiendo que tenemos un archivo llamado “archivo.txt” que contiene el siguiente texto:
“Contenido de prueba para probar las funciones de fopen().”
$archivo = fopen("archivo.txt", "r"); echo fread($archivo, 20); // Lee los primeros 20 bytes. fclose($archivo);
El resultado sería: “Contenido de prueba”
fgets(): Obtiene una línea desde donde se ubica el puntero. En otras palabras, lee una línea del fichero.
$archivo = fopen("archivo.txt", "r"); while (!feof($archivo)) { echo fgets($archivo); // Lee y muestra línea por línea. } fclose($archivo);
feof(): Sirve para comprobar si el puntero llegó al final del archivo.
Aquí no pongo ningún ejemplo porque ya nos sirve el ejemplo de arriba, el de la función fgets(). Mientras feof() no devuelva true, es decir, mientras el puntero no esté al final, sigue leyendo el archivo…
fclose(): Cierra el archivo y liberar los recursos.
$archivo = fopen('archivo.txt', 'r'); fclose($archivo);
fseek(): Permite mover el puntero del archivo a una posición especifica.
Siguiendo con el ejemplo del archivo que tenemos supuestamente llamado “archivo.txt” y que contiene el texto: “Contenido de prueba para probar las funciones de fopen().”
Si hacemos:
$archivo = fopen("archivo.txt", "r"); fseek($archivo, 10, SEEK_SET); // Mueve el puntero al byte 10. echo fread($archivo, 20); // Lee los siguientes 20 bytes. fclose($archivo);
El resultado será:
“de prueba para proba”
ftell(): Devuelve la posición actual del puntero del archivo.
$archivo = fopen("archivo.txt", "r"); echo ftell($archivo); // Muestra 0 al inicio. fread($archivo, 10); echo ftell($archivo); // Muestra 10 después de leer 10 bytes. fclose($archivo);
rewind(): Devuelve la posición del puntero al inicio del archivo.
Un buen ejemplo es el sacado de la documentación oficial:
$gestor = fopen('salida.txt', 'r+'); fwrite($gestor, 'Una sentencia realmente larga.'); rewind($gestor); fwrite($gestor, 'Foo'); rewind($gestor); echo fread($gestor, filesize('salida.txt')); fclose($gestor);
La salida por pantalla será: “Foo sentencia realmente larga.”
Hasta aquí hemos visto el uso de fopen() sobre archivos y las funciones disponibles, sin embargo, también podemos “abrir” direcciones web.
Abriendo URLs
Simplemente ten en cuenta dos cosas:
1º Asegúrate de tener activada la opción allow_url_fopen en el archivo php.ini. Esto es lo que permitirá que fopen() trate a las URLs como si fueran archivos.
2º Con fopen() podemos ver contenido web incluso descargarlo, pero todo de forma básica, así que si realmente te interesa mostrar contenido web y hacer “muchas cosas” 😝 es mejor y más conveniente usar bibliotecas completas y preparadas para tal fin como cURL que es más segura y flexible.
<?php // URL del contenido web $url = "https://www.oscardev.net"; // Abrir la URL en modo lectura $archivo = fopen($url, "r"); if ($archivo) { // Leer y mostrar el contenido línea por línea $linea = fgets($archivo); while ($linea !== false) { echo $linea . "<br>"; } fclose($archivo); } else { echo "No se puede leer la URL :-("; }
Una vez más repito, usar fopen() para abrir direcciones web no es recomendable. Piensa que está diseñada principalmente para trabajar con archivos locales y no puede trabajar con URLs de manera eficiente 😉
Abriendo archivos con file_get_contents()
Esta función, “al igual” que fopen(), lee un archivo o el contenido de una URL con algunas diferencias.
La primera diferencia es que esta más preparada para leer contenido web de forma eficiente y rápida. Por ejemplo, lo hace todo de una vez sin necesitar varios pasos.
La segunda diferencia, pero a la vez también, “una desventaja”, es que el contenido lo devuelve como una cadena de texto, es decir, lo almacena todo en un string. En otras palabras, carga todo el archivo en memoria con la correspondiente desventaja que esto supone.
Veamos algunos ejemplos.
Para leer un archivo local o una dirección web hacemos:
// Leer desde archivo $archivo = file_get_contents("archivo.txt"); echo $archivo; // Leer contenido de una web $contenido_web = file_get_contents("https://www.oscardev.net/sobre-mi/"); echo $contenido_web;
Nota: Al igual que fopen(), para leer desde una web, la directiva allow_url_fopen debe estar activada en el php.ini.
Como ves es mucho más sencillo, pero como dije antes, la desventaja que tiene es que, si el archivo en cuestión es muy grande, se consumirá demasiada memoria, ya que la función carga todo el contenido en una cadena.
Eso sí, si quieres simplicidad, no te preocupa la memoria, solo te interesa leer el archivo o el archivo no es muy grande, usa esta función.
Podemos leer una parte del archivo sin necesidad de usar funciones de punteros:
Siguiendo con el ejemplo del archivo.txt con el contenido: “Contenido de prueba para probar las funciones de fopen().”
Si hacemos:
$contenido = file_get_contents("archivo.txt", false, null, 0, 10); echo $contenido;
El resultado será: “Contenido”
Esto es debido a que con los dos últimos parámetros (0 y 10) le indicamos desde dónde hasta dónde ha de leer respectivamente.
Los parámetros que le podemos pasar a la función son:
- $filename: Ruta, nombre o url que se desea leer.
- $use_include_path: Si se establece a true, busca el archivo en las rutas de include_path definidas en php.ini.
¿Qué quiere decir esto?
Cuando incluimos o abrimos un archivo en PHP, PHP busca el archivo en el directorio que estemos trabajando o en la ruta que le especifiquemos, pero si establecemos $use_include_path a true, PHP buscará también automáticamente el archivo en una lista de carpetas definidas en la opción include_path del archivo php.ini.
Por ejemplo, si tienes un include_path configurado así (hablando de Windows):
include_path = “.;c:\php\includes”
y luego abres un archivo de esta manera:
$file = fopen(“archivo.txt”, “r”, true); // $use_include_path = true
PHP buscará primero archivo.txt en tu directorio actual y, si no lo encuentra, intentará buscarlo en c:\php\includes.
En defintiva, $use_include_path sirve para que PHP busque el archivo en rutas adicionales definidas en la configuración.
- $context: Permite definir un contexto para modificar el comportamiento de la función.
Es decir, nos permite configurar detalles avanzados a la hora de interactuar con archivos.
Por ejemplo, si estás trabajando con URLs, puedes usar un contexto para añadir cabeceras HTTP personalizadas. Esto se hace mediante la función stream_context_create() https://www.php.net/manual/es/function.stream-context-create.php.
Por ejemplo:
$context = stream_context_create([ "http" => [ "header" => "User-Agent: MiRobotPersonalizado/1.0" ] ]); $contenido = file_get_contents("https://oscardev.net", false, $context); echo $contenido;
Aquí, el contexto indica que PHP debe enviar la cabecera «User-Agent» al servidor.
- $offset: Posición desde donde comenzar a leer.
- $length: Número máximo de bytes a leer.
Ten en cuenta que, a excepción del nombre del archivo o URL, todos los demás parámetros son opcionales.
Como ves el uso de file_get_contents() es bastante sencillo, pero ahora mira el siguiente ejemplo:
Supón que tienes el siguiente archivo de texto llamado “otro_archivo.txt” con el siguiente contenido:
Contenido de prueba bla bla bla. Otra línea con contenido de prueba. ¡Otra línea más con maaaaaaaas contenido! Y oooooootra línea más. Y más y más. ¡No paramos! ¡Que sirva de ejemplo!
Ahora resulta que quieres leer sólo las 3 primeras líneas y para ello usas tanto la función file_get_contents() como fopen():
// Leer las primeras 3 líneas de un archivo con file_get_contents(): $contenido = file_get_contents("otro_archivo.txt"); $lineas = explode("\n", $contenido); for ($i = 0; $i < 3 && $i < count($lineas); $i++) { echo $lineas[$i] . "\n"; } // Leer las primeras 3 líneas de un archivo con fopen(): $archivo = fopen("otro_archivo.txt", "r"); $contador = 0; while (($linea = fgets($archivo)) !== false && $contador < 3) { echo $linea; $contador++; } fclose($archivo);
El resultado es el esperado, lee las 3 primeras líneas del archivo:
«Contenido de prueba bla bla bla. Otra línea con contenido de prueba. ¡Otra línea más con maaaaaaaas contenido!»
Peeeeeeeero, en este caso, fopen() es más eficiente porque no necesita cargar el archivo completo en memoria.
Ventajas y desventajas de cada función
Durante el articulo ya hemos ido viendo las ventajas y desventajas que tiene cada función. La decisión de usar una u otra, dependerá las necesidades específicas y del contexto en el que trabajamos.
Pero recordemos que:
file_get_contents(): No permite diferentes modos de apertura (solo lectura) y carga todo el archivo en memoria, sin embargo, es más simple de usar y directo, y es útil si necesitas leer el archivo completo como una cadena de texto. Si necesitas simplicidad y trabajas con archivos pequeños file_get_contents() es la mejor opción.
fopen(): Es útil para archivos grandes o más pesados y soporta diferentes modos de apertura y es más completo si lo que queremos es operar del todo sobre un archivo, como por ejemplo escribiendo o leyendo en un punto determinado. La contra es que requiere más pasos para trabajar (abrir, leer/escribir, cerrar), es decir, debemos implementar manualmente la lógica para trabajar con el contenido del archivo y cerrarlo siempre, cosa que con la otra función lo hacemos todo en una línea. Por último, aunque fopen() permite abrir URLs no es del todo eficiente y puede hacer que fopen() no funcione para algunas URLs, mientras que file_get_contents() suele ser más flexible y además, permite usar fácilmente un contexto.
Y finalmente esto sería todo sobre como abrir y trabajar con archivos en PHP. Espero como siempre que pueda resultar útil y… ¡Feliz entrada de año nuevo 2025! 🥳🎉
Sobre el autor
Este artículo está publicado bajo una licencia Creative Commons Atribución-CompartirIgual 4.0 Internacional . Puedes compartirlo y adaptarlo, incluso con fines comerciales, siempre que cites al autor y mantengas esta misma licencia.