2013-05-18 23 views
8

Vì vậy, tôi muốn người dùng có thể tải lên các tệp lớn mà không phải lo lắng về giá trị kích thước bài đăng tối đa. Cách khác là sử dụng PUT và gửi tệp dưới dạng dữ liệu thô. Khi sử dụng jquery tôi có thể làm điều này:Ranh giới biểu mẫu và ghi php: // đầu vào vào một tệp trong php

var data = new FormData(); 
    jQuery.each($('#file_upload')[0].files, function(i, file) { 
    data.append('file-'+i, file); 
}); 
$.ajax({ 
    url: 'upload.php?filename=test.pdf', 
    data: data, 
    cache: false, 
    contentType: false, 
    processData: false, 
    type: 'PUT', 
}); 

Trong PHP tôi có thể làm điều này:

$f = fopen($_GET['filename'], "w"); 
$s = fopen("php://input", "r"); 

while($kb = fread($s, 1024)) 
{ 
    fwrite($f, $kb, 1024); 
} 
fclose($f); 
fclose($s); 
Header("HTTP/1.1 201 Created"); 

Tôi không thực hiện:

$client_data = file_get_contents("php://input"); 

Kể từ khi đưa toàn bộ file vào một biến chắc chắn sẽ lấp đầy tất cả bộ nhớ khi tải lên các tệp lớn.

Điều tôi không thể hiểu được là cách ghi dữ liệu tệp mà không có ranh giới biểu mẫu. Ngay bây giờ nó viết ở phía trên cùng của tập tin một cái gì đó như thế này:

------WebKitFormBoundaryVz0ZGHLGxBOCUVQG 
Content-Disposition: form-data; name="file-0"; filename="somename.pdf" 
Content-Type: application/pdf 

và tại một cái gì đó phía dưới như thế này:

------WebKitFormBoundaryVz0ZGHLGxBOCUVQG--  

Vì vậy, tôi cần phải phân tích dữ liệu. Nhưng với điều đó tôi cần đọc toàn bộ luồng dữ liệu vào bộ nhớ và với các tệp video lớn, tôi không muốn làm điều đó. Tôi đã đọc một số điều về việc tạo luồng php: // temp. Nhưng không may mắn với điều đó. Làm cách nào để chỉ ghi nội dung vào một tệp mà không có tiêu đề biên? Và trước tiên không bơm tất cả dữ liệu vào một biến?

+0

Bạn có thể cung cấp tiêu đề 'Content-Type' không? –

Trả lời

1

Có lẽ một sự kết hợp của fgets ngừng đọc tại một dòng mới và kiểm tra ranh giới:

while($kb = fgets($s, 1024)) 
{ 
    if(strpos($kb, '------') === false) //or !== 0 for first position 
    { 
     fwrite($f, $kb, 1024); 
    } 
} 
+0

Nhưng làm thế nào để chắc chắn rằng '-----' được đưa vào cùng một đoạn? Điều gì sẽ xảy ra nếu '---' được đưa vào cuối đoạn đầu tiên và '---' - đó là sự bắt đầu của phần thứ hai? Hoặc nó không thể là trường hợp? – Tamara

+0

'fgets' đọc ở cuối dòng' \ n', do đó - sẽ nằm ở đầu dòng tiếp theo. – AbraCadaver

+0

Nếu đúng như vậy, điều gì sẽ xảy ra với các tiêu đề sau? Họ cũng sẽ làm hỏng tệp. –

1

Bạn có thể sử dụng this (có rất nhiều như nó). Nó hỗ trợ tải lên chunked có nghĩa là bạn sẽ không nhấn bất kỳ kích thước tối đa bài/tệp miễn là mỗi đoạn tải lên nhỏ hơn kích thước bài đăng tối đa.

Nó cũng bao gồm PHP code bạn sẽ cần ở phía máy chủ.

+0

Tôi sử dụng trình tải lên blueimp trên một số trang web có nhiều tệp được tải lên và nó hoạt động tốt cho người dùng của tôi. –

0

Không cần phải tạo lại bánh xe. Chỉ cần sử dụng POST và thay đổi cấu hình của PHP thành các giới hạn lớn hơn. Những giới hạn này cũng có thể được đặt trên cơ sở mỗi thư mục/máy chủ.

Sử dụng .htaccess hoặc apache.conf bạn

php_value upload_max_filesize 10G 
php_value post_max_size 10G 

Nó cũng là một ý tưởng tốt để điều chỉnh giới hạn khác, như max_input_time.

Đừng quên di chuyển tệp đã nhận bằng cách sử dụng move_uploaded_file để tránh bất kỳ công việc bổ sung nào.