166 votes

Copier tout le contenu d'un répertoire vers un autre en utilisant php

J'ai essayé de copier l'intégralité du contenu du répertoire vers un autre emplacement en utilisant

copy ("old_location/*.*","new_location/");

mais il dit qu'il ne peut pas trouver le flux, vrai *.* n'est pas trouvé.

Tout autre moyen

Merci Dave

1 votes

Les éditeurs : Etes-vous sûr que "old_location/." était juste une faute de frappe ?

0 votes

Rich Rodecker a un script sur son blog qui semble faire exactement cela. visible-form.com/blog/copy-directory-in-php

0 votes

@Felix : Je me demandais la même chose. J'ai fait un retour en arrière à la première révision, mais il n'y a pas eu de changement. "old_location/*.* . Je ne peux pas trouver une révision contenant "old_location/." .

258voto

Felix Kling Points 247451

Cela a fonctionné pour un répertoire à un niveau. Pour un dossier avec des répertoires à plusieurs niveaux, j'ai utilisé ceci :

public function recurseCopy($src,$dst, $childFolder='') { 

    $dir = opendir($src); 
    mkdir($dst);
    if ($childFolder!='') {
        mkdir($dst.'/'.$childFolder);

        while(false !== ( $file = readdir($dir)) ) { 
            if (( $file != '.' ) && ( $file != '..' )) { 
                if ( is_dir($src . '/' . $file) ) { 
                    $this->recurseCopy($src . '/' . $file,$dst.'/'.$childFolder . '/' . $file); 
                } 
                else { 
                    copy($src . '/' . $file, $dst.'/'.$childFolder . '/' . $file); 
                }  
            } 
        }
    }else{
            // return $cc; 
        while(false !== ( $file = readdir($dir)) ) { 
            if (( $file != '.' ) && ( $file != '..' )) { 
                if ( is_dir($src . '/' . $file) ) { 
                    $this->recurseCopy($src . '/' . $file,$dst . '/' . $file); 
                } 
                else { 
                    copy($src . '/' . $file, $dst . '/' . $file); 
                }  
            } 
        } 
    }

    closedir($dir); 
}

2 votes

C'est un astérisque et non une étoile ;)

7 votes

Cela fonctionne comme un charme Merci @FelixKling

2 votes

Pourquoi @mkdir au lieu de mkdir ?

96voto

mjolnic Points 566

Como décrit ici Cette autre approche prend également en compte les liens symboliques :

/**
 * Copy a file, or recursively copy a folder and its contents
 * @author      Aidan Lister <aidan@php.net>
 * @version     1.0.1
 * @link        http://aidanlister.com/2004/04/recursively-copying-directories-in-php/
 * @param       string   $source    Source path
 * @param       string   $dest      Destination path
 * @param       int      $permissions New folder creation permissions
 * @return      bool     Returns true on success, false on failure
 */
function xcopy($source, $dest, $permissions = 0755)
{
    $sourceHash = hashDirectory($source);
    // Check for symlinks
    if (is_link($source)) {
        return symlink(readlink($source), $dest);
    }

    // Simple copy for a file
    if (is_file($source)) {
        return copy($source, $dest);
    }

    // Make destination directory
    if (!is_dir($dest)) {
        mkdir($dest, $permissions);
    }

    // Loop through the folder
    $dir = dir($source);
    while (false !== $entry = $dir->read()) {
        // Skip pointers
        if ($entry == '.' || $entry == '..') {
            continue;
        }

        // Deep copy directories
        if($sourceHash != hashDirectory($source."/".$entry)){
             xcopy("$source/$entry", "$dest/$entry", $permissions);
        }
    }

    // Clean up
    $dir->close();
    return true;
}

// In case of coping a directory inside itself, there is a need to hash check the directory otherwise and infinite loop of coping is generated

function hashDirectory($directory){
    if (! is_dir($directory)){ return false; }

    $files = array();
    $dir = dir($directory);

    while (false !== ($file = $dir->read())){
        if ($file != '.' and $file != '..') {
            if (is_dir($directory . '/' . $file)) { $files[] = hashDirectory($directory . '/' . $file); }
            else { $files[] = md5_file($directory . '/' . $file); }
        }
    }

    $dir->close();

    return md5(implode('', $files));
}

0 votes

Cela a bien fonctionné pour copier un dossier contenant 140 sous-dossiers et chaque sous-dossier contenant 21 images. Cela fonctionne très bien ! Merci !

2 votes

mkdir devrait être ajouté true comme dernier paramètre pour supporter le répertoire récursif alors ce script est parfait

0 votes

Cela copie le dossier entier ? Et si vous ne voulez copier que les fichiers à l'intérieur de le dossier, sans le dossier parent, comme le dit la question : copy ("old_location/*.*","new_location/"); Est-ce que ça marche ? Et si vous avez des fichiers par points, seront-ils appariés ?

41voto

symcbean Points 27412

Copy() ne fonctionne qu'avec des fichiers.

Les commandes DOS copy et Unix cp copieront de manière récursive - la solution la plus rapide est donc de lancer un shell et de les utiliser, par exemple

`cp -r $src $dest`;

Sinon, vous devrez utiliser l'option opendir / readdir o scandir pour lire le contenu du répertoire, itérer à travers les résultats et si is_dir retourne vrai pour chacun d'entre eux, faire une récursion dans le répertoire.

par exemple

function xcopy($src, $dest) {
    foreach (scandir($src) as $file) {
        if (!is_readable($src . '/' . $file)) continue;
        if (is_dir($src .'/' . $file) && ($file != '.') && ($file != '..') ) {
            mkdir($dest . '/' . $file);
            xcopy($src . '/' . $file, $dest . '/' . $file);
        } else {
            copy($src . '/' . $file, $dest . '/' . $file);
        }
    }
}

5 votes

Voici une version plus stable et plus propre de xcopy() qui ne crée pas le dossier s'il existe : function xcopy($src, $dest) { foreach (scandir($src) as $file) { $srcfile = rtrim($src, '/') .'/'. $file; $destfile = rtrim($dest, '/') .'/'. $file; if (!is_readable($srcfile)) { continue; } if ($file != '.' && $file != '..') { if (is_dir($srcfile)) { if (!file_exists($destfile)) { mkdir($destfile); } xcopy($srcfile, $destfile); } else { copy($srcfile, $destfile); } } } }

0 votes

Merci pour le solution backtick ! Une page qui m'a aidé à peaufiner la commande de copie : UNIX cp expliqué . Informations supplémentaires : PHP >=5.3 offre de belles itérateurs

16voto

kzoty Points 71
function full_copy( $source, $target ) {
    if ( is_dir( $source ) ) {
        @mkdir( $target );
        $d = dir( $source );
        while ( FALSE !== ( $entry = $d->read() ) ) {
            if ( $entry == '.' || $entry == '..' ) {
                continue;
            }
            $Entry = $source . '/' . $entry; 
            if ( is_dir( $Entry ) ) {
                full_copy( $Entry, $target . '/' . $entry );
                continue;
            }
            copy( $Entry, $target . '/' . $entry );
        }

        $d->close();
    }else {
        copy( $source, $target );
    }
}

0 votes

Fonctionne parfaitement ! Merci frère

7voto

Hemanta Nandi Points 81
<?php
    function copy_directory( $source, $destination ) {
        if ( is_dir( $source ) ) {
        @mkdir( $destination );
        $directory = dir( $source );
        while ( FALSE !== ( $readdirectory = $directory->read() ) ) {
            if ( $readdirectory == '.' || $readdirectory == '..' ) {
                continue;
            }
            $PathDir = $source . '/' . $readdirectory; 
            if ( is_dir( $PathDir ) ) {
                copy_directory( $PathDir, $destination . '/' . $readdirectory );
                continue;
            }
            copy( $PathDir, $destination . '/' . $readdirectory );
        }

        $directory->close();
        }else {
        copy( $source, $destination );
        }
    }
?>

à partir de la dernière 4ème ligne, faites ceci

$source = 'wordpress';//i.e. your source path

y

$destination ='b';

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X