【问题标题】:Replacing file content in PHP在 PHP 中替换文件内容
【发布时间】:2011-04-04 06:01:43
【问题描述】:

我需要一个类似于 preg_replace 的函数,但我需要它来处理文件/文件内容,而不是字符串。

【问题讨论】:

  • 您可以通过使用 fread 循环将文件内容拉入变量中,然后像处理文本字符串一样使用 preg_replace ?
  • 是的,但是更新后的内容应该写入它所取自的文件中。
  • 那么将内容写回文件有什么问题?
  • 您可以使用 Unix 实用程序 sed
  • PHP 支持字符串中的二进制数据。请注意,手册中有一条注释说 preg fns 不喜欢大于 ~100k 的字符串。但是,它可能会在源字符串中出现空字符问题 - 因此以最多(例如)10k 的块读取文件,由空值分隔,去除任何尾随空值(并将其保留以备后用),将 preg 应用于每个块并再次写出来,如果您删除了一个空值,则将其添加回来。

标签: php file file-io preg-replace replace


【解决方案1】:

你可以这样做:

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

【讨论】:

    【解决方案2】:

    @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 流中读取、内联编辑以及写入文件流。它非常强大(因为您可以链接这些过滤器)...

    【讨论】:

    • 这个答案的唯一问题是当搜索词跨存储桶时,尤其是在处理大于 8 KiB 的文件时。
    【解决方案3】:
    <?php
    
    $pattern = "/created/";
    $replacement = "XXXXX";
    $file_name = "regex.txt";
    $getting_file_contents = file_get_contents($file_name);
    
    echo("Original file contents : " . "<br><br>");
    var_dump($getting_file_contents);
    echo("<br><br><br>");
    
    if ($getting_file_contents == true) {
      echo($file_name . " had been read succesfully" . "<br><br><br>");
    
      $replace_data_in_file = preg_replace($pattern, $replacement, $getting_file_contents);
      $writing_replaced_data = file_put_contents($file_name, $replace_data_in_file);
      echo("New file contents : " . "<br><br>");
      var_dump($replace_data_in_file);
      echo("<br><br>");
    
      if ($writing_replaced_data == true) {
        echo("Data in the file changed");
      }
      else {
        exit("Cannot change data in the file");
      }
    }
    else {
      exit("Unable to get file contents!");
    }
    
    ?>
    

    【讨论】:

    • 您能对此代码添加一些解释吗?否则它将被归类为低质量答案
    • 它的基本php函数,你可以从php.net/docs.php得到解释
    猜你喜欢
    • 2017-08-10
    • 1970-01-01
    • 2018-08-05
    • 1970-01-01
    • 2014-12-29
    • 1970-01-01
    • 2012-01-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多