Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you copy a file in PHP without overwriting an existing file?

Tags:

file

php

file-io

When you use the PHP copy function, the operation blindly copies over the destination file, even if it already exists. How do you copy a file safely, only performing the copy if there is no existing file?

like image 359
Douglas Mayle Avatar asked Oct 22 '08 18:10

Douglas Mayle


People also ask

How do I copy files without overwriting?

If you are copying files using drag-drop or copy/paste, you may simply choose “Skip this file” or “Skip these files” option to not overwrite the files that are already existed at the destination folder. Or, if you are using command line copy, you can answer N to bypass these files that are already existed.

Does copy item overwrite files?

By default when you run the PowerShell Copy-Item cmdlet, it will overwrite the file if it is already exists.

How do I copy and paste a file in PHP?

The copy() function in PHP is used to copy a file from source to target or destination directory. It makes a copy of the source file to the destination file and if the destination file already exists, it gets overwritten. The copy() function returns true on success and false on failure.


1 Answers

The obvious solution would be to call file_exists to check to see if the file exists, but doing that could cause a race condition. There is always the possibility that the other file will be created in between when you call file_exists and when you call copy. The only safe way to check if the file exists is to use fopen.

When you call fopen, set the mode to 'x'. This tells fopen to create the file, but only if it doesn't exist. If it exists, fopen will fail, and you'll know that you couldn't create the file. If it succeeds, you will have a created a file at the destination that you can safely copy over. Sample code is below:

// The PHP copy function blindly copies over existing files.  We don't wish
// this to happen, so we have to perform the copy a bit differently.  The
// only safe way to ensure we don't overwrite an existing file is to call
// fopen in create-only mode (mode 'x').  If it succeeds, the file did not
// exist before, and we've successfully created it, meaning we own the
// file.  After that, we can safely copy over our own file.

$filename = 'sourcefile.txt'
$copyname = 'sourcefile_copy.txt'
if ($file = @fopen($copyname, 'x')) {
    // We've successfully created a file, so it's ours.  We'll close
    // our handle.
    if (!@fclose($file)) {
        // There was some problem with our file handle.
        return false;
    }

    // Now we copy over the file we created.
    if (!@copy($filename, $copyname)) {
        // The copy failed, even though we own the file, so we'll clean
        // up by itrying to remove the file and report failure.
        unlink($copyname);
        return false;
    }

    return true;
}
like image 135
Douglas Mayle Avatar answered Sep 22 '22 07:09

Douglas Mayle