谁能给我一个 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"]=> array(5) ["name"]=> string(11) "phpC0F4.tmp" ["type"]=> string(24) "application/octet-stream" ["tmp_name"]=> string(14) "/tmp/phpj7C3Hv" ["error"]=> int(0) ["size"]=> 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') >= 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 并在值中寻找“@”。但我这样做只是为了 source 和 image 因为这是我需要的。
【讨论】:
有用;谢谢! 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 类的例子?的主要内容,如果未能解决你的问题,请参考以下文章