谁能给我一个 PHP 的 CURLFile 类的例子?

Posted

技术标签:

【中文标题】谁能给我一个 PHP 的 CURLFile 类的例子?【英文标题】:Can anyone give me an example for PHP's CURLFile class? 【发布时间】:2013-06-06 15:30:57 【问题描述】:

我有一个非常简单的 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,并且似乎 @filename 在 PHP >= 5.5.0 中已弃用,如 CURLOPT_POSTFIELDS 描述下的 here 所述,因此,我收到此错误:

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 或 *** 上的搜索中几乎没有任何相关内容出现。

我想知道是否有人使用过这个 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";
 

【问题讨论】:

你能 var_dump($_FILES) 吗? 在upload.php中?如果我这样做 - 我如何让它在我的 curl.php 页面上返回结果?我之前曾尝试这样做,但执行提交代码后实际上没有任何返回。 OK - 必须将 RETURNTRANSFER 设置为 true;所以这是 upload.php 下 var_dump($_FILES) 的结果:array(1) ["file"]=&gt; array(5) ["name"]=&gt; string(11) "phpC0F4.tmp" ["type"]=&gt; string(24) "application/octet-stream" ["tmp_name"]=&gt; string(14) "/tmp/phpj7C3Hv" ["error"]=&gt; int(0) ["size"]=&gt; int(483397) The file phpj7C3Hv has been uploaded 我 99% 都在工作 - 谢谢你。唯一缺少的是扩展。我需要做几件事 - 在 curl.php 中,我将代码更改为 $args['file'] = new CurlFile($_FILES['Filedata']['tmp_name'],'file/exgpd',$RealTitleID) 以包含 mime 类型和 postname。在upload.php 中,我将代码更改为$path = $folder . $_FILES['file']['name']。此时文件正在上传到远程服务器;唯一的问题是它不保留扩展名,只保留文件名。我只需要弄清楚那部分。 thanks man wtf a simple curl image file uplading 我花了 1 个小时才弄清楚哦 【参考方案1】:

RFC 上有一个 sn-p 代码: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);

【讨论】:

嗯 - 我粘贴的几乎所有有用的部分都没有在文档中。 该页面肯定会更有用地了解该类的实际使用情况;并添加 $args['file'] = new CurlFile($_FILES['Filedata']['tmp_name']); curl_setopt($ch, CURLOPT_POSTFIELDS, $args);摆脱了已弃用的错误;事实上,它完全消除了错误。我现在遇到的问题是我在另一端的“upload.php”已经失效。我不确定我需要对其进行哪些更改才能接收文件 - 因为它实际上不再接收文件了。 您可以将if (version_compare(PHP_VERSION, '5.5.0') &gt;= 0) 添加到您的代码中,否则回退到@ 一个问题...当我试图捕获我的文件时,没有出现在 $_FILE['file'] 变量中,而是在 $_POST['file'] 中,你知道为什么吗? 【参考方案2】:

感谢您的帮助,使用您的工作代码,我能够使用 php 5.5 和 Facebook SDK 解决我的问题。我从 sdk 类中的代码中得到了这个错误。

我不认为这算作回应,但我敢肯定有人像我一样在搜索与 facebook SDK 和 php 5.5 相关的错误

如果有人遇到同样的问题,我的解决方案是更改 base_facebook.php 中的一些代码以使用 CurlFile 类而不是 @filename。

由于我是从几个地方调用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 并在值中寻找“@”。但我这样做只是为了 sourceimage 因为这是我需要的。

【讨论】:

有用;谢谢! FWIW,我认为完全放弃@ 格式并更改您的应用程序代码以使用CurlFile() 方法可能更有意义。但这是有待商榷的。不管怎样,谢谢!【参考方案3】:

FOR 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;

【讨论】:

当使用 CurlFile 技术时,您不应该设置 CURLOPT_SAFE_UPLOAD(它默认为 true,应该保持这种状态),因此应该删除该行。 CURLOPT_SAFE_UPLOAD 甚至不再包含在 PHP 7 中。【参考方案4】:

CURLFile 上面已经很好地解释了,但是对于简单的一个文件传输,您不想发送多部分消息(一个文件不需要,并且某些 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

请注意,上面的代码有一些额外的调试 - 一旦它工作就删除它们。

【讨论】:

【参考方案5】:

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

【讨论】:

以上是关于谁能给我一个 PHP 的 CURLFile 类的例子?的主要内容,如果未能解决你的问题,请参考以下文章

谁能给我个PHP 5.5版本的下载地址啊。

TP框架的业务逻辑谁能给我说说

什么是减少变量?谁能给我一些例子?

谁能给我一个关于“啥使对象有状态”的这种情况的好例子?

谁能给我多发点后缀名啊,平时有好多后缀我都不知道是啥文件,谁能给我发一些?顺便都告诉是啥文件。

谁能给我一个xsl中模板“模式”的例子吗?