PHP中替换文件内容

发布于 2024-09-16 02:13:48 字数 136 浏览 4 评论 0原文

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

I need a function just like preg_replace but instead of strings I need it to work with files / file content.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

○闲身 2024-09-23 02:13:48

你可以这样做:

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

You can do:

$file = 'filename';
file_put_contents($file,str_replace('find','replace',file_get_contents($file)));
蹲在坟头点根烟 2024-09-23 02:13:48

@codaddict 的答案对于小文件来说已经足够了(如果文件的大小低于 MiB,我将如何实现它)。然而,它会消耗大量内存,因此在读取大文件时应该小心。

如果您想要一个更内存友好的版本,您可以使用 流过滤器...

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

@codaddict's answer is quite sufficent for small files (and would be how I would implement it if the size of the file was under a MiB). However it will eat up a ton of memory, and as such you should be careful when reading large files.

If you want a much more memory friendly version, you could use 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');

So, then you can append an arbitrary stream filter. The filter's name determines the arguments:

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

or for arrays,

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

Obviously this is a really simple example (and doesn't do a lot of error checking), but it allows you to do something like this:

$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');

And that will keep memory usage very low while processing potentially huge (GiB or TiB) files...

Oh, and the other cool thing, is it can inline edit differing stream types. What I mean by that is that you can read from a HTTP stream, edit inline, and write to a file stream. It's quite powerful (as you can chain these filters)...

裂开嘴轻声笑有多痛 2024-09-23 02:13:48
<?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

$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!");
}

?>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文