Khi bạn sử dụng chức năng PHP copy, thao tác sao chép một cách mù quáng trên tệp đích, ngay cả khi nó đã tồn tại. Làm cách nào để sao chép tệp một cách an toàn, chỉ thực hiện bản sao nếu không có tệp hiện có?Làm cách nào để sao chép tệp trong PHP mà không ghi đè tệp hiện có?
Trả lời
Giải pháp rõ ràng là gọi file_exists để kiểm tra xem tệp có tồn tại không, nhưng thực hiện điều đó có thể gây ra tình trạng chủng tộc. Luôn luôn có khả năng rằng các tập tin khác sẽ được tạo ra ở giữa khi bạn gọi file_exists và khi bạn gọi copy. Cách an toàn duy nhất để kiểm tra xem tệp có tồn tại hay không là sử dụng fopen.
Khi bạn gọi fopen, đặt chế độ thành 'x'. Điều này cho biết fopen để tạo tệp nhưng chỉ khi tệp không tồn tại. Nếu nó tồn tại, fopen sẽ không thành công và bạn sẽ biết rằng bạn không thể tạo tệp. Nếu thành công, bạn sẽ tạo một tệp tại đích mà bạn có thể sao chép an toàn. Mã mẫu bên dưới:
// 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 ([email protected]($file)) {
// There was some problem with our file handle.
return false;
}
// Now we copy over the file we created.
if ([email protected]($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;
}
Tôi nghĩ bạn đã trả lời câu hỏi của riêng mình - hãy kiểm tra để đảm bảo tệp đích tồn tại trước khi thực hiện sao chép. Nếu tệp tồn tại, hãy bỏ qua bản sao.
Cập nhật: Tôi thấy bạn thực sự đã trả lời câu hỏi của riêng bạn. Bạn đề cập đến điều kiện chủng tộc, nhưng nếu bạn thấy rằng tập tin đã tồn tại, làm thế nào để bạn biết rằng:
- tập tin đó là đã có thực sự là một trong những bạn muốn sao chép
- quá trình khác sao chép tập tin đã hoàn thành công việc của mình (các dữ liệu tập tin là tất cả những gì)
- việc sao chép quá trình khác tập tin sẽ không thất bại (và để lại một tập tin không đầy đủ, hoặc xóa các tập tin mới)
tôi nghĩ bạn nên xem xét những câu hỏi này khi thiết kế một giải pháp cho vấn đề của bạn.
Thử sử dụng chức năng link()
thay vì copy()
.
function safe_copy($src, $dest) {
if (link($src, $dest)) {
// Link succeeded, remove old name
unlink($filename);
return true;
} else {
// Link failed; filesystem has not been altered
return false;
}
}
Thật không may, điều này sẽ không hoạt động trên Windows.
Chức năng giả mạo mật ong, mà không quan tâm đến điều kiện chủng tộc, nhưng hoạt động trên nhiều nền tảng.
function safeCopy($src, $dest) {
if (is_file($dest) === true) {
// if the destination file already exists, it will NOT be overwritten.
return false;
}
if (copy($src, $dest) === false) {
echo "Failed to copy $src... Permissions correct?\n";
return false;
}
return true;
}
- 1. Sao chép tập tin mà không ghi đè lên
- 2. Tác vụ sao chép Gradle: Cách ghi đè các tệp hiện có?
- 3. Làm cách nào để ghi đè lên các tệp hiện có theo lô?
- 4. Làm cách nào để sao chép các tệp nhất định (cấu trúc phân cấp thư mục), nhưng không ghi đè lên các tệp hiện có?
- 5. Có cách nào để tạo tệp ant local.properties mà không ghi đè build.xml không?
- 6. Google Cloud Storage - GSUtil - Sao chép tệp, bỏ qua hiện tại, không ghi đè
- 7. Cách hoàn nguyên tệp về phiên bản trước mà không ghi đè thay đổi hiện tại?
- 8. Làm cách nào để sao chép tệp lớn trên Windows mà không có CopyFile hoặc CopyFileEx?
- 9. GIT: Cách kiểm tra tệp từ lần commit trước đó mà không ghi đè lên tệp hiện tại?
- 10. có cách nào để buộc sao chép không? sao chép mà không ghi đè nhanh chóng, sử dụng các cửa sổ?
- 11. Làm cách nào để ghi đè nội dung tệp bằng nội dung mới trong PHP?
- 12. C ghi ở giữa tệp nhị phân mà không ghi đè bất kỳ nội dung hiện có nào
- 13. Ghi vào một tệp hiện có mà không ghi đè lên nội dung trong đó bằng VB6?
- 14. Làm cách nào để sao chép các tệp vào một JAR hiện có với Ant?
- 15. Làm thế nào để lưu/ghi đè tệp Excel hiện có bằng Excel Interop - C#
- 16. Tránh nội dung của một tệp hiện có được ghi đè khi ghi vào một tệp
- 17. Tại sao File.Open tốt hơn File.Create để ghi đè lên một tệp hiện có?
- 18. PHP - ghi đè chức năng hiện có
- 19. Làm cách nào để sao chép tệp từ Tài nguyên?
- 20. Làm cách nào để sao chép tệp có khả năng hủy bản sao?
- 21. Làm thế nào để ghi đè register_argc_argv trong PHP?
- 22. Cách sao chép tệp .xib?
- 23. PHP: làm cách nào để sao chép tệp tạm thời tải lên nhiều địa điểm?
- 24. Tệp PHP tải lên và ghi đè lên tệp có cùng tên
- 25. Làm cách nào để ghi đè các mục hiện có bằng Folder.CopyHere trong PowerShell?
- 26. Magento ghi đè/lib/tệp?
- 27. Làm cách nào để có được đường dẫn của tệp hiện đang mở trong photoshop (cs5) bằng bản ghi chép?
- 28. Cách sao chép tệp trong C#
- 29. WIX cài đặt tệp, ghi đè
- 30. Làm cách nào để ghi đè WRAPPER trong tệp mẫu của Bộ công cụ mẫu?
Bạn vẫn có điều kiện chủng tộc. Nhưng bạn đang đi đúng hướng - nếu fopen thành công, hãy sử dụng hàm fwrite() để thực hiện sao chép và hủy liên kết tệp nguồn khi hoàn tất. –