For copying a folder and a file in php i use this loop:
if(is_dir($_POST['copyfile'])) {
$copyfolder = recurse_copy($src_folder,$dest_folder);
if( $copyfolder) {
echo 'succeed-folder';
exit;
}
else {
echo 'failed-folder';
exit;
}
}
else {
$copy = copy( $src_file_url, $dest_file );
if($copy) {
echo 'succeed-file';
exit;
}
else {
echo 'failed-file';
exit;
}
}
When copying a folder instead of a file, i check it with: if(is_dir($_POST['copyfile']))
In the case that it is really a folder, it copies the files in the folder correctly but gives me this echo: failed-folder
So there must be something wrong with the loop. What is wrong with the loop? I only want to distinguish if a folder or a file was copied with an echo
This is the function:
function recurse_copy($src_folder,$dest_folder ) {
$copydir = opendir($src_folder);
while(false !== ( $folder = readdir($copydir)) ) {
if (( $folder != '.' ) && ( $folder != '..' )) {
if ( is_dir($src_folder . '/' . $folder) ) {
recurse_copy($src_folder. '/' . $folder,$dest_folder . '/' . $folder);
}
else {
copy($src_folder. '/' . $folder , $dest_folder . '/' . $folder);
}
}
}
closedir($copydir);
}
You do not have a return statement at all. Therefore the function returns "void" which is evaluated to false. You need to return a bool value indicating if an error occurred.
This version does not stop the copy process, it just tracks if all operations were successful:
function recurse_copy($src_folder,$dest_folder ) {
$success = true;
$copydir = opendir($src_folder);
if(!$copydir)
return false;
while(false !== ( $folder = readdir($copydir)) ) {
if (( $folder != '.' ) && ( $folder != '..' )) {
if ( is_dir($src_folder . '/' . $folder) ) {
$success = recurse_copy($src_folder. '/' . $folder,$dest_folder . '/' . $folder) && $success;
}
else {
$success = copy($src_folder. '/' . $folder , $dest_folder . '/' . $folder) && $success;
}
}
}
closedir($copydir);
return $success;
}
An example of how you could alter the recurse_copy() function is to test each point which can be a problem - opendir(), mkdir() and copy() and they return false if any step fails. So this value is checked to stop the loop on failure and then returned at the end...
function recurse_copy($src,$dst) {
$dir = opendir($src);
// As long as opendir is OK, then mkdir, or set failure
$success = ($dir)?mkdir($dst):false;
while($success && (false !== ( $file = readdir($dir))) ) {
if (( $file != '.' ) && ( $file != '..' )) {
if ( is_dir($src . '/' . $file) ) {
$success = recurse_copy($src . '/' . $file,$dst . '/' . $file);
}
else {
$success = copy($src . '/' . $file,$dst . '/' . $file);
}
}
}
if ( $dir ) {
closedir($dir);
}
return $success;
}
I am writing a function to recursively copy a specific file type from one folder to the other, but the function copies all the files in the folder.
function recurse_copy($src, $dst) {
$dir = opendir($src);
#mkdir($dst);
while (false !== ( $file = readdir($dir))) {
if (( $file != '.' ) && ( $file != '..' )) {
if (is_dir($src . '/' . $file)) {
if ($file->getExtension() == "pdf") {
recurse_copy($src . '/' . $file, $dst . '/' . $file);
}
} else {
copy($src . '/' . $file, $dst . '/' . $file);
}
}
} closedir($dir);
}
// if statements for
$itp = new RecursiveDirectoryIterator("foldername/", > FilesystemIterator::SKIP_DOTS);
$displayp = Array('pdf');
$i = 0;
foreach (new RecursiveIteratorIterator($itp) as $filepop) {
if (in_array(strtolower(array_pop(explode('.', $filepop))), $displayp))
if ($filepop->getExtension() == "pdf") {
echo >
recurse_copy("a", "b");
}
}
$itcopy = new RecursiveDirectoryIterator("foldername/", FilesystemIterator::SKIP_DOTS);
$displayp = Array ( 'pdf' );
foreach(new RecursiveIteratorIterator($itcopy) as $filecopy)
{
if (in_array(strtolower(array_pop(explode('.', $filecopy))), $displayp))
if ($filecopy->getExtension()=="pdf"){
copy($filecopy->getrealPath(),'pdf_folder/'.$filecopy->getFilename()) ;
}
}
The following code successfully removes sub directories and the files within them.
However it also removes all files in the directory above what is specified as $dir. This is not desired.
Can anybody see what is wrong with the code?
private function unlinkPubDirectory()
{
$dir = DIR_DOWNLOAD_PUB;
$h1 = opendir($dir);
while ($subdir = readdir($h1)) {
$h2 = opendir($dir . $subdir);
while ($file = readdir($h2)) {
#unlink($dir . $subdir . '/' . $file);
}
closedir($h2);
#rmdir($dir . $subdir);
}
closedir($h1);
}
As marked in the comments you should check for '..' as a possible file/directory and omit it. Additionally, check for errors without the '#'-sign.
private function unlinkPubDirectory()
{
$dir = DIR_DOWNLOAD_PUB;
$h1 = opendir($dir);
while ($subdir = readdir($h1)) {
if ($subdir == '..') continue; // don't do anything with '..'
$h2 = opendir($dir . $subdir);
while ($file = readdir($h2)) {
unlink($dir . $subdir . '/' . $file);
}
closedir($h2);
rmdir($dir . $subdir);
}
closedir($h1);
}
This will show you what is being deleted
while ($subdir = readdir($h1)) {
$h2 = opendir($dir . $subdir);
while ($file = readdir($h2)) {
echo "<p>will remove file " . ($dir . $subdir . '/' . $file);
}
closedir($h2);
echo "<p>will remove dir " . ($dir . $subdir);
}
HINT: check for . or .. folders and ignore them
Hello I am using following code for copy the files from one directory to another directory its worked like a charms This is my code:
<?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);
} if(isset($_POST["source"]) && isset($_POST["destination"])){
$src = $_POST["source"];
$dst = $_POST["destination" ];
recurse_copy($src,$dst);
}
?>
now I want to copy only the image files from the source folder.How can i do that?
Getimagesize can help you. It return false on error. File not image is error.
<?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 {
/////
if(!getimagesize($src . '/' . $file,$dst . '/' . $file)) continue;
/////
copy($src . '/' . $file,$dst . '/' . $file);
}
}
}
closedir($dir);
} if(isset($_POST["source"]) && isset($_POST["destination"])){
$src = $_POST["source"];
$dst = $_POST["destination" ];
recurse_copy($src,$dst);
}
?>
OR
You just can check file extension:
$ext = end(explode('.',$file));
But it can lie.
I see 2 ways:
You make an array of the possible file extensions, and check end of
$file var for every file.
Or you use exif_imagetype() function along with the Imagetype
contants to determine the file type from the signature. Documentation
is here. However, there is a dependency for this, for details
see the first user contributed note.
I want to move all files and folders inside a folder to another folder. I found a code to copy all files inside a folder to another folder.
move all files in a folder to another
// Get array of all source files
$files = scandir("source");
// Identify directories
$source = "source/";
$destination = "destination/";
// Cycle through all source files
foreach ($files as $file) {
if (in_array($file, array(".",".."))) continue;
// If we copied this successfully, mark it for deletion
if (copy($source.$file, $destination.$file)) {
$delete[] = $source.$file;
}
}
// Delete all successfully-copied files
foreach ($delete as $file) {
unlink($file);
}
How do I change this to move all folders and files inside this folder to another folder.
This is what i use
// Function to remove folders and files
function rrmdir($dir) {
if (is_dir($dir)) {
$files = scandir($dir);
foreach ($files as $file)
if ($file != "." && $file != "..") rrmdir("$dir/$file");
rmdir($dir);
}
else if (file_exists($dir)) unlink($dir);
}
// Function to Copy folders and files
function rcopy($src, $dst) {
if (file_exists ( $dst ))
rrmdir ( $dst );
if (is_dir ( $src )) {
mkdir ( $dst );
$files = scandir ( $src );
foreach ( $files as $file )
if ($file != "." && $file != "..")
rcopy ( "$src/$file", "$dst/$file" );
} else if (file_exists ( $src ))
copy ( $src, $dst );
}
Usage
rcopy($source , $destination );
Another example without deleting destination file or folder
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);
}
Please See: http://php.net/manual/en/function.copy.php for more juicy examples
Thanks
:)
Use rename instead of copy.
Unlike the C function with the same name, rename can move a file from one file system to another (since PHP 4.3.3 on Unix and since PHP 5.3.1 on Windows).
You need the custom function:
Move_Folder_To("./path/old_folder_name", "./path/new_folder_name");
function code:
function Move_Folder_To($source, $target){
if( !is_dir($target) ) mkdir(dirname($target),null,true);
rename( $source, $target);
}
Think this should do the trick:
http://php.net/manual/en/function.shell-exec.php
shell_exec("mv sourcedirectory path_to_destination");
Hope this help.
I think the answers are not complete for me, beacuse DIRECTORY_SEPARATOR are not defined on any answer (thans to Edgar Aivars for remember that!), but I want to write my solution for move (rename), copy and delete directory structures (based on this post info, the credits are for yours!).
defined('DS') ? NULL : define('DS',DIRECTORY_SEPARATOR);
function full_move($src, $dst){
full_copy($src, $dst);
full_remove($src);
}
function full_copy($src, $dst) {
if (is_dir($src)) {
#mkdir( $dst, 0777 ,TRUE);
$files = scandir($src);
foreach($files as $file){
if ($file != "." && $file != ".."){
full_copy("$src".DS."$file", "$dst".DS."$file");
}
}
} else if (file_exists($src)){
copy($src, $dst);
}
}
function full_remove($dir) {
if (is_dir($dir)) {
$files = scandir($dir);
foreach ($files as $file){
if ($file != "." && $file != ".."){
full_remove("$dir".DS."$file");
}
}
rmdir($dir);
}else if (file_exists($dir)){
unlink($dir);
}
}
I hope this hepls anyone! (lile me in the future :D )
EDIT: Spell corrections... :(
My attempt at a recursive move function, after days of research and going through other excellent examples out there.
It provides for an overwriteExisting flag for choice. Consequently, if the overwriteExisting flag is false, the file will not be moved and the folder containing the file would not be removed.
function moveRecursive($sourcePath, $targetPath, $overwriteExisting) {
clearstatcache(); // not sure if this helps, or is even required.
$dir = opendir($sourcePath);
while (($file = readdir($dir)) !== false) {
echo nl2br($file . "\n");
if ($file != "." && $file != "..") {
if (is_dir($sourcePath . "/" . $file) == true) {
if (is_dir($targetPath. "/" . $file) == false) {
// I believe rename would be faster than copying and unlinking.
rename($sourcePath . "/" . $file, $targetPath. "/" . $file);
} else {
moveRecursive($sourcePath . "/" . $file, $targetPath ."/" . $file, $overwriteExisting);
if ($files = glob($sourcePath . "/*")) {
// remove the empty directory.
if (#rmdir($sourcePath . "/" . $file) == false) {
echo nl2br("rmdir has not removed empty directory " . $sourcePath . "/" . $file . "\n");
}
} else {
// when overwriteExisting flag is false, there would be some files leftover.
echo nl2br("cannot remove. not empty, count = " . count(glob($sourcePath . "/*")) . " -> " . $sourcePath . "/" . $file . "\n");
}
}
} else {
if (file_exists($targetPath. "/" . $file)) {
if ($overwriteExisting == true) {
// overwrite the file.
rename($sourcePath . "/" . $file, $targetPath. "/" . $file);
}
} else {
// if the target file does not exist, simply move the file.
rename($sourcePath . "/" . $file, $targetPath. "/" . $file);
}
}
}
}
closedir($dir);
}
I have spent about 3 hours testing this in many different scenarios, and it works most of the time. Although, sometimes, it gives me an Access denied code(5) error on Windows, which I have been unable to figure out. This is why I have put the clearstatcache() function up at the top, after reading up on its documentation. I don't know whether this is its appropriate usage. I can definitely imagine that it would slow down the function.
I can also imagine that this method may be faster than the copy -> unlink cycle, because if a target sub-folder does not exist, the whole folder tree below would be just moved. However, I am not sure and don't have the experience to conduct exhaustive tests, yet.
$src = 'user_data/company_2/T1/';
$dst = 'user_data/company_2/T2/T1/';
rcopy($src, $dst); // Call function
// Function to Copy folders and files
function rcopy($src, $dst) {
if (file_exists ( $dst ))
rrmdir ( $dst );
if (is_dir ( $src )) {
mkdir ( $dst );
$files = scandir ( $src );
foreach ( $files as $file )
if ($file != "." && $file != "..")
rcopy ( "$src/$file", "$dst/$file" );
} else if (file_exists ( $src ))
copy ( $src, $dst );
rrmdir ( $src );
}
// Function to remove folders and files
function rrmdir($dir) {
if (is_dir($dir)) {
$files = scandir($dir);
foreach ($files as $file)
if ($file != "." && $file != "..") rrmdir("$dir/$file");
rmdir($dir);
}
else if (file_exists($dir)) unlink($dir);
}
I use it
// function used to copy full directory structure from source to target
function full_copy( $source, $target )
{
if ( is_dir( $source ) )
{
mkdir( $target, 0777 );
$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 );
}
}