从 PHP 表单 POST 通过 cURL 发送文件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4223977/
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
Send file via cURL from form POST in PHP
提问by Martin Bean
I'm writing an API and I'm wanting to handle file uploads from a form POST
. The markup for the form is nothing too complex:
我正在编写一个 API,我想处理从表单上传的文件POST
。表单的标记并不复杂:
<form action="" method="post" enctype="multipart/form-data">
<fieldset>
<input type="file" name="image" id="image" />
<input type="submit" name="upload" value="Upload" />
</fieldset>
</form>
However, I'm having difficulties understanding how to handle this server-side and send along with a cURL request.
但是,我很难理解如何处理此服务器端并与 cURL 请求一起发送。
I'm familiar with sending POST
requests with cURL with a data array, and resources I've read on uploading files tell me to prefix the filename with an @
symbol. But these same resources have a hard-coded file name, e.g.
我熟悉使用POST
带有数据数组的 cURL发送请求,我在上传文件时阅读的资源告诉我在文件名前加上一个@
符号。但是这些相同的资源有一个硬编码的文件名,例如
$post = array(
'image' => '@/path/to/myfile.jpg',
...
);
Well which file path is this? Where would I find it? Would it be something like $_FILES['image']['tmp_name']
, in which case my $post
array should look like this:
那么这是哪个文件路径?我会在哪里找到它?会不会是这样的$_FILES['image']['tmp_name']
,在这种情况下,我的$post
数组应该是这样的:
$post = array(
'image' => '@' . $_FILES['image']['tmp_name'],
...
);
Or am I going about this the wrong way? Any advice would be most appreciated.
还是我以错误的方式解决这个问题?任何建议将不胜感激。
EDIT:If someone could give me a code snippet of where I would go with the following code snippets then I'd be most grateful. I'm mainly after what I would send as cURL parameters, and a sample of how to use those parameters with the receiving script (let's call it curl_receiver.php
for argument's sake).
编辑:如果有人可以给我一个代码片段,说明我将使用以下代码片段的位置,那么我将不胜感激。我主要关注我将作为 cURL 参数发送的内容,以及如何在接收脚本中使用这些参数的示例(为了参数,我们称之为curl_receiver.php
)。
I have this web form:
我有这个网络表格:
<form action="script.php" method="post" enctype="multipart/form-data">
<fieldset>
<input type="file" name="image />
<input type="submit" name="upload" value="Upload" />
</fieldset>
</form>
And this would be script.php
:
这将是script.php
:
if (isset($_POST['upload'])) {
// cURL call would go here
// my tmp. file would be $_FILES['image']['tmp_name'], and
// the filename would be $_FILES['image']['name']
}
回答by Jeff Davis
Here is some production code that sends the file to an ftp (may be a good solution for you):
这是一些将文件发送到 ftp 的生产代码(可能对您来说是一个很好的解决方案):
// This is the entire file that was uploaded to a temp location.
$localFile = $_FILES[$fileKey]['tmp_name'];
$fp = fopen($localFile, 'r');
// Connecting to website.
$ch = curl_init();
curl_setopt($ch, CURLOPT_USERPWD, "[email protected]:password");
curl_setopt($ch, CURLOPT_URL, 'ftp://@ftp.website.net/audio/' . $strFileName);
curl_setopt($ch, CURLOPT_UPLOAD, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 86400); // 1 Day Timeout
curl_setopt($ch, CURLOPT_INFILE, $fp);
curl_setopt($ch, CURLOPT_NOPROGRESS, false);
curl_setopt($ch, CURLOPT_PROGRESSFUNCTION, 'CURL_callback');
curl_setopt($ch, CURLOPT_BUFFERSIZE, 128);
curl_setopt($ch, CURLOPT_INFILESIZE, filesize($localFile));
curl_exec ($ch);
if (curl_errno($ch)) {
$msg = curl_error($ch);
}
else {
$msg = 'File uploaded successfully.';
}
curl_close ($ch);
$return = array('msg' => $msg);
echo json_encode($return);
回答by CharlesA
For people finding this post and using PHP5.5+, this might help.
对于找到这篇文章并使用PHP5.5+ 的人来说,这可能会有所帮助。
I was finding the approach suggested by netcoder wasn't working. i.e. this didn't work:
我发现 netcoder 建议的方法不起作用。即这不起作用:
$tmpfile = $_FILES['image']['tmp_name'];
$filename = basename($_FILES['image']['name']);
$data = array(
'uploaded_file' => '@'.$tmpfile.';filename='.$filename,
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
I would receive in the $_POST
var the 'uploaded_file'
field - and nothing in the $_FILES
var.
我会在$_POST
var'uploaded_file'
字段中收到 - 在var 中没有任何内容$_FILES
。
It turns out that for php5.5+there is a new curl_file_create()
function you need to use. So the above would become:
事实证明,对于php5.5+,curl_file_create()
您需要使用一个新函数。所以上面的将变成:
$data = array(
'uploaded_file' => curl_file_create($tmpfile, $_FILES['image']['type'], $filename)
);
As the @
format is now deprecated.
由于该@
格式现已弃用。
回答by netcoder
This should work:
这应该有效:
$tmpfile = $_FILES['image']['tmp_name'];
$filename = basename($_FILES['image']['name']);
$data = array(
'uploaded_file' => '@'.$tmpfile.';filename='.$filename,
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
// set your other cURL options here (url, etc.)
curl_exec($ch);
In the receiving script, you would have:
在接收脚本中,您将拥有:
print_r($_FILES);
/* which would output something like
Array (
[uploaded_file] => Array (
[tmp_name] => /tmp/f87453hf
[name] => myimage.jpg
[error] => 0
[size] => 12345
[type] => image/jpeg
)
)
*/
Then, if you want to properly handle the file upload, you would do something like this:
然后,如果您想正确处理文件上传,您可以执行以下操作:
if (move_uploaded_file($_FILES['uploaded_file'], '/path/to/destination/file.zip')) {
// do stuff
}
回答by Joacer
For my the @ symbol did not work, so I do some research and found this way and it work for me, I hope this help you.
对于我的@ 符号不起作用,所以我做了一些研究并找到了这种方式并且它对我有用,我希望这对您有所帮助。
$target_url = "http://server:port/xxxxx.php";
$fname = 'file.txt';
$cfile = new CURLFile(realpath($fname));
$post = array (
'file' => $cfile
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $target_url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/4.0 (compatible;)");
curl_setopt($ch, CURLOPT_HTTPHEADER,array('Content-Type: multipart/form-data'));
curl_setopt($ch, CURLOPT_FRESH_CONNECT, 1);
curl_setopt($ch, CURLOPT_FORBID_REUSE, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 100);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
$result = curl_exec ($ch);
if ($result === FALSE) {
echo "Error sending" . $fname . " " . curl_error($ch);
curl_close ($ch);
}else{
curl_close ($ch);
echo "Result: " . $result;
}
回答by otharwa
It works for me when sending an attachment to Mercadolibre, through its messaging system.
通过其消息传递系统向 Mercadolibre 发送附件时,它对我有用。
The anwswer https://stackoverflow.com/a/35227055/7656744
答案https://stackoverflow.com/a/35227055/7656744
$target_url = "http://server:port/xxxxx.php";
$fname = 'file.txt';
$cfile = new CURLFile(realpath($fname));
$post = array (
'file' => $cfile
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $target_url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/4.0 (compatible;)");
curl_setopt($ch, CURLOPT_HTTPHEADER,array('Content-Type: multipart/form-data'));
curl_setopt($ch, CURLOPT_FRESH_CONNECT, 1);
curl_setopt($ch, CURLOPT_FORBID_REUSE, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 100);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
$result = curl_exec ($ch);
if ($result === FALSE) {
echo "Error sending" . $fname . " " . curl_error($ch);
curl_close ($ch);
}else{
curl_close ($ch);
echo "Result: " . $result;
}
回答by lalithkumar
cURL file object in procedural method:
程序方法中的 cURL 文件对象:
$file = curl_file_create('full path/filename','extension','filename');
cURL file object in Oop method:
Oop 方法中的 cURL 文件对象:
$file = new CURLFile('full path/filename','extension','filename');
$post= array('file' => $file);
$curl = curl_init();
//curl_setopt ...
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
$response = curl_exec($curl);
curl_close($curl);
回答by Prabhat Bhardwaj
we can upload image file by curl request by converting it base64 string.So in post we will send file string and then covert this in an image.
我们可以通过 curl 请求通过将其转换为 base64 字符串来上传图像文件。因此,在后期我们将发送文件字符串,然后将其转换为图像。
function covertImageInBase64()
{
var imageFile = document.getElementById("imageFile").files;
if (imageFile.length > 0)
{
var imageFileUpload = imageFile[0];
var readFile = new FileReader();
readFile.onload = function(fileLoadedEvent)
{
var base64image = document.getElementById("image");
base64image.value = fileLoadedEvent.target.result;
};
readFile.readAsDataURL(imageFileUpload);
}
}
then send it in curl request
然后在 curl 请求中发送它
if(isset($_POST['image'])){
$curlUrl='localhost/curlfile.php';
$ch = curl_init();
curl_setopt($ch,CURLOPT_URL, $curlUrl);
curl_setopt($ch,CURLOPT_POST, 1);
curl_setopt($ch,CURLOPT_POSTFIELDS, 'image='.$_POST['image']);
$result = curl_exec($ch);
curl_close($ch);
}
see here http://technoblogs.co.in/blog/How-to-upload-an-image-by-using-php-curl-request/118
在这里看到http://technoblogs.co.in/blog/How-to-upload-an-image-by-using-php-curl-request/118
回答by Libertese
Here is my solution, i have been reading a lot of post and they was really helpfull, finaly i build a code for small files, with cUrl and Php, that i think its really usefull.
这是我的解决方案,我已经阅读了很多帖子,它们真的很有帮助,最后我用 cUrl 和 Php 为小文件构建了一个代码,我认为它非常有用。
public function postFile()
{
$file_url = "test.txt"; //here is the file route, in this case is on same directory but you can set URL too like "http://examplewebsite.com/test.txt"
$eol = "\r\n"; //default line-break for mime type
$BOUNDARY = md5(time()); //random boundaryid, is a separator for each param on my post curl function
$BODY=""; //init my curl body
$BODY.= '--'.$BOUNDARY. $eol; //start param header
$BODY .= 'Content-Disposition: form-data; name="sometext"' . $eol . $eol; // last Content with 2 $eol, in this case is only 1 content.
$BODY .= "Some Data" . $eol;//param data in this case is a simple post data and 1 $eol for the end of the data
$BODY.= '--'.$BOUNDARY. $eol; // start 2nd param,
$BODY.= 'Content-Disposition: form-data; name="somefile"; filename="test.txt"'. $eol ; //first Content data for post file, remember you only put 1 when you are going to add more Contents, and 2 on the last, to close the Content Instance
$BODY.= 'Content-Type: application/octet-stream' . $eol; //Same before row
$BODY.= 'Content-Transfer-Encoding: base64' . $eol . $eol; // we put the last Content and 2 $eol,
$BODY.= chunk_split(base64_encode(file_get_contents($file_url))) . $eol; // we write the Base64 File Content and the $eol to finish the data,
$BODY.= '--'.$BOUNDARY .'--' . $eol. $eol; // we close the param and the post width "--" and 2 $eol at the end of our boundary header.
$ch = curl_init(); //init curl
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'X_PARAM_TOKEN : 71e2cb8b-42b7-4bf0-b2e8-53fbd2f578f9' //custom header for my api validation you can get it from $_SERVER["HTTP_X_PARAM_TOKEN"] variable
,"Content-Type: multipart/form-data; boundary=".$BOUNDARY) //setting our mime type for make it work on $_FILE variable
);
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/1.0 (Windows NT 6.1; WOW64; rv:28.0) Gecko/20100101 Firefox/28.0'); //setting our user agent
curl_setopt($ch, CURLOPT_URL, "api.endpoint.post"); //setting our api post url
curl_setopt($ch, CURLOPT_COOKIEJAR, $BOUNDARY.'.txt'); //saving cookies just in case we want
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1); // call return content
curl_setopt ($ch, CURLOPT_FOLLOWLOCATION, 1); navigate the endpoint
curl_setopt($ch, CURLOPT_POST, true); //set as post
curl_setopt($ch, CURLOPT_POSTFIELDS, $BODY); // set our $BODY
$response = curl_exec($ch); // start curl navigation
print_r($response); //print response
}
With this we shoud be get on the "api.endpoint.post" the following vars posted You can easly test with this script, and you should be recive this debugs on the function postFile() at the last row
有了这个,我们应该在“api.endpoint.post”上发布以下变量您可以使用此脚本轻松测试,并且您应该在最后一行的函数 postFile() 上接收此调试
print_r($response); //print response
打印_r($响应);//打印响应
public function getPostFile()
{
echo "\n\n_SERVER\n";
echo "<pre>";
print_r($_SERVER['HTTP_X_PARAM_TOKEN']);
echo "/<pre>";
echo "_POST\n";
echo "<pre>";
print_r($_POST['sometext']);
echo "/<pre>";
echo "_FILES\n";
echo "<pre>";
print_r($_FILEST['somefile']);
echo "/<pre>";
}
Here you are it should be work good, could be better solutions but this works and is really helpfull to understand how the Boundary and multipart/from-data mime works on php and curl library,
在这里,它应该工作良好,可能是更好的解决方案,但这确实有效,并且非常有助于了解 Boundary 和 multipart/from-data mime 如何在 php 和 curl 库上工作,
My Best Reggards,
我最好的问候,
my apologies about my english but isnt my native language.
我为我的英语道歉,但不是我的母语。