2010-08-07 28 views
11

Tôi đang sử dụng chức năng cURL của PHP để đọc tiểu sử từ steampowered.com. Dữ liệu được truy xuất là XML và chỉ cần khoảng 1000 byte đầu tiên.Gặp sự cố khi giới hạn kích thước tải xuống của hàm cURL của PHP

Phương pháp tôi đang sử dụng là thêm tiêu đề Phạm vi mà tôi đọc trên câu trả lời Chồng tràn (curl: How to limit size of GET?). Một phương pháp khác tôi đã thử là sử dụng curlopt_range nhưng điều đó cũng không hiệu quả.

<? 
$curl_url = 'http://steamcommunity.com/id/edgen?xml=1'; 
$curl_handle = curl_init($curl_url); 

curl_setopt ($curl_handle, CURLOPT_RETURNTRANSFER, 1); 
curl_setopt ($curl_handle, CURLOPT_CONNECTTIMEOUT, 2); 
curl_setopt ($curl_handle, CURLOPT_HTTPHEADER, array("Range: bytes=0-1000")); 

$data_string = curl_exec($curl_handle); 

echo $data_string; 

curl_close($curl_handle); 
?> 

Khi mã này được thực thi, nó trả về toàn bộ.

Tôi đang sử dụng phiên bản PHP 5.2.14.

+3

bạn có chắc là máy chủ bạn đang truy vấn phạm vi hỗ trợ không? Nguyên nhân khi tôi thử từ dòng lệnh, tôi cũng nhận được toàn bộ tài liệu, điều này khiến tôi tin rằng steamcommunity.com không có chức năng đó được kích hoạt – Doon

Trả lời

18

Máy chủ không tôn trọng tiêu đề Phạm vi. Điều tốt nhất bạn có thể làm là hủy kết nối ngay khi bạn nhận được nhiều dữ liệu hơn mức bạn muốn. Ví dụ:

<?php 
$curl_url = 'http://steamcommunity.com/id/edgen?xml=1'; 
$curl_handle = curl_init($curl_url); 

$data_string = ""; 
function write_function($handle, $data) { 
    global $data_string; 
    $data_string .= $data; 
    if (strlen($data_string) > 1000) { 
     return 0; 
    } 
    else 
     return strlen($data); 
} 

curl_setopt ($curl_handle, CURLOPT_RETURNTRANSFER, 1); 
curl_setopt ($curl_handle, CURLOPT_CONNECTTIMEOUT, 2); 
curl_setopt ($curl_handle, CURLOPT_WRITEFUNCTION, 'write_function'); 

curl_exec($curl_handle); 

echo $data_string; 

lẽ sạch hơn, bạn có thể sử dụng các wrapper http (điều này cũng sẽ sử dụng curl nếu nó đã được biên soạn với --with-curlwrappers). Về cơ bản, bạn sẽ gọi tới số fread trong vòng lặp và sau đó fclose trên luồng khi bạn nhận được nhiều dữ liệu hơn mức bạn muốn. Bạn cũng có thể sử dụng luồng truyền tải (mở luồng với fsockopen, thay vì fopen và gửi tiêu đề theo cách thủ công) nếu allow_url_fopen bị tắt.

+0

Điều này đã làm được điều này! Mặc dù, tôi không hoàn toàn hiểu được cơ chế của CURLOPT_WRITEFUNCTION. Bạn có thể giải thích những gì đang xảy ra ở đó? Cảm ơn một lần nữa. – Curtis

+1

@Cur Đó là một cuộc gọi lại được gọi bởi phần mở rộng curl mỗi lần nhận dữ liệu mới. Cuộc gọi lại nhận được trình xử lý curl và dữ liệu vừa được đọc. Nó sẽ trả về số byte được đọc, nếu không, nó sẽ hủy bỏ việc truyền tải (mặc dù phần cuối cùng này không được ghi lại, nó có vẻ là hành vi). – Artefacto

+2

@Cur OK Tôi tìm thấy các tài liệu ở đây: "Trả về số byte thực sự được chăm sóc. Nếu số tiền đó khác với số tiền được chuyển đến hàm của bạn, nó sẽ báo hiệu lỗi cho thư viện. Điều này sẽ hủy bỏ việc chuyển và trả lại CURLE_WRITE_ERROR. " http://curl.haxx.se/libcurl/c/curl_easy_setopt.html – Artefacto

Các vấn đề liên quan