web-dev-qa-db-fra.com

Télécharger un fichier à l'aide de Guzzle 6 vers le point de terminaison de l'API

Je suis en mesure de télécharger un fichier sur un noeud final d'API à l'aide de Postman.

J'essaie de traduire cela en téléchargeant un fichier à partir d'un formulaire, en le téléchargeant à l'aide de Laravel et en l'envoyant sur le terminal à l'aide de Guzzle 6.

Capture d'écran de l'apparence dans Postman (j'ai volontairement oublié l'URL POST)  enter image description here

Vous trouverez ci-dessous le texte qu'il génère lorsque vous cliquez sur le lien "Générer du code" dans POSTMAN:

POST /api/file-submissions HTTP/1.1
Host: strippedhostname.com
Authorization: Basic 340r9iu34ontoeioir
Cache-Control: no-cache
Postman-Token: 6e0c3123-c07c-ce54-8ba1-0a1a402b53f1
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW

----WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="FileContents"; filename=""
Content-Type: 


----WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="FileInfo"

{ "name": "_aaaa.txt", "clientNumber": "102425", "type": "Writeoff" }
----WebKitFormBoundary7MA4YWxkTrZu0gW

Ci-dessous, la fonction du contrôleur pour enregistrer le fichier et d’autres informations. Le fichier est chargé correctement, je peux obtenir les informations sur le fichier.

Je pense que le problème que je rencontre est la configuration du tableau multipart et des en-têtes avec les données correctes.

public function fileUploadPost(Request $request)
{
    $data_posted = $request->input();
    $endpoint = "/file-submissions";
    $response = array();
    $file = $request->file('filename');
    $name = time() . '_' . $file->getClientOriginalName();
    $path = base_path() .'/public_html/documents/';

    $resource = fopen($file,"r") or die("File upload Problems");

    $file->move($path, $name);

    // { "name": "test_upload.txt", "clientNumber": "102425", "type": "Writeoff" }
    $fileinfo = array(
        'name'          =>  $name,
        'clientNumber'  =>  "102425",
        'type'          =>  'Writeoff',
    );

    $client = new \GuzzleHttp\Client();

    $res = $client->request('POST', $this->base_api . $endpoint, [
        'auth' => [env('API_USERNAME'), env('API_PASSWORD')],
        'multipart' => [
            [
                'name'  =>  $name,
                'FileContents'  => fopen($path . $name, 'r'),
                'contents'      => fopen($path . $name, 'r'),
                'FileInfo'      => json_encode($fileinfo),
                'headers'       =>  [
                    'Content-Type' => 'text/plain',
                    'Content-Disposition'   => 'form-data; name="FileContents"; filename="'. $name .'"',
                ],
                // 'contents' => $resource,
            ]
        ],
    ]);

    if($res->getStatusCode() != 200) exit("Something happened, could not retrieve data");

    $response = json_decode($res->getBody());

    var_dump($response);
    exit();
}

L'erreur que je reçois, capture d'écran de son affichage à l'aide de la vue de débogage de Laravel:

 enter image description here

20
Brad

La manière dont vous publiez des données est incorrecte, les données reçues sont donc mal formées.

Guzzle docs :

La valeur de multipart est un tableau de tableaux associatifs, chacun contenant les paires de valeurs de clé suivantes:

name: (chaîne, obligatoire) le nom du champ de formulaire

contents :( StreamInterface/resource/string, requis) Données à utiliser dans le fichier élément de formulaire.

headers: (array) Tableau associatif facultatif d'en-têtes personnalisés à utiliser avec l'élément de formulaire.

filename: (string) Facultatif chaîne à envoyer comme nom de fichier dans la partie.

L'utilisation de clés hors de la liste ci-dessus et la définition d'en-têtes inutiles sans séparer chaque champ dans un tableau entraîneront une requête incorrecte.

$res = $client->request('POST', $this->base_api . $endpoint, [
    'auth'      => [ env('API_USERNAME'), env('API_PASSWORD') ],
    'multipart' => [
        [
            'name'     => 'FileContents',
            'contents' => file_get_contents($path . $name),
            'filename' => $name
        ],
        [
            'name'     => 'FileInfo',
            'contents' => json_encode($fileinfo)
        ]
    ],
]);
32
revo
$body = fopen('/path/to/file', 'r');
$r = $client->request('POST', 'http://httpbin.org/post', ['body' => $body]);

http://docs.guzzlephp.org/en/latest/quickstart.html?highlight=file

0
Pawel