Отправить файл через cURL из формы POST в PHP

Я пишу 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.

Я знаком с отправкой запросов POST с помощью cURL с массивом данных, а ресурсы, которые я прочитал при загрузке файлов, говорят мне, чтобы префикс имени файла обозначался символом @ . Но эти же ресурсы имеют жестко закодированное имя файла, например

 $post = array( 'image' => '@/path/to/myfile.jpg', ... ); 

Ну, какой путь к файлу это? Где я его найду? Было бы что-то вроде $_FILES['image']['tmp_name'] , и в этом случае мой $post array должен выглядеть так:

 $post = array( 'image' => '@' . $_FILES['image']['tmp_name'], ... ); 

Или я об этом ошибаюсь? Любые советы будут оценены наиболее высоко.

EDIT: Если бы кто-то мог дать мне фрагмент кода, где бы я пошел со следующими фрагментами кода, я был бы очень благодарен. Я в основном после того, что я буду отправлять как параметры 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'] } 

Related of "Отправить файл через cURL из формы POST в PHP"

Вот какой производственный код, который отправляет файл в 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); 

Для людей, которые находят этот пост и используют 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) ); 

Поскольку формат @ теперь устарел.

Это должно работать:

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

Для меня символ @ не работал, поэтому я делаю некоторые исследования и нашел этот способ, и он работает для меня, я надеюсь, что это поможет вам.

  $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 через систему обмена сообщениями.

Ответ на вопрос 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'); 

Объект cURL в методе Oop:

 $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.So в сообщении мы отправим строку файла, а затем скрываем это в изображении.

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

затем отправьте его в запрос на завивание

 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

Вот мое решение, я читал много сообщений, и они были очень полезны, окончательно я создаю код для небольших файлов с 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 } - 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» следующие опубликованные 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>"; } - 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>"; } 

Здесь вы должны работать хорошо, могли бы быть более эффективными решениями, но это работает, и очень полезно понять, как миг Boundary и multipart / from-data работает в php и curl library,

Мои лучшие регги,

мои извинения за мой английский, но не мой родной язык.