Очевидным решением было бы вызвать file_exists , чтобы проверить, существует ли файл, но это может вызвать состояние гонки. Всегда существует вероятность того, что другой файл будет создан между вами при вызове file_exists и при вызове copy . Единственный безопасный способ проверить, существует ли файл, это использовать fopen .
Когда вы звоните fopen , установите режим 'x'. Это говорит fopen создать файл, но только если он не существует. Если он существует, fopen не удастся, и вы будете знать, что не можете создать файл. Если это удастся, у вас будет созданный файл в месте назначения, который вы можете безопасно скопировать. Пример кода ниже:
// 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;
}