PHP

2010-08-26 5 views
14

में फ़ाइल सामग्री को प्रतिस्थापित करना मुझे preg_replace की तरह एक फ़ंक्शन की आवश्यकता है लेकिन स्ट्रिंग के बजाय मुझे फ़ाइलों/फ़ाइल सामग्री के साथ काम करने की आवश्यकता है।PHP

+0

आप फ़्रेड का उपयोग करके फ़ाइल सामग्री को एक चर में खींचकर खींच सकते हैं और फिर preg_replace के साथ काम कर सकते हैं जैसा कि आप पाठ की एक स्ट्रिंग के साथ करेंगे? – Chris

+0

हां लेकिन फिर अद्यतन सामग्री को उन फ़ाइलों में लिखा जाना चाहिए जिन्हें से लिया गया था। –

+0

तो सामग्री को वापस सामग्री में लिखने में समस्या क्या है? –

उत्तर

40

आप कर सकते हैं:

$file = 'filename'; 
file_put_contents($file,str_replace('find','replace',file_get_contents($file))); 
19

@ codaddict के जवाब छोटे फ़ाइलों के लिए काफी पर्याप्त है (और मैं इसे कैसे लागू करता है, तो फ़ाइल का आकार एक MiB के तहत किया गया होगा)। हालांकि यह स्मृति का एक टन खाएगा, और बड़ी फ़ाइलों को पढ़ने के दौरान आपको सावधान रहना चाहिए।

आप एक अधिक स्मृति अनुकूल संस्करण चाहते हैं, आप stream filters इस्तेमाल कर सकते हैं ...

class ReplaceText_filter extends php_user_filter { 
    protected $search = ''; 
    protected $replace = ''; 

    public function filter($in, $out, &$consumed, $closing) { 
     while ($bucket = stream_bucket_make_writable($in)) { 
      $bucket->data = str_replace(
       $this->search, 
       $this->replace, 
       $bucket->data 
      ); 
      $consumed += $bucket->datalen; 
      stream_bucket_append($out, $bucket); 
     } 
     return PSFS_PASS_ON; 
    } 

    public function onCreate() { 
     if (strpos($this->filtername, '.') === false) return false; 
     list ($name, $arguments) = explode('.', $this->filtername, 2); 
     $replace = ''; 
     $search = $arguments; 
     if (strpos($arguments, '|') !== false) { 
      list ($search, $replace) = explode('|', $arguments, 2); 
     } 
     if (strpos($search, ',') !== false) { 
      $search = explode(',', $search); 
     } 
     if (strpos($replace, ',') !== false) { 
      $search = explode(',', $replace); 
     } 
     $this->search = $search; 
     $this->replace = $replace; 
    } 
} 
stream_filter_register('replacetext.*', 'ReplaceText_Filter'); 

तो, तो आप एक मनमाना धारा फिल्टर जोड़ सकते हैं। फिल्टर का नाम तर्क निर्धारित करता है:

$search = 'foo'; 
$replace = 'bar'; 
$name = 'replacetext.'.$search.'|'.$replace; 
stream_filter_append($stream, $name); 

या सरणियों के लिए,

$search = array('foo', 'bar'); 
$replace = array('bar', 'baz'); 
$name = 'replacetext.'.implode(',', $search).'|'.implode(',', $replace); 
stream_filter_append($stream, $name); 

जाहिर है यह वास्तव में सरल उदाहरण है (और त्रुटि जाँच का एक बहुत नहीं है), लेकिन यह भी कर सकते हैं कुछ इस तरह करते हैं:

$f1 = fopen('mysourcefile', 'r'); 
$f2 = fopen('mytmpfile', 'w'); 
$search = array('foo', 'bar'); 
$replace = array('bar', 'baz'); 
$name = 'replacetext.'.implode(',', $search).'|'.implode(',', $replace); 
stream_filter_append($f1, $name); 
stream_copy_to_stream($f1, $f2); 
fclose($f1); 
fclose($f2); 
rename('mytmpfile', 'mysourcefile'); 

और वह स्मृति के उपयोग बहुत कम है जिसके फलस्वरूप विशाल (GiB या TiB) फ़ाइलों को संसाधित कर रखेंगे ...

ओह, और दूसरी अच्छी चीज, क्या यह विभिन्न धारा प्रकारों को संपादित करने में इनलाइन कर सकती है। मेरा मतलब यह है कि आप एक HTTP स्ट्रीम से पढ़ सकते हैं, इनलाइन संपादित कर सकते हैं और फ़ाइल स्ट्रीम में लिख सकते हैं। यह काफी शक्तिशाली है (जैसा कि आप इन फ़िल्टरों को चेन कर सकते हैं) ...

+0

इस उत्तर के साथ एकमात्र समस्या तब होती है जब खोज शब्द बाल्टी में स्थित होते हैं, खासकर जब 8 कीबी से बड़ी फ़ाइलों से निपटते हैं। – bit2shift

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