2008-10-22 11 views
6

जब आप PHP copy फ़ंक्शन का उपयोग करते हैं, तो ऑपरेशन गंतव्य फ़ाइल पर अंधाधुंध प्रतिलिपि बनाता है, भले ही यह पहले से मौजूद हो। आप फ़ाइल को सुरक्षित रूप से कैसे प्रतिलिपि बनाते हैं, अगर कोई मौजूदा फ़ाइल नहीं है तो केवल प्रतिलिपि बना रही है?आप किसी मौजूदा फ़ाइल को ओवरराइट किए बिना PHP में फ़ाइल कैसे कॉपी करते हैं?

उत्तर

8

स्पष्ट समाधान यह देखने के लिए file_exists पर कॉल करना होगा कि यह देखने के लिए कि फ़ाइल मौजूद है या नहीं, लेकिन ऐसा करने से दौड़ की स्थिति हो सकती है। हमेशा संभावना है कि जब आप file_exists पर कॉल करते हैं और जब आप copy पर कॉल करते हैं तो दूसरी फ़ाइल बनाई जाएगी। फ़ाइल मौजूद है या नहीं, यह जांचने का एकमात्र सुरक्षित तरीका fopen का उपयोग करना है।

जब आप fopen पर कॉल करते हैं, तो मोड को 'x' पर सेट करें। फ़ाइल बनाने के लिए यह fopen बताता है, लेकिन केवल तभी होता है जब यह अस्तित्व में न हो। यदि यह मौजूद है, fopen विफल हो जाएगा, और आपको पता चलेगा कि आप फ़ाइल नहीं बना सके। यदि यह सफल होता है, तो आपके पास गंतव्य पर एक फ़ाइल बनाई जाएगी जिसे आप सुरक्षित रूप से कॉपी कर सकते हैं। नमूना कोड के नीचे है: link() समारोह का उपयोग कर

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

आपके पास अभी भी दौड़ की स्थिति है। लेकिन आप सही रास्ते पर हैं - यदि फॉपेन सफल होता है, तो कॉपी करने के लिए fwrite() का उपयोग करें, और पूर्ण होने पर स्रोत फ़ाइल को अनलिंक करें। –

3

मुझे लगता है कि आपने अपने प्रश्न का उत्तर दिया है - यह सुनिश्चित करने के लिए जांचें कि कॉपी करने से पहले गंतव्य फ़ाइल मौजूद है। अगर फ़ाइल मौजूद है, तो प्रतिलिपि छोड़ दें।

अद्यतन: मुझे लगता है कि आपने वास्तव में अपने स्वयं के प्रश्न का उत्तर दिया है। आप दौड़ की स्थिति का उल्लेख है, लेकिन लगता है फ़ाइल पहले से मौजूद है, तो आप कैसे जानते हैं कि है कि यदि आप कार्य करें:

  • फ़ाइल पहले से ही है कि वास्तव में एक आप को कॉपी
  • अन्य प्रक्रिया की प्रतिलिपि बनाना चाहते है वहाँ फ़ाइल अपना काम (फ़ाइल डेटा सब वहाँ है) पूरा कर लिया है
  • अन्य प्रक्रिया नकल फ़ाइल विफल (और एक अधूरी फ़ाइल छोड़ देते हैं, या हटाना नई फ़ाइल)

मैं आपको लगता है नहीं जा रहा है अपनी समस्या का समाधान तैयार करते समय इन सवालों पर विचार करना चाहिए।

0

कोशिश 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; 
    } 
} 

दुर्भाग्य से, इस विंडोज पर नहीं कार्य नहीं करेगा।

0

एक शहद बैजर फ़ंक्शन, जो केवल दौड़-परिस्थितियों की परवाह नहीं करता है, लेकिन क्रॉस-प्लेटफ़ॉर्म काम करता है।

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; 
} 
संबंधित मुद्दे

 संबंधित मुद्दे