2010-01-12 10 views
107

Ich habe versucht, den gesamten Inhalt des Verzeichnisses an einen anderen OrtKopieren gesamten Inhalt eines Verzeichnisses auf einen anderen mit PHP

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

mit kopieren, aber es sagt, dass es nicht Stream finden, true *.* nicht gefunden wird.

Jede andere Art und Weise

Dank Dave

+1

@die Redaktion: Sind Sie sicher, dass '" old_location /. "' Nur ein Tippfehler war? –

+0

@Felix: Ich habe mich das gleiche gefragt. Ich rollte zurück zur ersten Revision, aber es hat '" old_location /*.* '. Ich kann keine Revision finden, die' "old_location /." 'Enthält. – Asaph

+0

@Assaph: Dein Rollback war in Ordnung, sieh dir die Geschichte an .. Ich meinte 'copy (" old_location /. "," New_location/");' –

Antwort

191

Es scheint, dass nur Griff einzelne Dateien kopieren. Hier ist eine Funktion zum Kopieren von rekursiv ich in this note auf den copy documentation page gefunden:

<?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

Es ist ein Stern und kein Stern;) – Gordon

+1

Uups :-) Aber ich musste trotzdem bearbeiten;) –

+5

Funktioniert wie ein Charme .. Danke @FelixKling – Milap

26

copy() funktioniert nur mit Dateien.

Sowohl die DOS-Kopie als auch die Unix-cp-Befehle werden rekursiv kopiert - die schnellste Lösung besteht also nur darin, diese auszufüllen und zu verwenden. z.B.

`cp -r $src $dest`; 

Sonst wirst du die opendir/readdir oder scandir verwenden müssen, um den Inhalt des Verzeichnisses zu lesen, die Ergebnisse durchlaufen und wenn is_dir für jeden, Rekursion in sie true zurückgibt.

z.B.

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

Hier ist eine stabilere und sauberere Version von xcopy(), die den Ordner nicht erstellt, wenn es existiert: 'Funktion xcopy ($ src, $ dest) { \t foreach (scandir ($ src) als $ Datei) { \t \t $ srcfile = rtrim ($ src, '/'). '/'. $ Datei; \t \t $ destfile = rtrim ($ dest, '/'). '/'. $ Datei; \t \t if (! Is_readable ($ srcfile)) { \t \t \t fortfahren; \t \t} \t \t if ($ file! = '' && $ file! = '..') { \t \t \t if (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 Kopie ($ srcfile, $ destfile); \t \t \t} \t \t} \t} } ' – TheStoryCoder

+0

Danke für die ** Graviszeichen Lösung **! Eine Seite, die mir geholfen hat, den Kopierbefehl zu optimieren: [UNIX cp erklärt] (http://www.computerhope.com/unix/ucp.htm). Zusätzliche Informationen: PHP> = 5.3 bietet einige nette [Iteratoren] (http://de2.php.net/manual/en/class.recursivedirectoryiterator.php) – maxpower9000

7

Wie an anderer Stelle gesagt, copy nur mit einer einzigen Datei für Quelle arbeitet und kein Muster. Wenn Sie nach Muster kopieren möchten, verwenden Sie glob, um die Dateien zu ermitteln, und führen Sie anschließend copy aus. Dies wird jedoch weder Unterverzeichnisse kopieren noch das Zielverzeichnis erstellen.

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

erwägen, zu ändern: $ dest = realpath ($ dir. DIRECTORY_SEPARATOR). Basisname ($ Datei); mit: $ dest = realpath ($ dir). VERZEICHNIS_SEPARATOR. Basisname ($ Datei); – dawez

16

Die beste Lösung ist!

<?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

Funktioniert nicht auf Windows-Servern oder anderen Umgebungen, in denen Sie entweder keinen Zugriff auf 'shell_exec' oder' cp' haben. Das ist meiner Meinung nach kaum die "beste" Lösung. –

+3

Abgesehen davon können Kommandozeilen-Steuerelemente aus einer PHP-Datei ein großes Problem darstellen, wenn jemand eine Möglichkeit findet, eine Datei auf Ihrem Server zu erhalten. – Martijn

+0

Arbeitete wie ein Charme! Auf CentOS und es hat super funktioniert. Danke @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

Funktioniert perfekt! Danke bro –

5

Meine beschnittene Version von @Kzoty Antwort. Danke Kzoty.

Nutzungs

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

Als described here, dies ist ein weiterer Ansatz, der zu kümmern Symlinks nimmt:

/** 
* 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

gut kommentiert, kompakt und Plus-Funktionen ... gut! n__n – AgelessEssence

+0

Toll zum Kopieren eines Ordners mit 140 Unterordnern und jedem Unterordner mit 21 Bildern. Funktioniert super! Vielen Dank! – Darksaint2014

6

Voller Dank für seine hervorragende Antwort auf Felix Kling gehen muss, die ich dankbar in verwendet haben mein Code.Ich biete eine kleine Verbesserung einer boolean Rückgabewert Erfolg oder Misserfolg zu vermelden:

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

Sie verwenden recurse_copy() und recurseCopy() als Funktionsnamen, aktualisieren Sie sie. – AgelessEssence

+0

Der closedir ($ dir); Die Anweisung muss außerhalb der Anweisung if ($ reslut === true) liegen, d. h. einer geschweiften Klammer weiter unten. Andernfalls riskieren Sie nicht freigegebene Ressourcen. –

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

aus der letzten 4. Zeile, machen diese

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

und

$destination ='b'; 
+0

Funktioniert das nur auf Windows-Systemen? –

0

I Klonen Sie das gesamte Verzeichnis nach 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"); 
Verwandte Themen