Utilisation de curl pour télécharger des données POST avec des fichiers

Je voudrais utiliser cURL non seulement pour envoyer des paramètres de données dans HTTP POST, mais aussi pour télécharger des fichiers avec un nom de formulaire spécifique. Comment dois-je faire ?

Paramètres HTTP Post:

Userid = 12345 filecomment = c'est un fichier image

Téléchargement de fichier HTTP: Emplacement du fichier = /home/user1/Desktop/test.jpg Nom du formulaire pour file = image (correspond au $_FILES['image'] du côté PHP)

J'ai figuré une partie de la commande cURL comme suit:

curl -d "userid=1&filecomment=This is an image file" --data-binary @"/home/user1/Desktop/test.jpg" localhost/uploader.php

Le le problème que je reçois est le suivant:

Notice: Undefined index: image in /var/www/uploader.php

Le problème est que j'utilise $_FILES ['image'] pour récupérer des fichiers dans le script PHP.

Comment ajuster mes commandes cURL en conséquence ?

306
demandé sur KARTHIKEYAN.A 2012-10-01 09:10:56

6 réponses

, Vous devez utiliser le -F option:
-F/--form <name=content> Specify HTTP multipart POST data (H)

, Essayez ceci:

curl \
  -F "userid=1" \
  -F "filecomment=This is an image file" \
  -F "image=@/home/user1/Desktop/test.jpg" \
  localhost/uploader.php
500
répondu jimp 2015-11-05 12:44:57

Capture de l'id utilisateur en tant que variable path (recommandé):

curl -i -X POST -H "Content-Type: multipart/form-data" 
-F "data=@test.mp3" http://mysuperserver/media/1234/upload/

Capture de l'id utilisateur dans le cadre du formulaire:

curl -i -X POST -H "Content-Type: multipart/form-data" 
-F "data=@test.mp3;userid=1234" http://mysuperserver/media/upload/

Ou:

curl -i -X POST -H "Content-Type: multipart/form-data" 
-F "data=@test.mp3" -F "userid=1234" http://mysuperserver/media/upload/
64
répondu r1ckr 2018-06-29 13:28:03

Voici ma solution, j'ai lu beaucoup de messages et ils étaient vraiment utiles. Enfin, j'ai écrit du code pour les petits fichiers, avec cURL et PHP que je pense 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 cela, nous devrions être sur l'api".terminaison.poster " les vars suivants affichés. Vous pouvez facilement tester avec ce script, et vous devriez recevoir ce débogue sur la fonction postFile() à la dernière ligne.

print_r($response); //print response

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

Cela devrait bien fonctionner, ils peuvent être de meilleures solutions mais cela fonctionne et est vraiment utile pour comprendre comment le mime Boundary et multipart / from-data fonctionne sur la bibliothèque PHP et cURL.

21
répondu Libertese 2015-02-23 16:52:05

Si vous téléchargez un fichier binaire comme csv, utilisez format ci-dessous pour télécharger le fichier

curl -X POST \
    'http://localhost:8080/workers' \
    -H 'authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6ImFjY2VzcyIsInR5cGUiOiJhY2Nlc3MifQ.eyJ1c2VySWQiOjEsImFjY291bnRJZCI6MSwiaWF0IjoxNTExMzMwMzg5LCJleHAiOjE1MTM5MjIzODksImF1ZCI6Imh0dHBzOi8veW91cmRvbWFpbi5jb20iLCJpc3MiOiJmZWF0aGVycyIsInN1YiI6ImFub255bW91cyJ9.HWk7qJ0uK6SEi8qSeeB6-TGslDlZOTpG51U6kVi8nYc' \
    -H 'content-type: application/x-www-form-urlencoded' \
    --data-binary '@/home/limitless/Downloads/iRoute Masters - Workers.csv'
3
répondu KARTHIKEYAN.A 2017-11-27 11:13:09

Voici comment échapper correctement les noms de fichiers arbitraires des fichiers téléchargés avec bash:

#!/bin/bash
set -eu

f="$1"
f=${f//\\/\\\\}
f=${f//\"/\\\"}
f=${f//;/\\;}

curl --silent --form "uploaded=@\"$f\"" "$2"
1
répondu Vladimir Panteleev 2016-10-06 21:28:39

Comme alternative à curl, vous pouvez utiliser HTTPie , c'est un CLI, un outil de type cURL pour les humains.

  1. Instructions d'Installation: https://github.com/jakubroztocil/httpie#installation

  2. Ensuite, exécutez:

    http -f POST http://localhost:4040/api/users username=johnsnow photo@images/avatar.jpg
    
    HTTP/1.1 200 OK
    Access-Control-Expose-Headers: X-Frontend
    Cache-control: no-store
    Connection: keep-alive
    Content-Encoding: gzip
    Content-Length: 89
    Content-Type: text/html; charset=windows-1251
    Date: Tue, 26 Jun 2018 11:11:55 GMT
    Pragma: no-cache
    Server: Apache
    Vary: Accept-Encoding
    X-Frontend: front623311
    
    ...
    
0
répondu Gianfranco P. 2018-06-26 11:18:58