web-dev-qa-db-ja.com

PHPのCURLFileクラスの例を教えてもらえますか?

リモートサーバーにファイルをアップロードするための非常に簡単なPHPコードがありました。私がそれを行っていた方法(他のソリューションでここで提案されているように)は、cUrlを使用してファイルをアップロードすることです。

これが私のコードです:

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

サーバーはPHP 5.5.0を実行しており、 here のように@filenameがPHP> = 5.5.0で非推奨になっているようです。 CURLOPT_POSTFIELDSの説明の下にあるため、このエラーが表示されます。

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

興味深いことに、基本的なクラスの概要を除いて、php.netのこのクラスにはまったく何もありません。例やメソッドやプロパティの説明はありません。基本的には空白です here 。私はそれがドキュメントがほとんどまたはまったくないまったく新しいクラスであり、実際の使用がほとんどないことを理解しています。これは、このクラスのGoogleまたはここのStackoverflowでの検索で実際に関連するものは何もありません。

このCURLFileクラスを使用したことがある人がいて、コードで@filenameの代わりにそれを使用する例について教えてもらえますか?.

編集:

「upload.php」コードも追加したかった。このコードは従来の@filenameメソッドで動作しますが、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";
}

最終編集

あまり文書化されていないCURLFileクラスの同様の作業例を探している他の人のために、Final/Workingコードを追加したい...

curl.php(ローカルサーバー)

<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(リモートサーバー)

$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";
} 
33
luci5r

コードのRFCにスニペットがあります: 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);
_

オブジェクトを作成する恐怖症がある場合は、一見無意味な関数curl_file_create( string $filename [, string $mimetype [, string $postname ]] )を使用することもできます。

_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);
_
48
Danack

あなたの助けをありがとう、あなたの作業コードを使用して、私はPHP 5.5とFacebook SDKで私の問題を解決することができました。 SDKクラスのコードからこのエラーが発生していました。

私はこれが応答としてカウントされるとは思わないが、facebook SDKとphp 5.5に関連する私のようなこのエラーを探している人がいると確信している

誰かが同じ問題を抱えている場合の解決策は、@ filenameの代わりにCurlFileクラスを使用するようにbase_facebook.phpから小さなコードを変更することでした。

私はいくつかの場所からSDKを呼び出しているため、SDKの数行を変更しました。

「makeRequest」というメソッドで、この変更を行いました。

コードのこの部分では:

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

最初の部分を(ファイルのアップロードを有効にして)変更します:

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, '&');
}

たぶん、これはすべての解析を改善することができます$ paramと値で「@」を探します.. sourceおよびimageなぜなら、必要だったからです。

5
Claudio Romano

Curl_setopt()の場合:ファイルのアップロードに@filename APIを使用することは非推奨です。代わりにCURLFileクラスを使用してください

$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;
1
Rahul Sid

Php POST curl関数で複数のファイルを送信するリクエスト:

<?php
    $file1 = realpath('ads/ads0.jpg');
    $file2 = realpath('ads/ads1.jpg');
    // Old method
    // Single file
    // $data = array('name' => 'Alexia', 'address' => 'Usa', 'age' => 21, 'file' => '@'.$file1);    
    // $data = array('name' => 'Alexia', 'address' => 'Usa', 'age' => 21, 'file[0]' => '@'.$file1, 'file[1]' => '@'.$file2);
    // CurlFile method   
    $f1 = new CurlFile($file1, mime_content_type($file1), basename($file1)); 
    $f2 = new CurlFile($file2, mime_content_type($file2), basename($file2)); 
    $data = array('name' => 'Alexia', 'address' => 'Usa', 'age' => 21, 'file[1]' => $f1, 'file[2]' => $f2);

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, 'https://url.x/upload.php');
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
    curl_setopt($ch, CURLOPT_SAFE_UPLOAD, false); // !!!! required as of PHP 5.6.0 for files !!!
    curl_setopt($ch, CURLOPT_POSTFIELDS, $data);    
    curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-GB; rv:1.9.2) Gecko/20100115 Firefox/3.6 (.NET CLR 3.5.30729)");
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); // 1, 2
    curl_setopt($ch, CURLOPT_TIMEOUT, 60);
    // curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
    $res2 = curl_exec($ch);
    echo $res2;
?>

<?php
    // upload.php
    $json = json_decode(file_get_contents('php://input'), true);
    if(!empty($json)){ print_r($json); }
    if(!empty($_GET)){ print_r($_GET); }
    if(!empty($_POST)){ print_r($_POST); }
    if(!empty($_FILES)){ print_r($_FILES); }
?>
0
Max

CURLFileは上で十分に説明されていますが、マルチパートメッセージを送信したくない(1つのファイルには必要なく、一部のAPIはマルチパートをサポートしない)単純な1ファイル転送では、次のように動作します。

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

上記のコードには追加のデバッグがあります-動作したら削除してください。

0
brianlmerritt