2010-07-13 33 views
6

Tôi đến từ nền C và C++ nhưng cũng chơi với một số nội dung web. Tất cả chúng tôi là C folks (hy vọng) biết rằng gọi số feof trên FILE* trước khi đọc là một lỗi. Đây là cái gì đó thường xuyên đưa người mới đến C và C++. Đây có phải là trường hợp thực hiện PHP không?Hành vi feof của PHP so với C

Tôi cho rằng đó là do tệp có thể là ổ cắm hoặc bất kỳ thứ gì khác mà không thể biết kích thước trước khi đọc xong. Nhưng chỉ là về tất cả các ví dụ PHP (ngay cả những người được tìm thấy trên php.net Tôi đã nhìn thấy trông giống như thế này (và báo động đi tắt trong đầu của tôi):

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

Tôi biết nó là thích hợp hơn để viết những dòng này như thế này và tránh điều này vấn đề:

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

nhưng điều đó ngoài vấn đề. Tôi đã thử nghiệm nếu mọi thứ thất bại nếu tôi làm "sai cách", nhưng tôi không thể làm cho hành vi không chính xác. nhưng tôi thấy nó đáng để thử.

Vì vậy, có sai khi gọi feof trước một số fread bằng PHP không?

Có một vài cách mà PHP có thể đã làm điều này khác với phiên bản của C, nhưng tôi cảm thấy chúng có nhược điểm.

  • chúng có thể được đặt mặc định là! EOF. Điều này là phụ tối ưu vì nó có thể không chính xác đối với một số trường hợp góc.

  • họ có thể nhận được kích thước tệp trong một cuộc gọi fopen, nhưng điều này không thể hoạt động trên tất cả các loại tài nguyên tệp, mang lại hành vi không nhất quán và sẽ chậm hơn.

Trả lời

3

PHP không biết liệu nó có nằm ở cuối tệp cho đến khi bạn đã cố gắng đọc nó hay không. Hãy thử ví dụ đơn giản này:

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

Bạn sẽ nhận được một dòng đọc read 0 bytes. feof() trả về true ngay cả khi bạn đang ở cuối tập tin. Thông thường, điều này không gây ra sự cố vì fread($fp, 1) không trả về dữ liệu nào và mọi thao tác bạn đang thực hiện trên đó sẽ không xử lý dữ liệu nào. Nếu bạn thực sự cần phải biết nếu bạn đang ở cuối của tập tin, bạn phải làm một đọc đầu tiên.

-1

Xác nhận của bạn về việc không gọi feof trước khi fread không chính xác - do đó câu hỏi không hợp lệ.

+5

Bạn đã tạo tài khoản của mình chỉ để cung cấp cho chúng tôi khoản đóng góp có giá trị này? –

+0

trong C nó chắc chắn là một lỗi hợp lý để gọi 'feof' trước một thao tác có thể đặt cờ EOF. 'fopen' không phải là một trong những hoạt động đó. –

+0

Arrrggghhh! Nó chắc chắn không phải là một lỗi, logic, cú pháp, hay cách khác. Nó hoàn toàn hợp lệ. Nếu bạn hiểu nó làm gì - nó sẽ hoạt động chính xác như mong đợi, như MightyE đã giải thích ở trên. Câu hỏi đóng khung tình trạng là một lỗi; không phải vậy. – Anonymous

0

Đây có thể là câu hỏi nhiều hơn câu trả lời nhưng tại sao không sử dụng file_get_contents()? Theo kinh nghiệm của tôi, nếu bạn đang đọc một tệp hoặc một luồng, hàm này thực hiện công việc dơ bẩn cho bạn (giả sử bạn muốn đọc toàn bộ tài nguyên cho một chuỗi, hoặc biết/có thể tính giới hạn và bù đắp). Hàm sister_put_contents() hoạt động tốt, ngược lại.

Ví dụ, đây là một ví dụ:

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

hoặc một dòng:

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

Sau đó, bạn không cần phải lo lắng về EOF hay bất cứ điều gì, nó làm điều đó cho bạn (ftp đặt bị một chút xúc xắc, nhưng không sao cả.) Tất nhiên, điều này sẽ không hoạt động trong mọi tình huống ...

Có điều gì đó tôi thiếu trong câu hỏi ban đầu khiến phương pháp này không khả thi?

+1

Cách tiếp cận của bạn là tốt và hoàn toàn hợp lý, câu hỏi của tôi là học thuật hơn thực tế. Tôi chỉ muốn biết nếu 'foef' trong PHP có hành vi tương tự như trong C. Cảm ơn. –

+1

Ah, một học giả, tôi đã không nhìn thấy áo khoác da của bạn với hai khuỷu tay 8o) (Homer Simpson FTW, "CORRECTION, tôi đã làm hỏng hai áo khoác!") – Tim