Copiar directorios y subdirectorios de forma recursiva con PHP
Bienvenidos a VerTutoriales.com, en esta ocasión os traigo una función que parece ser que en internet hay mucho tema abierto pero ninguno concluye una función que copie realmente una carpeta exactamente como queremos, es decir, con las subcarpetas (tantas como sean) y todos su archivos, por supuesto.
Así que me puse manos a la obra, y utilizando una función lo que hago es llamar a esta tantas veces como directorios o carpetas anidadas tenga, de esta manera entrará en cada una de ellas, la creará de igual manera en la carpeta destino e irá copiando los archivos que vaya encontrando en su sitio. Vamos a ver la función y luego explico brevemente los parámetros, aunque creo que está bien claro el código.
<?
//Recojo el valor de donde copio y donde tengo que copiar
function copia($dirOrigen, $dirDestino)
{
//Creo el directorio destinomkdir($dirDestino, 0777, true);
//abro el directorio origenif ($vcarga = opendir($dirOrigen))
{
while($file = readdir($vcarga)) //lo recorro enterito
{
if ($file != “.” && $file != “..”) //quito el raiz y el padre
{
echo “<b>$file</b>”; //muestro el nombre del archivo
if (!is_dir($dirOrigen.$file)) //pregunto si no es directorio
{
if(copy($dirOrigen.$file, $dirDestino.$file)) //como no es directorio, copio de origen a destino
{
echo ” COPIADO!”;
}else{
echo ” ERROR!”;
}
}else{
echo ” — directorio — <br />”; //era directorio llamo a la función de nuevo con la nueva ubicación
copia($dirOrigen.$file.”/”, $dirDestino.$file.”/”);
}
echo “<br />”;
}
}
closedir($vcarga);
}
}$destino=”carpetanueva/”;
$origen = “privado/”;copia($origen, $destino)
?>
Bueno pues esta es la función, la llamada está clara que es copia(“directorioOrigen/”, “directorioDestino/”). La función como dije está bien comentada, pero explicando muy brevemente, lo que hacemos es recorrer el directorio actual y vamos copiando los archivos que encontremos en la carpeta destino, cuando en ese listado que recorremos encontramos una carpeta, directamente llamamos a la misma función pero con los parámetros de origen y destino actualizados con la nueva carpeta, y repetimos la operación tantas veces como carpetas tenga, una vez que termina con el directorio, sale de la función y continua por donde iba. Esto lo repetirá tantas veces como sea necesario, en las pruebas no me ha tardado en copiar un número aceptable de carpetas-archivos, así que lo dejo aquí para que lo utilceis en vuestros códigos.
Se aceptan gracias y por supuesto aportes para mejora. Hay que tener en cuenta que el directorio lo creo con todos los permisos, quizás sea necesario tener en cuenta el cambiar luego los permisos o ponerles otros. Eso cada cual.
Venga un saludo.
Comments
Excelente la rutina, realmente no hay que modificarle nada y adicionarle tampoco, cumple a cabalidad su proposito..
..Gracias por el aporte
Gracias, la verdad que no encontré ningún código que lo realizara integramente. Así que tuve que pelearme con ello, lo peor de todo es que ahroa estoy peleandome con los permisos en el servidor y creo que tendré que hacerlo finalmente con las funciones de ftp.
Un saludo!
El único problema con ese código es que si por ejemplo un fichero o directorio tiene un nombre que pueda ser evaluado como false (por ejemplo “0”) el ciclo while dejará de iterar.
Para que esto no suceda, habría que hacer algo como esto:
while(false !== ($file = readdir($vcarga)))
De manera de asegurar que el ciclo va a iterar hasta que el valor devuelto por readdir($vcarga) sea exactamente false, y no algo que pueda ser evaluado como false.
Salu2
Interesante, me gustaría saber con qué te has encontrado para llegar a tal código 🙂
Por cierto, el while tendría que quedar:
while(false != ($file = readdir($vcarga)))
Le sobraba un =
Gracias por el aporte. Un saludo!
Precisamente ese igual de mas es necesario, para obligar a que no solo sea false, si no que sea exactamente del mismo tipo. Es decir, que sea booleano.
Explicación de los operadores:
!=: Distintos resultados, independientemente de los tipos de variables.
!==: Distintos resultados, para variables del mismo tipo.
==: Resultados iguales, independientemente de los tipos de variables.
===: Resultados iguales, del mismo tipo de variable obligatoriamente.
…
Si no estuviera ese = de mas, sería equivalente al ciclo while original, ya que lo que hace el ciclo es exactamente eso, iterar mientras sea distinto de false.
Salu2.
Muy buena .. lo anduve buscando por horas esto y lo encontre gracias a ustedes .
PD : Por si a alguien le sirve revisen bien las comillas estas ( ” ) cuando copian a Dreamweaver porque en realidad son las simples como estas ( ‘ ) . Tambien otra cosa , si alguno quiere definir una variable dentro del destino ponganlo asi :
$destino=”carpeta/$variable/”;
$origen = ‘capeta/’;
si se fijan el origen esta con comillas simples y el destino con dobles . A mi me volvio loco eso pero cambiandole las comillas funciono perfectamente .
MIL GRACIAS A TODOS DESDE ARGENTINA
Gracias a tí Andrés.
Creo que el problema de las comillas, no es por las comillas simples o dobles, son por que en realidad al copiar y pegar toma otros caracteres y no los típicos “” 😀
Espero que ayuden a mucha más gente con dudas 🙂
Hola!
Excelente código, impecable!!
Solo que me quedo con una duda….
En esta parte…
if ($file != “.” && $file != “..”) //quito el raiz y el padre
A que te refieres con quitar raíz y padre?
Saludos!
Todo directorio tiene para el sistema el directorio “.” que es si mismo, por eso cuando se localiza un directorio o vas a dar una url se suele poner “./carpeta/” o “./archivo.ext” si te fijas lleva un punto delante y si nos vamos con “..” es el directorio padre, el ejemplo sería “../carpeta/” o “../archivo.ext” lo cual nos llevaría al directorio que contiene desde el que estamos llamandolo.
El hecho de quitarlos es para que no nos dé error, aparte que carecería de sentido ya que cada directorio los tiene.
Gracias
Disculpa, y si el directorio de origen ya existe??
Si el directorio existe, no lo crea 🙂
Creo recordar que sobreescribe la información que encuentre, pero prueba antes 🙂 y si puedes comentas la experiencia.
Un saludo!
Cómo podemos modificar este codigo que funciona bien, para poder copiar carpetas de un FTP a una carpeta local ?
ese codigo cuando lo copias y pegas te da un error, al principio pensaba que las llaves d’ator estaban mal cerradas pero tras comprobar que estan bien no veo el fallo
no funciona :&
¿Qué error te da? El código está en producción y como tal funcionando sin problemas, comprueba que tengas permisos de usuario en el FTP
Muy buen código, una duda, como puedo hacer que este código me copie los archivos de una carpeta de un FTP a una carpeta local??
Para ello necesitas utilizar una función de FTP como bien dices, este código utiliza solo funciones de servidor.
Un saludo!
Hola no logro hacerlo funcionar con un formulario que cree una carpeta como destino
Si quieres crear carpetas o copiar ficheros y demás, tendrás que tener permisos para ello, revisa que el usuario que estás utilizando para el script de tu PHP tenga permisos de escritura.
Un saludo!
No me funciona favor su ayuda
<?
//Recojo el valor de donde copio y donde tengo que copiar
function copia($dirOrigen, $dirDestino)
{
//Creo el directorio destino
mkdir($dirDestino, 0777, true);
//abro el directorio origen
if ($vcarga = opendir($dirOrigen))
{
while($file = readdir($vcarga)) //lo recorro enterito
{
if ($file != "." && $file != "..") //quito el raiz y el padre
{
echo "$file“;
//muestro el nombre del archivo
if (!is_dir($dirOrigen.$file)) //pregunto si no es directorio
{
if(copy($dirOrigen.$file, $dirDestino.$file)) //como no es directorio, copio de origen a destino
{
echo ” COPIADO!”;
}
else
{
echo ” ERROR!”;
}
}
else
{
echo ” — directorio — “;
//era directorio llamo a la función de nuevo con la nueva ubicación
copia($dirOrigen.$file.”/”, $dirDestino.$file.”/”);
}
echo “”;
}
}
closedir($vcarga);
}
}
$destino=”carpetaD/”;
$origen = “carpetaO/”;
copia($origen, $destino)
?>
Buenas, comprueba que tengas permisos de escritura, el código como comentaba, está en producción por lo que funciona sin problema.
Posiblemente sea problema de los permisos y para el usuario de PHP para la copia de ficheros te diga que no puede.
¿Qué error te devuelve?
Un saludo!
Buenisimo es justo lo que andaba buscando para un proyecto que estoy haciendo, gracias
Me alegro que te sirva el código en php para copiar directorios de forma recursiva jeje
Gracias por comentar!
Un saludo!
Muchas gracias!, andaba necesitando asi para un desarrollo que estoy haciendo actualmente.
Saludos!
Me alegro que te ayude el código PHP para copiar de forma recursiva ficheros y directorios!
Un saludo!
es mucho perdir pero tengo un problema mi objetivo es crear id de cuentas de logins lo que necesito es tomar 2 variables de la base de datos el id y el nombre pero quiero crear una carpeta con un php y crearlo en el directorio que yo quiero
mi codigo lo que hace es crea una carpeta despues se crea el archivo php con su nombre de una variable despues crea su contenido dentro y finaliza cerrando el archivo lo siguente es renombra la carpeta con la otra variable
pero todo eso se crea donde tengo el php y intento buscar un codigo entendible donde lea la variable de la carpeta y me lo mueva junto con su archivo php o lo que tiene la carpeta ala otra carpeta de sessions
bueno almenos quiero saber como mover la carpeta con sus archivos a otro directorio
Buenas Lider Shinobi 😉
Si quieres mover contenido puedes utilizar la shell de tu sistema, entiendo que si estás utilizando PHP estás sobre un sistema Linux, por lo que puedes utilizar la propia Shell que trae PHP para lidiar con comandos de Linux o sino la propia función copy($archivo, $nuevo_archivo) de PHP.
No sé en el punto que te encuentras, si has conseguido crear la carpeta, crear el fichero PHP escribiendo como si fuera un fichero de texto, pero guardando con extensión PHP, etc…
De todas maneras si desglosas el desarrollo podría serte más concreto 😉
Sea como sea, suerte con la programación!
buenas tardes me gustaria saber como configurar para que en la variable destino ponga una carpeta alojada en un servidor web , gracias y saludos
Lo que ise fue colocar el archivo php en el servidor pero al momento de correrlo desde el servidor , crea la carpeta destino , pero de la carpeta origen no me copia nada a la carpeta destino
carpeta origen = carpeta local
carpeta destino = carpeta remota
saludos y gracias
Si te crea la carpeta es por que no existe, sino lo que puede ocurrir es que esas rutas sigan incorrectas.
Tal y como se hace la llamada $origen = “privado/”; privado/ es la carpeta origen a copiar $destino también puedes indicar el destino en el que copiar, o desde donde copiarlo 😉