Ошибка PHP LimitIterator («Не поддерживает поиск» + «Невозможно перемотать файл»)

Я использую SplFileObject и LimitIterator для чтения содержимого с позиции 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; } 

Solutions Collecting From Web of "Ошибка PHP LimitIterator («Не поддерживает поиск» + «Невозможно перемотать файл»)"

Это ограничение оболочки http. Если файл находится на диске, вы можете получить доступ к нему в любой позиции. Если вы хотите начать чтение в середине файла, это возможно. Однако, когда файл находится на веб-сервере, и вы получаете его с помощью HTTP, немного сложнее прочитать середину файла.

Вы можете скопировать файл во временное место, а затем использовать LimitIterator.

Чтобы функция SplFileObject rewind() работала над SplFileObject , базовому потоковому потоку необходимо поддерживать поиск.

Текущая HTTP-оболочка PHP не поддерживает поиск. Таким образом, вы получите сообщение об ошибке:

PHP Предупреждение: SplFileObject :: rewind () [splfileobject.rewind]: поток не поддерживает поиск в …

Первой мыслью, которая пришла мне в голову, было использование NoRewindIterator который просто отключает вызов NoRewindIterator rewind() и, следовательно, предотвращает запуск ошибки.

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

Однако, поскольку rewind() больше не существует, LimitIterator несколько обманут. Это приводит к игнорированию параметра смещения , это не будет смещение 80, а только нулевое (без смещения).

Чтобы преодолеть это, CachingIterator можно вставить в микс. Это решает именно эту проблему:

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

Пример вывода ( Demo ):

 080: 081: </span> 082: </div> 083: <div id="hsearch"> 084: <form id="search" action="/search" method="get" autocomplete="off"> 085: <div> 

Как вы можете видеть, технически PHPs SPL поставляется с достаточным количеством внутренних инструментов, чтобы записывать временный файл для потока HTTP. Но имейте в виду, что итератор здесь только вперед, а это значит, что вы можете использовать его только один раз.