2010-07-13 7 views
6

Я родом из C и C++, но также играю с некоторыми веб-материалами. Все мы, люди (надеюсь) знаем, что вызов feof на FILE* перед выполнением чтения является ошибкой. Это то, что часто забивает новичков на C и C++. Это также относится к реализации PHP?Поведение фейсов PHP по сравнению с C

Я полагаю, что это должно быть потому, что файл может быть сокетом или чем-либо еще, где невозможно узнать размер до окончания чтения. Но почти каждый пример PHP (даже те, что на php.net я видел выглядит примерно так (и сигналы тревоги уходят в моей голове):

$f = fopen("whatever.txt", "rb"); 
while(!feof($f)) { 
    echo fgets($f); 
} 
fclose($f); 

Я знаю, что предпочтительнее, чтобы написать это, как это и избежать этого вопрос:

$f = fopen("whatever.txt", "rb"); 
while($line = fgets($f)) { 
    echo $line; 
} 
fclose($f); 

но это, кроме точки я пытался тестирование, если все будет работать, если я сделал это «неправильный путь», но я не мог заставить его вызвать неправильное поведение Это не совсем научное,.. но я решил, что стоит попробовать.

Итак, неправильно ли звонить feof перед fread в PHP?

Существует несколько способов, которыми PHP мог бы сделать это по-другому, чем версия C, но я чувствую, что у них есть недостатки.

  • они могут иметь это значение по умолчанию! EOF. Это неоптимально, потому что это может быть некорректно для некоторых угловых случаев.

  • они могут получить размер файла во время вызова fopen, но это не может работать на всех типах файловых ресурсов, что приводит к несовместимому поведению и будет медленнее.

ответ

3

PHP не знает, находится ли он в конце файла, пока вы не попытаетесь его прочитать. Попробуйте этот простой пример:

<?php 
$fp = fopen("/dev/null","rb"); 
while (!feof($fp)) { 
    $data = fread($fp, 1); 
    echo "read " . strlen($data) . " bytes"; 
} 
fclose($fp); 
?> 

вы получите один линия чтения read 0 bytes. Функция feof() вернулась, даже если вы были технически в конце файла. Обычно это не вызывает проблемы, потому что fread($fp, 1) не возвращает никаких данных, и любая обработка, которую вы делаете, не обрабатывает данные просто отлично. Если вам действительно нужно знать, находитесь ли вы в конце файла, вам сначала нужно прочитать.

-1

Неправильное указание на отказ feof перед тем, как fread - следовательно, вопрос недействителен.

+5

Вы создали свой аккаунт, чтобы дать нам этот ценный вклад? –

+0

в C это, безусловно, логическая ошибка для вызова 'feof' перед операцией, которая может установить флаг EOF. 'fopen' не является одной из этих операций. –

+0

Arrrggghhh! Это, безусловно, не ошибка, логика, синтаксическая или иная. Это совершенно верно. Если вы понимаете, что он делает - он будет вести себя точно так, как ожидалось, как объяснил MightyE выше. Вопрос сформулировал условие как ошибку; это не. – Anonymous

0

Это может быть скорее вопрос, чем ответ, но почему бы не использовать file_get_contents()? По моему опыту, если вы читаете файл или поток, эта функция выполняет грязную работу для вас (при условии, что вы хотите прочитать весь ресурс для строки или знать/можете вычислить предел и смещение). Его сестра-функция file_put_contents() работает хорошо, наоборот.

Например, вот пример:

$expected_content = "Hello Stack Overflow!" 
$real_content = file_get_contents("/path/to/file.txt"); 
if ($expected_content != $real_content){ 
    file_put_contents("/path/to/file.txt", $real_content); 
} 

или поток:

$expected_content = "Hello Stack Overflow!" 
$real_content = file_get_contents("http://host.domain.com/file.txt"); 
if ($expected_content != $real_content){ 
    $options = array('ftp' => array('overwrite' => true)); 
    $stream = stream_context_create($options); 
    file_put_contents("ftp://user:[email protected]/file.txt", $real_content, 0, $stream); 
} 

Тогда вам не нужно беспокоиться о EOF или что-нибудь, он делает это для вас (FTP положить становится немного рискованным, но это нормально). Конечно, это не будет работать во всех ситуациях ...

Есть ли что-то, что мне не хватает в исходном вопросе, который делает этот подход неосуществимым?

+1

Ваш подход прекрасен и полностью разумен, мой вопрос более академичен, чем практичен. Я просто хотел знать, имеет ли «foef» в PHP такое же поведение, как и в C. Спасибо. –

+1

А, академик, я не видел твою кожаную куртку с твидовыми локтями 8o) (Гомер Симпсон FTW, «КОРРЕКЦИЯ, я разрушил две куртки!») – Tim

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