Envoyer le fichier via cURL à partir du formulaire POST en PHP

j'écris une API et je veux gérer les téléchargements de fichiers à partir d'un formulaire POST. Le balisage de la forme n'est rien de trop complexe:

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

cependant, j'ai des difficultés à comprendre comment gérer ce côté serveur et envoyer avec une requête cURL.

je suis familier avec l'envoi d' POST requêtes avec cURL avec un tableau de données, et les ressources que j'ai lues lors du téléchargement de fichiers me disent de préfixer le nom du fichier avec un @ symbole. Mais ces mêmes ressources avoir un nom de fichier codé, par exemple

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

Eh bien, quel chemin de fichier s'agit-il? Où puis-je la trouver? Serait-il quelque chose comme $_FILES['image']['tmp_name'], auquel cas mon $post tableau devrait ressembler à ceci:

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

ou est-ce que je m'y prends mal? Tout conseil serait grandement apprécié.

EDIT: si quelqu'un pouvait me donner un extrait de code d'où j'irais avec les extraits de code suivants, alors je vous en serais très reconnaissant. Je suis surtout après l' ce que j'enverrais comme paramètres cURL, et un exemple d'utilisation de ces paramètres avec le script de réception (appelons-le curl_receiver.php pour la commodité du raisonnement).

j'ai ce formulaire web:

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

Et ce serait 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']
}
37
demandé sur think123 2010-11-19 13:09:32

8 réponses

voici un code de production qui envoie le fichier à un ftp (peut être une bonne solution pour vous):

// 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);
55
répondu Jeff Davis 2014-05-08 14:22:59

Pour les gens de trouver ce post et à l'aide de PHP5.5+, ce qui pourrait aider.

je trouvais que l'approche suggérée par netcoder ne fonctionnait pas. ce qui ne fonctionne pas:

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

je voudrais recevoir dans le $_POST var 'uploaded_file' champ - et rien dans le $_FILES var.

Il s'avère que pour php5.5+ il y a un nouveau curl_file_create() fonction, vous devez utiliser. Ci-dessus devient:

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

@ le format est maintenant obsolète.

39
répondu CharlesA 2017-01-19 09:31:32

Cela devrait fonctionner:

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

Dans le script, vous devrez:

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

ensuite, si vous voulez gérer correctement le téléchargement de fichier, vous feriez quelque chose comme ceci:

if (move_uploaded_file($_FILES['uploaded_file'], '/path/to/destination/file.zip')) {
   // do stuff
}
26
répondu netcoder 2013-01-20 20:09:24

pour mon le @ symbole n'a pas fonctionné, donc je fais quelques recherches et j'ai trouvé cette façon et cela fonctionne pour moi, j'espère que cela vous aide.

    $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;
    }   
7
répondu Joacer 2016-02-05 14:54:36

cela fonctionne pour moi lors de l'envoi d'une pièce jointe à Mercadolibre, à travers son système de messagerie.

Le 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;
}   
3
répondu otharwa 2017-07-01 03:29:24

cURL fichier objet dans la méthode procédurale:

$file = curl_file_create('full path/filename','extension','filename');

cURL fichier objet en programmation orientée objet, méthode:

$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);
1
répondu lalithkumar 2017-05-11 05:25:24

nous pouvons télécharger le fichier image par requête curl en le convertissant en chaîne base64.Ainsi, en post, nous enverrons la chaîne de fichier et la couvrirons dans une image.

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

puis l'envoyer en curl request

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

-1
répondu Prabhat Bhardwaj 2017-11-02 13:09:33

Voici ma solution, j'ai lu beaucoup de post et c'était vraiment utile, finalement je construis un code pour les petits fichiers, avec cUrl et Php, que je pense que c'est vraiment utile.

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

}

avec ceci nous devrions être sur l'api".terminaison.post" vars posté Vous pouvez facilement tester avec ce script, et vous devriez recevoir ce debugs sur la fonction postFile () à la dernière ligne

print_r($response); //imprimer réponse

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

Ici vous êtes il devrait être bon travail, pourrait être de meilleures solutions mais cela fonctionne et est vraiment utile pour comprendre comment la frontière et multipart / à partir de données mime fonctionne sur php et bibliothèque curl,

Mon Meilleur Reggards,

mes excuses sur mon anglais mais n'est pas ma langue maternelle.

-3
répondu Libertese 2014-04-21 23:49:43