在PHP中通过表单POST通过cURL发送文件

我正在写一个API,我想要处理从表单POSTfile upload。 表单的标记不是太复杂:

 <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', ... ); 

那么这是哪个文件path? 我在哪里可以find它? 它会像$_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'] } 

下面是一些生成代码,将文件发送到一个FTP(可能是一个很好的解决scheme):

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

对于查找这篇文章和使用PHP5.5 +的人来说 ,这可能会有所帮助。

我发现netcoderbuild议的方法不起作用。 即这不起作用:

 $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。

事实certificate,对于php5.5 + ,你需要使用一个新的curl_file_create()函数。 所以上面会变成:

 $data = array( 'uploaded_file' => curl_file_create($tmpfile, $_FILES['image']['type'], $filename) ); 

由于@格式现已被弃用。

这应该工作:

 $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 ) ) */ 

然后,如果你想正确处理file upload,你可以这样做:

 if (move_uploaded_file($_FILES['uploaded_file'], '/path/to/destination/file.zip')) { // do stuff } 

因为我的@符号不起作用,所以我做了一些调查,发现这种方式,它为我工作,我希望这可以帮助你。

  $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; } 

通过邮件系统发送附件到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; } 

程序方法中的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); 

我们可以通过curl请求上传图片文件,将它转换成base64 string。所以在后期我们会发送文件string,然后在图片中隐藏这个。

 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

这是我的解决scheme,我一直在阅读很多post,他们真的很有帮助,最后我build立一个小文件的代码,与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 } 

有了这个,我们应该得到的“api.endpoint.post”下面的variables你可以很容易地testing这个脚本,你应该recive这个debugging函数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>"; } 

在这里,你应该是工作好,可能是更好的解决scheme,但这个工作,是真正有用的了解如何边界和multipart / from-data mime工作在PHP和curl库,

我最好的Reggards,

我的道歉我的英文,但不是我的母语。