Sara
Sara

Reputation: 14638

move all files and folders in a folder to another?

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.

Upvotes: 16

Views: 53437

Answers (8)

Manish
Manish

Reputation: 87

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.

Upvotes: 1

chybeat
chybeat

Reputation: 46

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... :(

Upvotes: 3

T.Todua
T.Todua

Reputation: 56555

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

Upvotes: 12

Neeraj
Neeraj

Reputation: 9205

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

Upvotes: 0

Neeraj
Neeraj

Reputation: 11

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

Upvotes: 1

metalfight - user868766
metalfight - user868766

Reputation: 2750

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.

Upvotes: 12

Joni
Joni

Reputation: 111409

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).

Upvotes: 19

Baba
Baba

Reputation: 95161

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 :)

Upvotes: 34

Related Questions