Ethan
Ethan

Reputation: 53

Use copy() in a foreach loop to copy multiple files php

I'm trying to copy multiple files from one domain on a web server to another using copy() and looping through a list of files, but it's only copying the last file on the list.

Here is the contents of files-list.txt:

/templates/template.php
/admin/admin.css
/admin/codeSnippets.php
/admin/editPage.php
/admin/index.php
/admin/functions.php
/admin/style.php
/admin/editPost.php
/admin/createPage.php
/admin/createPost.php
/admin/configuration.php

This script runs on the website that I'm trying to copy the files to. Here's the script:

$filesList = file_get_contents("http://copyfromhere.com/copythesefiles/files-list.txt");
$filesArray = explode("\n", $filesList);

foreach($filesArray as $file) {
    $filename = trim('http://copyfromhere.com/copythesefiles' . $file);

    $dest = "destFolder" . $file;

    if(!@copy($filename, $dest))
    {
        $errors= error_get_last();
        echo "COPY ERROR: ".$errors['type'];
        echo "<br />\n".$errors['message'];
    } else {
        echo "$filename copied to $dest from remote!<br/>";
    }
}

I get the affirmative message for each and every file individually just as I should, but when I check the directory, only the last file from files-list.txt is there. I've tried changing the order, so I know the problem lies with the script, not any individual file.

The output from the echo statements looks something like this:

http://copyfromhere.com/copythesefiles/admin/admin.css copied to updates/admin/editPage.php from remote!
http://copyfromhere.com/copythesefiles/admin/admin.css copied to updates/admin/editPost.php from remote!
http://copyfromhere.com/copythesefiles/admin/admin.css copied to updates/admin/index.php from remote!

Etc

Upvotes: 1

Views: 1525

Answers (2)

Dave Morton
Dave Morton

Reputation: 691

I've modified your code slightly, and tested it on my local dev server. The following seems to work:

$fileURL = 'http://copyfromhere.com/copythesefiles';
$filesArray = file("$fileURL/files-list.txt", FILE_IGNORE_NEW_LINES);
foreach ($filesArray as $file) {
  $fileName = "$fileURL/$file";
  $dest = str_replace($fileURL, 'destFolder', $fileName);
  if (!copy($fileName, $dest)) {
    $errors= error_get_last();
    echo "COPY ERROR: ".$errors['type'];
    echo "<br />\n".$errors['message'];
  }
  else {
    echo "$fileName copied to $dest from remote!<br/>";
  }
}

This uses the same fix that Mark B pointed out, but also consolidated the code a little.

Upvotes: 1

Marc B
Marc B

Reputation: 360762

Unless the data you're fetching from that remote site has leading/ in the path/filename, you're not generating proper paths:

$file = 'foo.txt'; // example only
$dest = "destFolder" . $file;

produces destFolderfoo.txt, and you end up littering your script's working directory with a bunch of wonky filenames. Perhaps you wanted

$dest = 'destFolder/' . $file;
                   ^----note this

instead.

Upvotes: 1

Related Questions