2008-10-22 39 views

Trả lời

8

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; 
} 
+0

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

3

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.

0

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.

0

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; 
} 
Các vấn đề liên quan