J'ai essayé de copier tout le contenu du répertoire dans un autre emplacement en utilisant
copy ("old_location/*.*","new_location/");
mais il dit qu'il ne peut pas trouver le flux, true *.*
n'est pas trouvé.
Tout autre moyen
Merci Dave
Il semble que copier seulement traite fichiers uniques. Voici une fonction de copie récursive que j'ai trouvée dans cette note sur la page de documentation de copie :
<?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);
}
?>
Comme décrit ici , c'est une autre approche qui prend également en charge les liens symboliques:
/**
* 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;
}
copy () ne fonctionne qu'avec des fichiers.
La copie DOS et les commandes Unix cp seront toutes deux copiées de manière récursive. La solution la plus rapide consiste donc simplement à utiliser Shell. par exemple.
`cp -r $src $dest`;
Sinon, vous devrez utiliser la variable opendir
/readdir
ou scandir
pour lire le contenu du répertoire, parcourir les résultats et si is_dir renvoie la valeur true pour chacun d'eux, effectuez une récurrence dans celui-ci.
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);
}
}
}
La meilleure solution est!
<?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
?>
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 );
}
}
<?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 4ème ligne, faites ceci
$source = 'wordpress';//i.e. your source path
et
$destination ='b';
Comme indiqué ailleurs, copy
ne fonctionne qu'avec un seul fichier pour la source et non un modèle. Si vous souhaitez copier par modèle, utilisez glob
pour déterminer les fichiers, puis exécutez la copie. Cela ne copie pas les sous-répertoires et ne crée pas le répertoire de destination.
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
Merci à Felix Kling pour son excellente réponse que j’ai utilisée avec reconnaissance dans mon code. J'offre une petite amélioration d'une valeur de retour booléenne pour signaler un succès ou un échec:
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;
}
Ma version taillée de @Kzoty répond ..__ Merci Kzoty.
Usage
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();
}
}
Avec Symfony, cela est très facile à accomplir:
$fileSystem = new Symfony\Component\Filesystem\Filesystem();
$fileSystem->mirror($from, $to);
Voir https://symfony.com/doc/current/components/filesystem.html
Je clone tout le répertoire par 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");
Pour les serveurs Linux, vous n'avez besoin que d'une ligne de code pour copier de manière récursive tout en préservant les droits:
exec('cp -a '.$source.' '.$dest);
Une autre façon de le faire est:
mkdir($dest);
foreach ($iterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($source, \RecursiveDirectoryIterator::SKIP_DOTS), \RecursiveIteratorIterator::SELF_FIRST) as $item)
{
if ($item->isDir())
mkdir($dest.DIRECTORY_SEPARATOR.$iterator->getSubPathName());
else
copy($item, $dest.DIRECTORY_SEPARATOR.$iterator->getSubPathName());
}
mais c'est plus lent et ne conserve pas les autorisations.
// using exec
function rCopy($directory, $destination)
{
$command = sprintf('cp -r %s/* %s', $directory, $destination);
exec($command);
}