PHP LimitIterator 失败(“不支持查找”+“无法倒回文件”)

Shl*_*omo 1 php spl splfileobject

我使用SplFileObjectLimitIterator来读取大文件中从位置 x 到 y 的内容。

当使用像/home/devel/stuff/myfile.log.

当使用这样的路径时,http://mydomain.com:8090/devel/stuff/myfile.log它不起作用。不过路径是正确的。

使用绝对路径时会失败吗?


错误消息是:

PHP Warning: SplFileObject::rewind() [<a href='splfileobject.rewind'>splfileobject.rewind</a>]: stream does not support seeking in ...

PHP Fatal error: Uncaught exception 'RuntimeException' with message 'Cannot rewind file ...'


完整代码:

  // $pStrFile contains the valid (yes!) path
  $oFile = new SplFileObject($pStrFile);
  // $nFrom = 80 and $nLines = 30
  $fileIterator = new LimitIterator($oFile, $nFrom, $nLines);

  foreach($fileIterator as $line) {
      $strLines .= $line;
  }
Run Code Online (Sandbox Code Playgroud)

hak*_*kre 5

为了让该rewind()函数在 上工作SplFileObject,底层的 Streamwrapper 需要支持查找。

PHP 当前的HTTP 流包装器不支持查找。所以你会收到错误消息:

PHP 警告:SplFileObject::rewind() [splfileobject.rewind]:流不支持在...中查找

我想到的第一个想法是使用NoRewindIterator仅禁用rewind()调用的方法,从而防止触发错误。

$obj      = new SplFileObject('http://www.stackoverflow.com/');
$norewind = new NoRewindIterator($obj);
$limit    = new LimitIterator($norewind, 80, 30);
Run Code Online (Sandbox Code Playgroud)

然而,既然已经没有了rewind(),那LimitIterator也多少有些被愚弄了。这会导致忽略偏移参数,它不会是 80 的偏移,而只是零(无偏移)。

为了克服这个问题,CachingIterator可以将 a 插入到混合物中。它正好解决了这个问题:

$obj      = new SplFileObject('http://www.stackoverflow.com/');
$norewind = new NoRewindIterator($obj);
$caching  = new CachingIterator($norewind);
$limit    = new LimitIterator($caching, 80, 30);

foreach ($limit as $i => $line)
{
    printf("%03d: %s", $i, $line);
 }
Run Code Online (Sandbox Code Playgroud)

示例输出(演示):

080: 
081: </span>
082:                 </div>
083:                 <div id="hsearch">
084:                     <form id="search" action="/search" method="get" autocomplete="off">
085:                     <div>
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,从技术上讲,PHP SPL 附带了足够的内部工具,可以避免写入 HTTP 流的临时文件。但请记住,这里的迭代器是仅向前的,这意味着您只能使用它一次。