谁能给我一个 PHP 的 CURLFile 类的例子?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17032990/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Can anyone give me an example for PHP's CURLFile class?
提问by luci5r
I had a very simple PHP code to upload a file to a remote server; the way I was doing it (as has been suggested here in some other solutions) is to use cUrl to upload the file.
我有一个非常简单的 PHP 代码将文件上传到远程服务器;我这样做的方式(正如在其他一些解决方案中所建议的那样)是使用 cUrl 上传文件。
Here's my code:
这是我的代码:
$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);
The server is running PHP 5.5.0 and it appears that @filename has been deprecated in PHP >= 5.5.0 as stated hereunder the CURLOPT_POSTFIELDS
description, and therefore, I'm getting this error:
服务器正在运行PHP 5.5.0,看来,@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 ...
Interestingly, there is absolutely nothing about this Class on php.net aside from a basic class overview. No examples, no description of methods or properties. It's basically blank here. I understand that is a brand new class with little to no documentation and very little real-world use which is why practically nothing relevant is coming up in searches on Google or here on Stackoverflow on this class.
有趣的是,除了基本的类概述之外,php.net 上绝对没有关于这个类的内容。没有示例,没有方法或属性的描述。这里基本上是空白的。我知道这是一个全新的课程,几乎没有文档,也很少在现实世界中使用,这就是为什么在 Google 或 Stackoverflow 上的此类搜索中几乎没有任何相关内容。
I'm wondering if there's anyone who has used this CURLFile class and can possibly help me or give me an example as to using it in place of @filename in my code.
我想知道是否有人使用过这个 CURLFile 类并且可以帮助我或给我一个例子来在我的代码中使用它代替 @filename 。
Edit:
编辑:
I wanted to add my "upload.php" code as well; this code would work with the traditional @filename method but is no longer working with the CURLFile class code:
我也想添加我的“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";
}
Final Edit:
最终编辑:
Wanted to add Final / Working code for others looking for similar working example of the scarcely-documented CURLFile class ...
想要为其他人添加最终/工作代码,以寻找几乎没有记录的 CURLFile 类的类似工作示例......
curl.php (local server)
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 (remote server)
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";
}
回答by Danack
There is a snippet on the RFC for the code: https://wiki.php.net/rfc/curl-file-upload
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);
You can also use the seemingly pointless function curl_file_create( string $filename [, string $mimetype [, string $postname ]] )
if you have a phobia of creating objects.
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);
回答by Claudio Romano
Thanks for your help, using your working code I was able to solve my problem with php 5.5 and Facebook SDK. I was getting this error from code in the sdk class.
感谢您的帮助,使用您的工作代码,我能够使用 php 5.5 和 Facebook SDK 解决我的问题。我从 sdk 类中的代码中收到此错误。
I don't thinks this count as a response, but I'm sure there are people searching for this error like me related to facebook SDK and php 5.5
我不认为这算作响应,但我确定有人像我一样搜索与 facebook SDK 和 php 5.5 相关的错误
In case someone has the same problem, the solution for me was to change a little code from base_facebook.php to use the CurlFile Class instead of the @filename.
如果有人遇到同样的问题,我的解决方案是从 base_facebook.php 更改一些代码以使用 CurlFile 类而不是 @filename。
Since I'm calling the sdk from several places, I've just modified a few lines of the sdk:
由于我是从几个地方调用sdk,我只是修改了sdk的几行:
In the method called "makeRequest" I made this change:
在名为“makeRequest”的方法中,我进行了以下更改:
In this part of the code:
在这部分代码中:
if ($this->getFileUploadSupport()){
$opts[CURLOPT_POSTFIELDS] = $params;
} else {
$opts[CURLOPT_POSTFIELDS] = http_build_query($params, null, '&');
}
Change the first part (with file upload enabled) to:
将第一部分(启用文件上传)更改为:
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, '&');
}
Maybe this can be improved parsing every $paramand looking for '@' in the value.. but I did it just for sourceand imagebecause was what I needed.
也许这可以改进解析每个$param并在值中查找 '@' .. 但我这样做只是为了源和图像,因为这是我需要的。
回答by Rahul Sid
FOR curl_setopt(): The usage of the @filename API for file uploading is deprecated. Please usethe CURLFile class instead
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;
回答by brianlmerritt
CURLFile has been explained well above, but for simple one file transfers where you don't want to send a multipart message (not needed for one file, and some APIs don't support multipart), then the following works.
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
}
Note the above code has some extra debug - remove them once it is working.
请注意,上面的代码有一些额外的调试 - 一旦它工作就删除它们。
回答by Max
Php POST request send multiple files with curl function:
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); }
?>