Nasıl Varolan dosyanın üzerine yazmadan PHP bir dosyayı kopyalamak mı?

4 Cevap php

Eğer PHP copy işlevi, hedef dosya üzerinde işlem körü körüne kopya, zaten varsa bile kullanın. Nasıl varolan bir dosya varsa, sadece kopyalama yaparken, güvenli bir dosyayı kopyalamak mı?

4 Cevap

Bariz çözüm file_exists dosya varsa görmek için kontrol etmek için aramak, ama bunu yaparken bir yarış durumu neden olabilir olurdu. Diğer dosya file_exists arayın ve ne zaman aradığınızda copy arasında oluşturulmuş olacağını olasılığı her zaman vardır. Dosyası varsa kontrol etmek için tek güvenli yolu kullanmaktır fopen.

Aradığınızda fopen, 'x' modunu ayarlayın. Bu fopen dosyası oluşturmak için, ama yok sadece söyler. Varsa, fopen başarısız olur ve size dosya oluşturmak olamayacağını bileceksiniz. Eğer başarılı olursa, size güvenle üzerinde kopyalayabilirsiniz hedefe bir oluşturulmuş bir dosyası olacak. Örnek kod aşağıda:

// 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;
}

Ben kendi sorusunu yanıtladı düşünüyorum - hedef dosya kopyalama yapmadan önce varolduğundan emin olmak için kontrol edin. Dosyası varsa, kopya atlayın.

Güncelle: Ben gerçekten kendi soru cevap yaptım bakın. Sen yarış koşulları söz, ancak dosya zaten var olduğunu bulursak, bunu nasıl biliyor musunuz:

  • zaten var olan dosya gerçekten kopyalamak istediğiniz biridir
  • Dosya kendi işini tamamlamış diğer işlem kopyalama (dosya veri hepsi var)
  • dosya kopyalama diğer işlem başarısız (ve tamamlanmamış bir dosya bırakmak, ya da yeni bir dosya silme) gitmiyor

Ben senin soruna bir çözüm tasarlarken bu soruları düşünmelisiniz düşünüyorum.

Kullanmayı deneyin link() function instead of 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;
    }
}

Ne yazık ki, bu not Windows üzerinde çalışır.

Sadece yarış koşulları umurumda değil, bir bal porsuk fonksiyonu, çapraz-platform çalışır.

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