使用PHP替换大文件中的字符

使用PHP替换大文件中的字符,php,replace,large-files,file-handling,Php,Replace,Large Files,File Handling,我试图用这段代码替换大型XML文件(110MB)中的单引号,但出现了一个错误。我需要一个代码,可以处理至少3GB的XML文件 错误消息: 致命错误:允许的内存大小134217728字节已用尽 (试图分配20449728字节)在上的C:\xampp\htdocs\replace.php中 第10行 不建议将大文件读入php。调用适当的命令行,如sed 参考资料:简化: $str = str_replace( "'","'",file_get_contents('electronic

我试图用这段代码替换大型XML文件(110MB)中的单引号,但出现了一个错误。我需要一个代码,可以处理至少3GB的XML文件

错误消息:

致命错误:允许的内存大小134217728字节已用尽 (试图分配20449728字节)在上的C:\xampp\htdocs\replace.php中 第10行


不建议将大文件读入php。调用适当的命令行,如
sed

参考资料:

简化:

$str = str_replace( "'","'",file_get_contents('electronics.xml'));

这是非常错误的:

开放式XML

    $file = fopen($path, 'a+');
虽然无原因地循环,但fgets读取到文件的末尾,所以循环在第一次迭代时完成

    while (feof($file) === false)  
    {
无目的地再次读取同一文件的全部内容

        $str=file_get_contents($path);  
读取整个文件,未指定长度,因此读取到EOF

        $str=str_replace($string, $replace, fgets($file));  
    }
    fclose($file); 

什么也没有完成。

放下
文件获取内容
,你正在为每行迭代读取整个文件。对单个XML文件使用
fread
或类似的东西110MB是相当多的,但是只要代码编写得好,就不会使用超过220-250MB的内存。也就是说,我建议您加载整个文件,替换字符串并将其保存回其他地方。在保存之前,请取消设置原始指针以释放一些内存。通过这种方式,您为每一行迭代使用file\u get\u内容,这实际上就是您完成内存的原因。另外,我建议您增加php.ini的最大内存。
    ////
 //PHP 5.3 + Class find and replace string in files
 //
 //by Bruce Afruz 
 //
 //2013
 //
 //example usage for single file:
 //
 //$new = new fileReplacement('./');
 //$new->setExt("check.php");
 //$new->changeContents("hello", "goodbye");
 //
 //example usage for multiple files:
 //
 //$new = new fileReplacement('./test');
 //$new->setExt("*.html");
 //$new->changeContents("hello", "goodbye");
 //
 //to change directory:
 //
 //$new = new fileReplacement('./test');
 //$new->setDir("./test2");
 //$new->setExt("*.html");
 //$new->changeContents("hello", "goodbye");
 ////


 class fileReplacement 
 {
  private $ext , $dir ;
  public function getDir() {
   return $this->dir;
  }
  public function setDir($dir) {
   $this->dir = $dir;
  }
   public function getExt() {
   return $this->ext;
  }
  public function setExt($ext) {
   $this->ext = $ext;
  }
 function __construct($dir) {
   $this->dir = $dir;
  }

  public function rglob($pattern = '*', $flags = 0, $path = '') {

  chdir($this->getDir());
  $paths = glob($path . '*', GLOB_MARK | GLOB_ONLYDIR | GLOB_NOSORT);
  $files = glob($path . $pattern, $flags);
  foreach ($paths as $path) {
  $files = array_merge($files, $this->rglob($pattern, $flags, $path));
  }
  return $files;
 }

 public function changeContents($replace , $sentence , $flags = 0, $path = '') {
 $all = $this->rglob($this->getExt() , $flags, $path);
 foreach ($all as $file) {

  $filename = $file;
  $handle = fopen($filename, "r");
  $contents = fread($handle, filesize($filename));
  fclose($handle);
  $contents = str_replace($replace , $sentence, $contents);

  if (is_writable($filename)) {
   if (!$handle = fopen($filename, 'w+')) {
    echo "Cannot open file ($filename)
";
    exit;
   }

   // Write $contents to our opened file.
   if (fwrite($handle, $contents) === FALSE) {
    echo "Cannot write to file ($filename)
";
    exit;
   }

   echo "Success, wrote content to file ($filename)
";

   fclose($handle);
  } else {
   echo "The file $filename is not writable
";
  }
 }
 }}
    ////
 //PHP 5.3 + Class find and replace string in files
 //
 //by Bruce Afruz 
 //
 //2013
 //
 //example usage for single file:
 //
 //$new = new fileReplacement('./');
 //$new->setExt("check.php");
 //$new->changeContents("hello", "goodbye");
 //
 //example usage for multiple files:
 //
 //$new = new fileReplacement('./test');
 //$new->setExt("*.html");
 //$new->changeContents("hello", "goodbye");
 //
 //to change directory:
 //
 //$new = new fileReplacement('./test');
 //$new->setDir("./test2");
 //$new->setExt("*.html");
 //$new->changeContents("hello", "goodbye");
 ////


 class fileReplacement 
 {
  private $ext , $dir ;
  public function getDir() {
   return $this->dir;
  }
  public function setDir($dir) {
   $this->dir = $dir;
  }
   public function getExt() {
   return $this->ext;
  }
  public function setExt($ext) {
   $this->ext = $ext;
  }
 function __construct($dir) {
   $this->dir = $dir;
  }

  public function rglob($pattern = '*', $flags = 0, $path = '') {

  chdir($this->getDir());
  $paths = glob($path . '*', GLOB_MARK | GLOB_ONLYDIR | GLOB_NOSORT);
  $files = glob($path . $pattern, $flags);
  foreach ($paths as $path) {
  $files = array_merge($files, $this->rglob($pattern, $flags, $path));
  }
  return $files;
 }

 public function changeContents($replace , $sentence , $flags = 0, $path = '') {
 $all = $this->rglob($this->getExt() , $flags, $path);
 foreach ($all as $file) {

  $filename = $file;
  $handle = fopen($filename, "r");
  $contents = fread($handle, filesize($filename));
  fclose($handle);
  $contents = str_replace($replace , $sentence, $contents);

  if (is_writable($filename)) {
   if (!$handle = fopen($filename, 'w+')) {
    echo "Cannot open file ($filename)
";
    exit;
   }

   // Write $contents to our opened file.
   if (fwrite($handle, $contents) === FALSE) {
    echo "Cannot write to file ($filename)
";
    exit;
   }

   echo "Success, wrote content to file ($filename)
";

   fclose($handle);
  } else {
   echo "The file $filename is not writable
";
  }
 }
 }}