我正在编写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>
但是,我很难理解如何处理此服务器端并发送cURL请求。
我熟悉使用cURL向数据阵列发送POST
个请求,而我在上传文件时读到的资源告诉我在文件名前添加@
符号。但是这些相同的资源具有硬编码的文件名,例如
$post = array(
'image' => '@/path/to/myfile.jpg',
...
);
这是哪个文件路径?我在哪里可以找到它?它会是$_FILES['image']['tmp_name']
,在这种情况下,我的$post
数组应如下所示:
$post = array(
'image' => '@' . $_FILES['image']['tmp_name'],
...
);
或者我是以错误的方式来做这件事的?任何建议都会非常感激。
编辑:如果有人可以给我一个代码片段,我将使用以下代码片段,那么我将非常感激。我主要关注我将作为cURL参数发送的内容,以及如何将这些参数与接收脚本一起使用的示例(为了参数,我们将其称为curl_receiver.php
)。
我有这个网页表单:
<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>
这将是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']
}
答案 0 :(得分:56)
以下是一些将文件发送到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@email.org: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);
答案 1 :(得分:43)
对于发现此帖并使用 PHP5.5 + 的人来说,这可能有所帮助。
我发现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);
我会在$_POST
var 'uploaded_file'
字段中收到 - 并且$_FILES
var中没有任何内容。
事实证明,对于 php5.5 + ,您需要使用新的curl_file_create()
功能。所以上面会变成:
$data = array(
'uploaded_file' => curl_file_create($tmpfile, $_FILES['image']['type'], $filename)
);
由于@
格式现已弃用。
答案 2 :(得分:27)
这应该有效:
$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);
在接收脚本中,您将拥有:
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
)
)
*/
然后,如果你想正确处理文件上传,你可以这样做:
if (move_uploaded_file($_FILES['uploaded_file'], '/path/to/destination/file.zip')) {
// do stuff
}
答案 3 :(得分:10)
因为我的@符号不起作用,所以我做了一些研究并找到了这种方式,它对我有用,我希望这对你有所帮助。
$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;
}
答案 4 :(得分:3)
通过其邮件系统向Mercadolibre发送附件时,它适用于我。
anwswer 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;
}
答案 5 :(得分:1)
程序方法中的cURL文件对象:
$file = curl_file_create('full path/filename','extension','filename');
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);
答案 6 :(得分:-1)
我们可以通过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);
}
}
然后在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);
}
见http://technoblogs.co.in/blog/How-to-upload-an-image-by-using-php-curl-request/118
答案 7 :(得分:-3)
这是我的解决方案,我一直在阅读很多帖子,他们真的很有帮助,最后我用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
}
有了这个,我们应该得到&#34; api.endpoint.post&#34;发布了以下vars 您可以使用此脚本轻松测试,并且您应该在最后一行的函数postFile()上重温此调试
的print_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>";
}
在这里,你应该工作得很好,可能是更好的解决方案,但这有效,并且非常有助于理解边界和multipart / from-data mime如何在php和curl库上工作,
我最好的问候,
我对我的英语表示道歉,但不是我的母语。