2010-01-12 24 views
107

ho cercato di copiare l'intero contenuto della cartella in un'altra posizione utilizzandoCopiare intero contenuto di una directory ad un'altra usando php

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

ma dice che non riesce a trovare torrente, vero *.* non si trova.

Qualsiasi altro modo

Grazie Dave

+1

@the editor: sei sicuro che '" old_location /. "' Era solo un refuso? –

+0

@Felix: Mi stavo chiedendo la stessa cosa. Sono tornato alla prima revisione ma ha '" posizione_rossa /*.* '. Non riesco a trovare una revisione che contenga' "posizione_variabile /." '. – Asaph

+0

@Asaf: il tuo rollback era ok, guarda la storia .. Intendevo 'copia (" old_location /. "," Nuova_location/");' –

risposta

191

Sembra che copia solo manico singoli file. Ecco una funzione per copiare in modo ricorsivo ho trovato in this note sul copy documentation page:

<?php 
function recurse_copy($src,$dst) { 
    $dir = opendir($src); 
    @mkdir($dst); 
    while(false !== ($file = readdir($dir))) { 
     if (($file != '.') && ($file != '..')) { 
      if (is_dir($src . '/' . $file)) { 
       recurse_copy($src . '/' . $file,$dst . '/' . $file); 
      } 
      else { 
       copy($src . '/' . $file,$dst . '/' . $file); 
      } 
     } 
    } 
    closedir($dir); 
} 
?> 
+2

È un asterisco e non una stella;) – Gordon

+1

Uups :-) Ma dovevo comunque modificarlo;) –

+5

Funziona come un incantesimo .. Grazie @FelixKling – Milap

26

copy() funziona solo con i file.

Entrambi i comandi cp di copia DOS e Unix verranno copiati in modo ricorsivo, quindi la soluzione più rapida è solo quella di utilizzarli. per esempio.

`cp -r $src $dest`; 

In caso contrario sarà necessario utilizzare il opendir/readdir o scandir di leggere il contenuto della directory, scorrere i risultati e se is_dir Restituisce vero per ciascuno di essi, ricorsione in esso.

ad es.

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); 
     } 
    } 
} 
+1

Ecco una versione più stabile e pulita di xcopy() che non crea la cartella se esiste: 'function xcopy ($ src, $ dest) { \t foreach (scandir ($ src) come $ file) { \t \t $ srcfile = rtrim ($ src, '/'). '/'. $ File; \t \t $ destfile = rtrim ($ dest, '/'). '/'. $ File; \t \t if (! Is_readable ($ srcfile)) { \t \t \t continua; \t \t} \t \t if ($ file! = '' && $ file! = '..') { \t \t \t se (is_dir ($ SRCFILE)) { \t \t \t \t if (!file_exists ($ destfile)) { \t \t \t \t \t mkdir ($ destfile); \t \t \t \t} \t \t \t \t xcopy ($ SRCFILE, $ destfile); \t \t \t} else { \t \t \t \t copia ($ SRCFILE, $ destfile); \t \t \t} \t \t} \t}} ' – TheStoryCoder

+0

Grazie per la soluzione backtick ** **! Una pagina che mi ha aiutato a modificare il comando di copia: [UNIX cp spiegato] (http://www.computerhope.com/unix/ucp.htm). Informazioni aggiuntive: PHP> = 5.3 offre alcuni simpatici [iteratori] (http://de2.php.net/manual/en/class.recursivedirectoryiterator.php) – maxpower9000

7

Come detto altrove, copy funziona solo con un singolo file per la fonte e non un modello. Se si desidera copiare per modello, utilizzare glob per determinare i file, quindi eseguire la copia. Questo però non copierà le sottodirectory, né creerà la directory di destinazione.

function copyToDir($pattern, $dir) 
{ 
    foreach (glob($pattern) as $file) { 
     if(!is_dir($file) && is_readable($file)) { 
      $dest = realpath($dir . DIRECTORY_SEPARATOR) . basename($file); 
      copy($file, $dest); 
     } 
    }  
} 
copyToDir('./test/foo/*.txt', './test/bar'); // copies all txt files 
+0

considera la modifica: $ dest = realpath ($ dir. DIRECTORY_SEPARATOR). basename ($ file); con: $ dest = realpath ($ dir). DIRECTORY_SEPARATOR. basename ($ file); – dawez

16

La soluzione migliore è!

<?php 
$src = "/home/www/domain-name.com/source/folders/123456"; 
$dest = "/home/www/domain-name.com/test/123456"; 

shell_exec("cp -r $src $dest"); 

echo "<H3>Copy Paste completed!</H3>"; //output when done 
?> 
+28

Non funziona su server Windows o altri ambienti in cui non si ha accesso a 'shell_exec' o' cp'. Questo rende - a mio parere - difficilmente la soluzione "migliore". –

+3

Oltre a ciò, i controlli da riga di comando da un file PHP possono essere un grosso problema quando qualcuno trova un modo per ottenere un file sul server. – Martijn

+0

Ha funzionato come un fascino! Su CentOS ha funzionato alla grande. Grazie @bstpierre –

12
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

funziona perfettamente! Grazie fratello –

5

La mia versione di potati @Kzoty risposta. Grazie Kzoty.

Uso

Helper::copy($sourcePath, $targetPath); 

class Helper { 

    static function copy($source, $target) { 
     if (!is_dir($source)) {//it is a file, do a normal copy 
      copy($source, $target); 
      return; 
     } 

     //it is a folder, copy its files & sub-folders 
     @mkdir($target); 
     $d = dir($source); 
     $navFolders = array('.', '..'); 
     while (false !== ($fileEntry=$d->read())) {//copy one by one 
      //skip if it is navigation folder . or .. 
      if (in_array($fileEntry, $navFolders)) { 
       continue; 
      } 

      //do copy 
      $s = "$source/$fileEntry"; 
      $t = "$target/$fileEntry"; 
      self::copy($s, $t); 
     } 
     $d->close(); 
    } 

} 
74

Come described here, questo è un altro approccio che si prende cura dei link simbolici troppo:

/** 
* Copy a file, or recursively copy a folder and its contents 
* @author  Aidan Lister <[email protected]> 
* @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) 
{ 
    // 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 
     xcopy("$source/$entry", "$dest/$entry", $permissions); 
    } 

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

ben commentato, compatto e funzioni aggiuntive ... buono !! n__n – AgelessEssence

+0

Funzionava benissimo per copiare una cartella con 140 sottocartelle e ogni sottocartella contenente 21 immagini. Funziona alla grande! Grazie! – Darksaint2014

6

grazie completo deve andare a Felix Kling per la sua risposta eccellente che ho con gratitudine usato in il mio codiceOffro un piccolo aumento di un valore di ritorno booleano segnalare il successo o il fallimento:

function recurse_copy($src, $dst) { 

    $dir = opendir($src); 
    $result = ($dir === false ? false : true); 

    if ($result !== false) { 
    $result = @mkdir($dst); 

    if ($result === true) { 
     while(false !== ($file = readdir($dir))) { 
     if (($file != '.') && ($file != '..') && $result) { 
      if (is_dir($src . '/' . $file)) { 
      $result = recurse_copy($src . '/' . $file,$dst . '/' . $file); 
      }  else { 
      $result = copy($src . '/' . $file,$dst . '/' . $file); 
      } 
     } 
     } 
     closedir($dir); 
    } 
    } 

    return $result; 
} 
+1

stai utilizzando recurse_copy() e recurseCopy() come nomi di funzioni, aggiornalo. – AgelessEssence

+0

Il closedir ($ dir); la dichiarazione deve essere al di fuori dell'istruzione if ($ reslut === true), cioè una parentesi graffa più in basso. Altrimenti rischi di avere risorse non liberate. –

8
<?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); 
     } 
    } 
?> 

dall'ultima linea 4, fanno di questo

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

e

$destination ='b'; 
+0

Funziona solo su sistemi Windows? –

0

I clona l'intera directory tramite SPL Directory Iterator.

function recursiveCopy($source, $destination) 
{ 
    if (!file_exists($destination)) { 
     mkdir($destination); 
    } 

    $splFileInfoArr = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($source), RecursiveIteratorIterator::SELF_FIRST); 

    foreach ($splFileInfoArr as $fullPath => $splFileinfo) { 
     //skip . .. 
     if (in_array($splFileinfo->getBasename(), [".", ".."])) { 
      continue; 
     } 
     //get relative path of source file or folder 
     $path = str_replace($source, "", $splFileinfo->getPathname()); 

     if ($splFileinfo->isDir()) { 
      mkdir($destination . "/" . $path); 
     } else { 
     copy($fullPath, $destination . "/" . $path); 
     } 
    } 
} 
#calling the function 
recursiveCopy(__DIR__ . "/source", __DIR__ . "/destination"); 
Problemi correlati