2013-06-10 36 views
29

ファイルをリモートサーバーにアップロードするための非常に単純なPHPコードがありました。私がそれをやっていた方法(ここでいくつかの他の解決策で提案されているように)は、ファイルをアップロードするためにcUrlを使用することです。誰でも私にPHPのCURLFileクラスの例を教えてもらえますか?

はここに私のコードです:

$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で実行され、@filenameしたがってCURLOPT_POSTFIELDS説明の下に述べhereとしてPHP> = 5.5.0で非推奨とされたことが表示されます、

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クラスの同様の作業例...

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"; 
} 
+0

var_dump($ _ FILES)できますか? upload.phpの – Danack

+1

?私がそれをすれば、どうすればcurl.phpページの結果を返すことができますか?以前はこれをやろうとしていましたが、送信コードを実行すると実際には何も返されませんでした。 – luci5r

+0

OK - RETURNTRANSFERをtrueに設定する必要がありました。これはupload.phpのvar_dump($ _ FILES)の結果です:array(1){["file"] => array(5){["name"] => string(11) "phpC0F4.tmp" [ ( "tmp_name")=>文字列(14) "/ tmp/phpj7C3Hv" ["エラー"] => int(0)["size"] => int(483397)}} phpj7C3Hvファイルがアップロードされました ' – luci5r

答えて

38

コードのためのRFCのスニペットがあります:https://wiki.php.net/rfc/curl-file-upload場合にも、一見無意味な機能curl_file_create(string $filename [, string $mimetype [, string $postname ]])を使用することができます

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_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

ありがとう男 - そこを見てみましょう。 – luci5r

+0

まあ、私がペーストしたビットは、ドキュメントにない便利なビットのほとんどすべてです。 – Danack

+0

このページは、クラスの実際の使用状況をより明確に示しています。 $ args ['file'] =新しいCurlFile($ _ FILES ['Filedata'] ['tmp_name'])を追加します。 curl_setopt($ ch、CURLOPT_POSTFIELDS、$ args); Deprecatedエラーを取り除きました。実際にはエラーを一掃しました。私が今問題としているのは、相手側の "upload.php"が無効になっていることです。ファイルを受信するために変更が必要なのかどうかはわかりません。実際にファイルを受け取っていないからです。 – luci5r

5

あなたの助けを借りて、私は自分の問題をphp 5.5とFacebook SDKで解決できました。私はsdkクラスのコードからこのエラーを受け取りました。

私は応答として、この数を考えていないが、私は誰かが、解決策を同じ問題を抱えている場合はFacebookのSDKとPHP 5.5

に関連する私のようなこのエラーを探して人がいると確信していますbase_facebook.phpから少しのコードを@filenameの代わりにCurlFileクラスを使うように変更しました。

私はいくつかの場所から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を解析し、価値の中で「@」を探して改善することができます。しかし、私はのソースの画像のために私が必要としたものでした。

+0

あなたのコードは他の人にとっても役に立ちます。 – luci5r

+0

便利です。ありがとう! FWIW、 '@'形式を完全に放棄し、アプリケーションコードを 'CurlFile()'アプローチを使うように変更するほうが意味があると思います。しかし、それは議論のためです。いずれにせよ、ありがとう! – rinogo

1

FOR curl_setopt():ファイルアップロードのための@filename APIの使用は推奨されていません。代わりに

$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

CurlFileテクニックを使用する場合は、CURLOPT_SAFE_UPLOADを設定しないでください(デフォルトはtrue、それはそのままにしておきます)。 CURLOPT_SAFE_UPLOADはPHP 7にも含まれていません。 – orrd

0

CURLFileが良くについて説明したCURLFileクラスをusethe、単純な1つのファイル1つのファイルに必要のないマルチパートメッセージを(送信したくない転送、およびいくつかのAPIをサポートしないでくださいマルチパート)、次のように動作します。

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

上記のコードにはいくつかの特別なデバッグがあることに注意してください。

関連する問題