2013-05-27 3 views
2

С помощью этого кода (и PHP 5.4.13 на поле Linux, Apache SAPI):Fread РНР() возвращает меньше, чем расширенный

$intOffset = 0; 
    $intInterval = min(filesize(TL_ROOT . '/' . $this->strFile), 1024); 
    $strBuffer = ''; 

    print 'INTERVAL: '.$intInterval.'<br />'; 
    print 'POS1: '.ftell($this->resFile).'<br />'; 
    // Read to delimiter 
    do 
    { 
     $intOffset -= $intInterval; 

     $fseek = @fseek($this->resFile, $intOffset, SEEK_END); 
     print 'POS2: '.ftell($this->resFile).'<br />'; 
     print 'READING: '.abs($intOffset).'<br />'; 
     $add = @fread($this->resFile, abs($intOffset)); 
     print 'ADD LEN: '.strlen($add).'<br />'; 
     print 'POS3: '.ftell($this->resFile).'<br />'; 
     print 'OFFSET: '.$intOffset.'<br />'; 
     print 'BUF LEN (0): '.strlen($strBuffer).'<br />'; 
     $strBuffer = $add . $strBuffer; 
     print 'BUF LEN (1): '.strlen($strBuffer).'<br />'; 
    } 
    while ($fseek != -1 && ($pos = strpos($strBuffer, self::CENTRAL_DIR_END)) === false); 

    print 'BUF LEN (2): '.strlen($strBuffer).'<br />'; 
    print 'POS: '.$pos.'<br />'; 

я получаю этот отладочный вывод:

INTERVAL: 1024 
POS1: 0 
POS2: 1078538 
READING: 1024 
ADD LEN: 821 
POS3: 1079562 
OFFSET: -1024 
BUF LEN (0): 0 
BUF LEN (1): 821 
BUF LEN (2): 821 
POS: 785 

WTF здесь происходит? С каких это пор, когда можно вернуть строку длиной 821 из чтения, которая переместила указатель на файл 1024 байта? Существует ли несколько многобайтовых вещей? Файл был открыт в режиме 'rb' и руководство говорит strlen() возвращает длину в байтах, так что не должна быть проблемой ...

+0

Удаление оператора '@' может показывать полезные сообщения об ошибках – arnaud576875

+0

Пробовал это, никаких изменений в выходе. – djc

+1

Тем не менее, удаление ошибок полностью не является хорошей идеей для вашего собственного здравомыслия;) – arnaud576875

ответ

4

возможно вернуть строку длиной 821 от чтения, что выдвинутого указатель файла 1024 байта? Существует ли несколько многобайтовых вещей?

Как вы указали, strlen подсчитывает байты; однако некоторые расширения могут перегрузить функцию strlen для подсчета символов вместо этого (например, mbstring)

+0

Вы совершенно правы. Исправлена ​​проблема с отключением mbstring.func_overload. Должен был подумать об этом сам, я был так близко ... Я полагаю, что запуск сервера с func_overload = 7, установленным по умолчанию, может быть не такой хорошей идеей? (Я также написал https://github.com/contao/core/issues/5842 об этом.) – djc

+0

Да, func_overload, скорее всего, сломает скрипты и редко бывает хорошей идеей – arnaud576875

Смежные вопросы