@ Felix: Eu estava pensando a mesma coisa. Voltei para a primeira revisão, mas ela tem "old_location/*.*. Não consigo encontrar uma revisão contendo "old_location/.".
Asaph
@Asaph: Seu reversão foi ok, olhar para a história ... eu quis dizercopy ("old_location/.","new_location/");
Felix Kling
3
@dave Quando você receberá um :) aceito?
Nam G VU
Respostas:
239
Parece que a cópia única lidar com arquivos individuais . Aqui está uma função para copiar recursivamente que encontrei nesta nota na página de documentação da cópia :
@ Oliboy50: Você pode perguntar à pessoa que escreveu o código há 5 anos: php.net/manual/en/function.copy.php#91010 . Talvez fosse mais popular na época suprimir mensagens de erro.
Funcionou muito bem para copiar uma pasta com 140 subpastas e cada subpasta contendo 21 imagens. Funciona bem! Obrigado!
precisa saber é o seguinte
1
mkdirdeve ser adicionado truecomo o último parâmetro para apoiar diretório de forma recursiva, em seguida, esse script é perfeito
CénitS
Isso copia a pasta inteira? E se você quiser apenas copiar os arquivos dentro da pasta, sem a pasta pai, como a pergunta diz: copy ("old_location/*.*","new_location/");Isso funciona? E se você tiver arquivos de ponto, eles serão correspondidos?
XCS
35
copy () funciona apenas com arquivos.
Os comandos DOS copy e Unix cp serão copiados recursivamente - portanto, a solução mais rápida é apenas descartar e usá-los. por exemplo
`cp -r $src $dest`;
Caso contrário, você precisará usar o opendir/ readdirou scandirpara ler o conteúdo do diretório, percorrer os resultados e se is_dir retornar true para cada um, recursá-lo.
Aqui está uma versão mais estável e mais limpa do xcopy () que não cria a pasta, se existir: 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); } } } }
TheStoryCoder
Obrigado pela solução backtick ! Uma página que me ajudou a ajustar o comando copy: o UNIX cp explicou . Informações adicionais: PHP> = 5.3 oferece algumas agradáveis iteradores
Não funcionará em servidores Windows ou em outros ambientes nos quais você não tem acesso shell_execou cp. Isso torna - na minha opinião - dificilmente a "melhor" solução.
The Pellmeister
3
Além disso, os controles da linha de comando de um arquivo PHP podem ser um grande problema quando alguém encontra uma maneira de obter um arquivo no seu servidor.
287
Trabalhou como um encanto! No CentOS e funcionou muito bem. Obrigado @bstpierre
Nick Green
1
Isso não funcionará no Windows, porque cpé um comando do Linux. Para o uso do Windows xcopy dir1 dir2 /e /i, onde /eestá para a cópia diretórios vazios e /ipara ignorar perguntas sobre arquivos ou diretórios
Michel
Sim, é a melhor solução se o servidor suportar esse comando e você tiver as permissões necessárias. É muito rápido. Infelizmente não está funcionando em todos os ambientes.
Como dito em outro lugar, copysó funciona com um único arquivo de origem e não com um padrão. Se você deseja copiar por padrão, use globpara determinar os arquivos e execute a cópia. Porém, isso não copiará subdiretórios, nem criará o diretório de destino.
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
considere alterar: $ dest = caminho real ($ dir. DIRECTORY_SEPARATOR). nome de base (arquivo $); com: $ dest = caminho real ($ dir). DIRECTORY_SEPARATOR. nome de base (arquivo $);
Devo agradecer a Felix Kling por sua excelente resposta, que usei com gratidão no meu código. Ofereço um pequeno aprimoramento de um valor de retorno booleano para relatar sucesso ou falha:
você está usando recurse_copy () e recurseCopy () como nomes de função, atualize-o.
AgelessEssence
O closedir ($ dir); A instrução precisa estar fora da instrução if ($ reslut === true), ou seja, uma chave mais abaixo. Caso contrário, você corre o risco de ter recursos não liberados.
Minha versão podada da resposta @Kzoty. Obrigado Kzoty.
Uso
Helper::copy($sourcePath, $targetPath);classHelper{staticfunction 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();}}
Eu tive uma situação semelhante em que precisava copiar de um domínio para outro no mesmo servidor. Aqui está exatamente o que funcionou no meu caso, você também pode ajustar para se adequar ao seu:
Observe o uso de "substr ()", sem ele, o destino se torna '/home/user/abcde.com/../folder/', que pode ser algo que você não deseja. Então, usei substr () para eliminar os três primeiros caracteres (../) para obter o destino desejado que é '/home/user/abcde.com/folder/'. Assim, você pode ajustar a função substr () e também a função glob () até que ela atenda às suas necessidades pessoais. Espero que isto ajude.
"old_location/."
foi apenas um erro de digitação?"old_location/*.*
. Não consigo encontrar uma revisão contendo"old_location/."
.copy ("old_location/.","new_location/");
Respostas:
Parece que a cópia única lidar com arquivos individuais . Aqui está uma função para copiar recursivamente que encontrei nesta nota na página de documentação da cópia :
fonte
@mkdir
invés demkdir
?Conforme descrito aqui , essa é outra abordagem que também cuida dos links simbólicos:
fonte
mkdir
deve ser adicionadotrue
como o último parâmetro para apoiar diretório de forma recursiva, em seguida, esse script é perfeitocopy ("old_location/*.*","new_location/");
Isso funciona? E se você tiver arquivos de ponto, eles serão correspondidos?copy () funciona apenas com arquivos.
Os comandos DOS copy e Unix cp serão copiados recursivamente - portanto, a solução mais rápida é apenas descartar e usá-los. por exemplo
Caso contrário, você precisará usar o
opendir
/readdir
ouscandir
para ler o conteúdo do diretório, percorrer os resultados e se is_dir retornar true para cada um, recursá-lo.por exemplo
fonte
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); } } } }
A melhor solução é!
fonte
shell_exec
oucp
. Isso torna - na minha opinião - dificilmente a "melhor" solução.cp
é um comando do Linux. Para o uso do Windowsxcopy dir1 dir2 /e /i
, onde/e
está para a cópia diretórios vazios e/i
para ignorar perguntas sobre arquivos ou diretóriosfonte
Como dito em outro lugar,
copy
só funciona com um único arquivo de origem e não com um padrão. Se você deseja copiar por padrão, useglob
para determinar os arquivos e execute a cópia. Porém, isso não copiará subdiretórios, nem criará o diretório de destino.fonte
da última quarta linha, faça isso
e
fonte
Devo agradecer a Felix Kling por sua excelente resposta, que usei com gratidão no meu código. Ofereço um pequeno aprimoramento de um valor de retorno booleano para relatar sucesso ou falha:
fonte
Com o Symfony, isso é muito fácil de realizar:
Consulte https://symfony.com/doc/current/components/filesystem.html
fonte
Minha versão podada da resposta @Kzoty. Obrigado Kzoty.
Uso
fonte
Eu clono o diretório inteiro pelo SPL Directory Iterator.
fonte
fonte
Para servidores Linux, você só precisa de uma linha de código para copiar recursivamente, preservando a permissão:
Outra maneira de fazer isso é:
mas é mais lento e não preserva permissões.
fonte
Eu tive uma situação semelhante em que precisava copiar de um domínio para outro no mesmo servidor. Aqui está exatamente o que funcionou no meu caso, você também pode ajustar para se adequar ao seu:
Observe o uso de "substr ()", sem ele, o destino se torna '/home/user/abcde.com/../folder/', que pode ser algo que você não deseja. Então, usei substr () para eliminar os três primeiros caracteres (../) para obter o destino desejado que é '/home/user/abcde.com/folder/'. Assim, você pode ajustar a função substr () e também a função glob () até que ela atenda às suas necessidades pessoais. Espero que isto ajude.
fonte