Introducción
Es muy común en PHP trabajar con archivos o ficheros. Hay ocasiones en las que vamos a necesitar mover, copiar, renombrar, crear o eliminar un archivo o directorio.
Hoy veremos cómo realizar todas estas operaciones desde PHP.
Crear archivo vacío
Si sólo queremos crear un archivo, sin escribirle contenido, usamos touch:
<?php
$nombre_archivo = "1.txt";
$resultado = touch(__DIR__ . "/$nombre_archivo");
if ($resultado) {
echo "El archivo $nombre_archivo se ha creado :)";
} else {
echo "Error creando archivo";
}
Esta función regresa true o false dependiendo del éxito de la operación. Notar por favor que concatenamos con __DIR__ para darle a touch la ruta absoluta del fichero.
Por cierto, en este caso fue un archivo .txt pero podríamos hacerlo con cualquier tipo de archivo. También podríamos modificar el momento de acceso y última modificación del archivo, pero eso es tema para otro post. Aquí la documentación oficial.
Crear archivo de texto y escribirle contenido
Anteriormente sólo “tocamos” un archivo. Ahora veamos cómo escribirle texto a un archivo txt.
<?php
$nombre_archivo = "2.txt";
$contenido = "Hola, mundo. Soy el contenido del archivo :)";
$resultado = file_put_contents(__DIR__ . "/$nombre_archivo", $contenido);
if ($resultado === FALSE) {
echo "Error escribiendo contenido";
} else {
echo "Correcto. Se han escrito $resultado bytes :)";
}
Así es como escribimos contenido en un archivo de texto. Si el archivo no existe, será creado.
La función file_put_contents devuelve un entero, o false. False en caso de que la operación no haya sido completada correctamente, o un entero representando los bytes escritos en caso contrario.
Por cierto, esta función va a sobrescribir el contenido del archivo, no lo adjuntará. Sigamos leyendo para ver cómo hacer que adjunte y no remplace el contenido.
Crear archivo de texto y adjuntar contenido
Utilizamos de nuevo a file_put_contents pero ahora le pasamos una bandera para que adjunte el contenido. Así:
<?php
$nombre_archivo = "3.txt";
$contenido = "Hola, mundo. Soy el contenido del archivo :)" . PHP_EOL; #Escribir con salto de línea
$resultado = file_put_contents(__DIR__ . "/$nombre_archivo", $contenido, FILE_APPEND);
if ($resultado === FALSE) {
echo "Error escribiendo contenido";
} else {
echo "Correcto. Se han escrito o adjuntado $resultado bytes :)";
}
Veamos que como tercer argumento pasamos la bandera FILE_APPEND que indica a file_put_contents que adjunte el contenido.
También cambiamos el contenido, agregándole un salto de línea. Así, si ejecutamos el script muchas veces y abrimos el archivo de texto, se verán líneas separadas.
Crear directorio o carpeta
Veamos cómo crear una carpeta o directorio en PHP. Ahora utilizamos la función mkdir que recibe como primer argumento la ruta de la carpeta que se va a crear, así como el modo y un booleano indicando si será recursiva o no.
Aquí sólo veremos cómo crear un directorio, pero podemos profundizar en la documentación oficial.
<?php
$nombre_directorio = "fotos";
$resultado = mkdir(__DIR__ . "/$nombre_directorio");
if ($resultado) {
echo "Se ha creado el directorio $nombre_directorio";
} else {
echo "Error creando directorio";
}
Mkdir regresa un booleano indicando el éxito o fracaso.
Copiar archivo
Si queremos crear una copia de un archivo en otro directorio, usamos copy y le pasamos el origen y el destino. Así:
<?php
#Copiar 3.txt en el directorio fotos
$origen = __DIR__ . "/3.txt";
$destino = __DIR__ . "/fotos/3.txt";
$resultado = copy($origen, $destino);
if ($resultado) {
echo "Se ha copiado $origen a $destino";
} else {
echo "Error copiando $origen a $destino";
}
Igualmente podríamos crear una copia (para respaldar, por ejemplo) en el mismo directorio, de esta manera:
<?php
$origen = __DIR__ . "/3.txt";
$destino = __DIR__ . "/3_copia.txt"; #Copiar pero cambiar nombre
$resultado = copy($origen, $destino);
if ($resultado) {
echo "Se ha copiado $origen a $destino";
} else {
echo "Error copiando $origen a $destino";
}
Como vemos, copy devuelve un booleano indicando el éxito de la operación.
Mover archivo
Si queremos cortar o mover un archivo a otra ubicación utilizamos rename. Básicamente lo que hacemos cuando movemos un archivo es renombrarlo; de ahí que la función se llame de esa manera.
Este ejemplo mueve el archivo 2.txt a fotos/2.txt
<?php
$origen = __DIR__ . "/2.txt";
$destino = __DIR__ . "/fotos/2.txt"; #Mover a fotos/2.txt
$resultado = rename($origen, $destino);
if ($resultado) {
echo "Se ha movido $origen a $destino";
} else {
echo "Error moviendo $origen a $destino";
}
Con esto cambiamos de lugar a 2.txt
Renombrar
Utilizamos la misma función para cambiar el nombre de un archivo. En este caso renombramos 1.txt a 1.log:
<?php
$antiguo_nombre = __DIR__ . "/1.txt";
$nuevo_nombre = __DIR__ . "/1.log";
$resultado = rename($antiguo_nombre, $nuevo_nombre);
if ($resultado) {
echo "Se ha renombrado $antiguo_nombre a $nuevo_nombre";
} else {
echo "Error renombrando $antiguo_nombre a $nuevo_nombre";
}
Eliminar archivo
Si queremos eliminar un archivo (no un directorio) utilizamos unlink, así:
<?php
$archivo = __DIR__ . "/1.txt";
$resultado = unlink($archivo);
if ($resultado) {
echo "Se ha eliminado $archivo";
} else {
echo "Error eliminando $archivo";
}
Notar por favor que esto elimina un archivo, pero no un directorio.
Eliminar directorio
Ahora veamos cómo eliminar un directorio, folder o carpeta. Para ello ahora usamos rmdir. El directorio en cuestión debe estar vacío, si no, no podremos eliminarlo.
<?php
$directorio = __DIR__ . "/fotos";
$resultado = rmdir($directorio);
if ($resultado) {
echo "Se ha eliminado $directorio";
} else {
echo "Error eliminando $directorio";
}
Si el directorio no está vacío, se generará un error que dice Directory not empty.
Esto es porque el directorio tiene contenido; si queremos eliminarlo completamente primero debemos vaciarlo; es decir, eliminar archivos y ficheros dentro de ese folder.
Eliminar directorio y contenidos recursivamente
En caso de que deseemos eliminar un directorio recursivamente (o sea, borrarlo junto con su contenido) podemos usar el siguiente código:
<?php
function eliminar_directorio_recursivamente($ruta)
{
if (is_dir($ruta)) {
#Obtener un arreglo con directorios y archivos
$subdirectorios_o_archivos = scandir($ruta);
foreach ($subdirectorios_o_archivos as $subdirectorio_o_archivo) {
# Omitir . y .., pues son directorios
# que se refieren al directorio actual
# o al directorio padre
if ($subdirectorio_o_archivo != "." && $subdirectorio_o_archivo != "..") {
# Si es un directorio, recursión
if (is_dir($ruta . "/" . $subdirectorio_o_archivo)) {
eliminar_directorio_recursivamente($ruta . "/" . $subdirectorio_o_archivo);
} else {
# Si es un archivo, lo eliminamos con unlink
unlink($ruta . "/" . $subdirectorio_o_archivo);
}
}
}
# Al final de todo, el directorio estará vacío
# y podremos usar rmdir
rmdir($ruta);
}
}
$ruta_directorio = __DIR__ . "/fotos";
eliminar_directorio_recursivamente($ruta_directorio);
Como se puede observar, en ese caso se elimina al directorio fotos con todo su contenido. Hay que ser cuidadosos con esta función.
Por cierto, el código sólo fue traducido y explicado por mí, aunque yo no soy el autor. El original está aquí.
Comprobar si directorio o archivo existe
En los ejemplos de arriba copiamos, movimos e hicimos todas las operaciones sin comprobar primero si el archivo, fichero o directorio en cuestión existían.
Cuando desarrollemos apps de la vida real, debemos manejar todos esos errores. En este caso, si queremos comprobar si el directorio o fichero existe usamos file_exists.
Otras funciones que vienen de gran ayuda son is_dir para comprobar si una ruta es un directorio, así como is_file que hace lo mismo pero para un archivo.