2013-06-10 20 views
29

Tôi đã có một mã PHP rất đơn giản để tải tệp lên máy chủ từ xa; cách tôi đã làm nó (như đã được đề xuất ở đây trong một số giải pháp khác) là sử dụng cUrl để tải lên các tập tin.Bất cứ ai có thể cho tôi một ví dụ cho lớp CURLFile của PHP?

Dưới đây là mã của tôi:

$ch = curl_init("http://www.remotesite.com/upload.php"); 
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); 
curl_setopt($ch, CURLOPT_POST, true); 
curl_setopt($ch, CURLOPT_POSTFIELDS, array('fileupload' => '@'.$_FILES['Filedata']['tmp_name'])); 
echo curl_exec($ch);   

Các máy chủ đang chạy PHP 5.5.0 và dường như @filename đã bị phản đối trong PHP> = 5.5.0 như đã nêu here dưới mô tả CURLOPT_POSTFIELDS, và do đó, Tôi gặp phải lỗi này:

Deprecated: curl_setopt(): The usage of the @filename API for file uploading is deprecated. Please use the CURLFile class instead in ... 

Điều thú vị là, hoàn toàn không có gì về Lớp này trên php.net ngoài tổng quan lớp cơ bản. Không có ví dụ, không có mô tả về phương pháp hoặc thuộc tính. Về cơ bản nó trống here. Tôi hiểu rằng đó là một lớp hoàn toàn mới với ít hoặc không có tài liệu và sử dụng rất ít trong thế giới thực, đó là lý do tại sao thực tế không có gì liên quan đến các tìm kiếm trên Google hoặc ở đây trên Stackoverflow trên lớp này.

Tôi tự hỏi liệu có ai đã sử dụng lớp CURLFile này và có thể giúp tôi hoặc cho tôi ví dụ về cách sử dụng nó thay cho @filename trong mã của tôi hay không.

Edit:

tôi muốn thêm "upload.php" tôi mã là tốt; mã này sẽ làm việc với các phương pháp truyền thống @filename nhưng không còn được làm việc với mã lớp CURLFile:

$folder = "try/"; 
$path = $folder . basename($_FILES['file']['tmp_name']); 
if(move_uploaded_file($_FILES['file']['tmp_name'], $path)) { 
echo "The file ". basename($_FILES['file']['tmp_name']). " has been uploaded"; 
} 

cuối cùng Sửa:

Muốn thêm cuối cùng/code làm việc cho những người khác tìm kiếm Ví dụ làm việc tương tự của lớp CURLFile hiếm khi các tài liệu ...

curl.php (máy chủ địa phương)

<form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post" enctype="multipart/form-data"> 
<label for="file">Filename:</label> <input type="file" name="Filedata" id="Filedata" /> 
<br /> 
<input type="submit" name="submit" value="Submit" /> 
</form> 

<?php 
if ($_POST['submit']) { 
    $uploadDir = "/uploads/"; 
    $RealTitleID = $_FILES['Filedata']['name']; 
    $ch = curl_init("http://www.remotesite.com/upload.php"); 
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); 
    curl_setopt($ch, CURLOPT_POST, 1); 
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); 
    $args['file'] = new CurlFile($_FILES['Filedata']['tmp_name'],'file/exgpd',$RealTitleID); 
    curl_setopt($ch, CURLOPT_POSTFIELDS, $args); 
    $result = curl_exec($ch);  
} 
?> 

upload.php (từ xa máy chủ)

$folder = "try/"; 
$path = $folder . $_FILES['file']['name']; 
if(move_uploaded_file($_FILES['file']['tmp_name'], $path)) { 
echo "The file ". basename($_FILES['file']['name']). " has been uploaded"; 
} 
+0

Bạn có thể var_dump ($ _ FILES) không? – Danack

+1

trong upload.php? Nếu tôi làm điều đó - làm cách nào để tôi trả lại kết quả trên trang curl.php của tôi? Tôi đã cố gắng làm điều đó sớm hơn nhưng không có gì thực sự trở lại khi tôi thực thi mã gửi. – luci5r

+0

OK - Đã đặt RETURNTRANSFER thành true; vì vậy đây là kết quả của var_dump ($ _ FILES) trong tệp upload.php: 'mảng (1) {[" tệp "] => mảng (5) {[" tên "] => chuỗi (11)" phpC0F4.tmp "[ "type"] => string (24) "application/octet-stream" ["tmp_name"] => chuỗi (14) "/ tmp/phpj7C3Hv" ["lỗi"] => int (0) ["kích thước"] => int (483397)}} Các tập tin phpj7C3Hv đã được tải lên ' – luci5r

Trả lời

38

Có một đoạn trên RFC cho mã: https://wiki.php.net/rfc/curl-file-upload

curl_setopt($curl_handle, CURLOPT_POST, 1); 
$args['file'] = new CurlFile('filename.png', 'image/png', 'filename.png'); 
curl_setopt($curl_handle, CURLOPT_POSTFIELDS, $args); 

Bạn cũng có thể sử dụng chức năng dường như vô nghĩa nếu curl_file_create(string $filename [, string $mimetype [, string $postname ]]) bạn có một nỗi ám ảnh của việc tạo ra các đối tượng.

curl_setopt($curl_handle, CURLOPT_POST, 1); 
$args['file'] = curl_file_create('filename.png', 'image/png', 'filename.png'); 
curl_setopt($curl_handle, CURLOPT_POSTFIELDS, $args); 
+0

Cảm ơn người đàn ông - Hãy để tôi có một cái nhìn trên đó. – luci5r

+0

Vâng - bit tôi dán gần như là tất cả các bit hữu ích không có trong tài liệu. – Danack

+0

Trang này chắc chắn cung cấp một cái nhìn hữu ích hơn về cách sử dụng thực tế của lớp học; và thêm $ args ['file'] = new CurlFile ($ _ FILES ['Filedata'] ['tmp_name']); curl_setopt ($ ch, CURLOPT_POSTFIELDS, $ args); đã loại bỏ lỗi Không được chấp nhận; trong thực tế nó đã loại bỏ các lỗi tất cả cùng nhau. Vấn đề tôi có bây giờ là "upload.php" của tôi ở đầu kia đã trở thành không hợp lệ. Tôi không chắc chắn những thay đổi tôi cần phải thực hiện cho nó để RECIEVE tập tin - bởi vì nó không thực sự nhận được các tập tin nữa. – luci5r

5

Cảm ơn sự giúp đỡ của bạn, sử dụng mã làm việc của bạn Tôi có thể giải quyết vấn đề với php 5.5 và Facebook SDK. Tôi đã nhận được lỗi này từ mã trong lớp sdk.

Tôi không nghĩ đếm này như một câu trả lời, nhưng tôi chắc chắn có những người tìm kiếm lỗi này như tôi liên quan đến facebook SDK và php 5,5

Trong trường hợp ai đó có cùng một vấn đề, giải pháp đối với tôi là thay đổi một đoạn mã nhỏ từ base_facebook.php để sử dụng lớp CurlFile thay vì @filename.

Kể từ khi tôi gọi sdk từ nhiều nơi, tôi vừa sửa đổi một vài dòng của sdk:

Trong phương pháp này được gọi là "makeRequest" Tôi đã thực hiện thay đổi này:

Trong phần này của mã:

if ($this->getFileUploadSupport()){ 
    $opts[CURLOPT_POSTFIELDS] = $params; 
} else { 
    $opts[CURLOPT_POSTFIELDS] = http_build_query($params, null, '&'); 
} 

Thay đổi phần đầu tiên (với tập tin tải lên kích hoạt) tới:

if ($this->getFileUploadSupport()){ 
    if(!empty($params['source'])){ 
    $nameArr = explode('/', $params['source']); 
    $name = $nameArr[count($nameArr)-1]; 
    $source = str_replace('@', '', $params['source']); 
    $size = getimagesize($source); 
    $mime = $size['mime']; 
    $params['source'] = new CurlFile($source,$mime,$name); 
    } 

    if(!empty($params['image'])){ 
    $nameArr = explode('/', $params['image']); 
    $name = $nameArr[count($nameArr)-1]; 
    $image = str_replace('@', '', $params['image']); 
    $size = getimagesize($image); 
    $mime = $size['mime']; 
    $params['image'] = new CurlFile($image,$mime,$name); 
    } 
    $opts[CURLOPT_POSTFIELDS] = $params; 
} else { 
    $opts[CURLOPT_POSTFIELDS] = http_build_query($params, null, '&'); 
} 

Có lẽ điều này có thể được cải thiện phân tích cú pháp mỗi $ param và tìm kiếm '@' trong giá trị .. nhưng tôi đã làm nó chỉ cho nguồnimage vì đó là những gì tôi cần.

+0

Bạn đời tuyệt vời - mã của bạn cũng hữu ích cho người khác. – luci5r

+0

Hữu ích; cảm ơn! FWIW, tôi nghĩ rằng nó có thể có ý nghĩa hơn để từ bỏ định dạng '@' hoàn toàn và thay đổi mã ứng dụng của bạn để sử dụng phương thức 'CurlFile()'. Nhưng đó là cho cuộc tranh luận. Dù bằng cách nào, cảm ơn! – rinogo

1

CHO curl_setopt(): Việc sử dụng API @filename để tải tệp lên không được chấp nhận. Hãy usethe lớp CURLFile thay

$img='image.jpg'; 

$data_array = array(
     'board' => $board_id, 
     'note' => $note, 
     'image' => new CurlFile($img) 
    ); 

$curinit = curl_init($url); 
    curl_setopt($curinit, CURLOPT_RETURNTRANSFER, true); 
    curl_setopt($curinit, CURLOPT_POST, true); 
    curl_setopt($curinit, CURLOPT_CUSTOMREQUEST, "POST"); 
    curl_setopt($curinit, CURLOPT_POSTFIELDS, $data_array); 
    curl_setopt($curinit, CURLOPT_SAFE_UPLOAD, false); 
    $json = curl_exec($curinit); 
    $phpObj = json_decode($json, TRUE); 
    return $phpObj; 
+0

Khi sử dụng kỹ thuật CurlFile, bạn không nên đặt CURLOPT_SAFE_UPLOAD (mặc định là true, và nó nên được để lại theo cách đó), để dòng đó phải được loại bỏ. CURLOPT_SAFE_UPLOAD không còn được bao gồm trong PHP 7 nữa. – orrd

0

CURLFile đã được giải thích tốt trên, nhưng đối với đơn giản một chuyển file mà bạn không muốn gửi một thông điệp nhiều phần dữ liệu (không cần thiết cho một tập tin, và một số hàm API không hỗ trợ multipart), sau đó các công trình sau đây.

$ch = curl_init('https://example.com'); 

$verbose = fopen('/tmp/curloutput.log', 'w+'); // Not for production, but useful for debugging curl issues. 

$filetocurl = fopen(realpath($filename), 'r'); 

// Input the filetocurl via fopen, because CURLOPT_POSTFIELDS created multipart which some apis do not accept. 

// Change the options as needed. 

$options = array(
    CURLOPT_RETURNTRANSFER => true, 
    CURLOPT_POST => true, 
    CURLOPT_HTTPHEADER => array(
     'Content-type: application/whatever_you_need_here', 
     'Authorization: Basic ' . $username . ":" . $password) // Use this if you need password login 
    ), 
    CURLOPT_NOPROGRESS => false, 
    CURLOPT_UPLOAD => 1, 
    CURLOPT_TIMEOUT => 3600, 
    CURLOPT_INFILE => $filetocurl, 
    CURLOPT_INFILESIZE => filesize($filename), 
    CURLOPT_VERBOSE => true, 
    CURLOPT_STDERR => $verbose // Remove this for production 
); 

if (curl_setopt_array($ch, $options) !== false) { 
    $result = curl_exec($ch); 
    $info = curl_getinfo($ch); 
    curl_close($ch); 
} else { 
    // A Curl option could not be set. Set exception here 
} 

Lưu ý mã trên có thêm một số gỡ lỗi - xóa chúng khi hoạt động.