2011-01-25 44 views
14

Tôi có một tập lệnh PHP đôi khi cần ghi các tệp lớn vào đĩa. Sử dụng file_put_contents(), nếu tệp đủ lớn (trong trường hợp này khoảng 2 MB), tập lệnh PHP hết bộ nhớ (Lỗi nghiêm trọng PHP: Kích thước bộ nhớ được phép của ######## bytes đã hết). Tôi biết tôi chỉ có thể tăng giới hạn bộ nhớ, nhưng điều đó dường như không phải là một giải pháp đầy đủ cho tôi - phải có một cách tốt hơn, đúng không?Cách tốt nhất để viết một tệp lớn vào đĩa bằng PHP là gì?

Cách tốt nhất để ghi tệp lớn vào đĩa bằng PHP là gì?

+1

nguồn gốc của dữ liệu là gì? Ngoài ra, hầu hết các cấu hình PHP sẽ có thể xử lý 2MB không có vấn đề gì. Giới hạn bộ nhớ của bạn có thể là theo cách. – webbiedave

+1

Tệp này đến từ đâu? Nếu nó tồn tại trên đĩa rồi, thì 'copy()' sẽ là thích hợp nhất. – mario

+0

Trong trường hợp này, tôi nhận được tập tin từ một máy chủ từ xa bằng cách sử dụng curl. Vì vậy, tôi có nó trong một biến. –

Trả lời

15

Bạn sẽ cần một tập tin tạm thời, trong đó bạn đặt bit của file nguồn cộng với những gì được nối:

$sp = fopen('source', 'r'); 
$op = fopen('tempfile', 'w'); 

while (!feof($sp)) { 
    $buffer = fread($sp, 512); // use a buffer of 512 bytes 
    fwrite($op, $buffer); 
} 

// append new data 
fwrite($op, $new_data);  

// close handles 
fclose($op); 
fclose($sp); 

// make temporary file the new source 
rename('tempfile', 'source'); 

Bằng cách đó, toàn bộ nội dung của source không được đọc vào bộ nhớ. Khi sử dụng cURL, bạn có thể bỏ qua việc thiết CURLOPT_RETURNTRANSFER và thay vào đó, thêm một bộ đệm đầu ra mà viết vào một tập tin tạm thời:

function write_temp($buffer) { 
    global $handle; 
    fwrite($handle, $buffer); 
    return ''; // return EMPTY string, so nothing's internally buffered 
} 

$handle = fopen('tempfile', 'w'); 
ob_start('write_temp'); 

$curl_handle = curl_init('http://example.com/'); 
curl_setopt($curl_handle, CURLOPT_BUFFERSIZE, 512); 
curl_exec($curl_handle); 

ob_end_clean(); 
fclose($handle); 

Có vẻ như tôi luôn nhớ rõ ràng. Như được Marc chỉ ra, có CURLOPT_FILE để ghi trực tiếp phản hồi vào đĩa.

+0

Làm cho tinh thần, nhưng trong trường hợp này tôi đã lấy tập tin từ một máy chủ khác nhau bằng cách sử dụng curl, vì vậy nó đã có trong bộ nhớ. –

+0

@Joe Tôi đã cập nhật câu trả lời. Một gợi ý khác đến với bạn. –

+0

cho giải pháp đầu tiên bạn có thể đã sử dụng ['stream_copy_to_stream'] (http://php.net/stream_copy_to_stream) quá ;-) – arnaud576875

1

Viết từng dòng (hoặc gói bằng gói trong trường hợp tập tin nhị phân) sử dụng các chức năng như fwrite()

0

Hãy thử this answer:

$file = fopen("file.json", "w"); 

    $pieces = str_split($content, 1024 * 4); 
    foreach ($pieces as $piece) { 
     fwrite($file, $piece, strlen($piece)); 
    } 

    fclose($file); 
Các vấn đề liên quan