PHP Envoi de données multidimensionnelles et de fichiers multiples avec CurlFile en une seule requête


Exemple

Disons que nous avons un formulaire comme celui ci-dessous. Nous voulons envoyer les données à notre serveur Web via AJAX et de là à un script exécuté sur un serveur externe.

C'est le formulaire que nous voulons envoyer

Nous avons donc des entrées normales, un champ multi-sélection et une zone de dépôt de fichiers où nous pouvons télécharger plusieurs fichiers.

En supposant que la requête AJAX POST a réussi, nous obtenons les données suivantes sur le site PHP:

// print_r($_POST)

Array
(
    [first_name] => John
    [last_name] => Doe
    [activities] => Array
        (
            [0] => soccer
            [1] => hiking
        )
)

et les fichiers devraient ressembler à ceci

// print_r($_FILES)

Array
(
    [upload] => Array
        (
            [name] => Array
                (
                    [0] => my_photo.jpg
                    [1] => my_life.pdf
                )

            [type] => Array
                (
                    [0] => image/jpg
                    [1] => application/pdf
                )

            [tmp_name] => Array
                (
                    [0] => /tmp/phpW5spji
                    [1] => /tmp/phpWgnUeY
                )

            [error] => Array
                (
                    [0] => 0
                    [1] => 0
                )

            [size] => Array
                (
                    [0] => 647548
                    [1] => 643223
                )

        )

)

Jusqu'ici tout va bien. Maintenant, nous voulons envoyer ces données et fichiers au serveur externe en utilisant cURL avec la classe CurlFile

Comme cURL n'accepte qu'un tableau simple mais pas multidimensionnel, nous devons d'abord aplatir le tableau $ _POST.

Pour ce faire, vous pouvez par exemple utiliser cette fonction qui vous donne les informations suivantes:

// print_r($new_post_array)

Array
(
    [first_name] => John
    [last_name] => Doe
    [activities[0]] => soccer
    [activities[1]] => hiking
)

L'étape suivante consiste à créer des objets CurlFile pour les fichiers téléchargés. Cela se fait par la boucle suivante:

$files = array();

foreach ($_FILES["upload"]["error"] as $key => $error) {
    if ($error == UPLOAD_ERR_OK) {

        $files["upload[$key]"] = curl_file_create(
            $_FILES['upload']['tmp_name'][$key],
            $_FILES['upload']['type'][$key],
            $_FILES['upload']['name'][$key]
        );
    }
}

curl_file_create est une fonction d'assistance de la classe CurlFile et crée les objets CurlFile. Nous sauvegardons chaque objet dans le tableau $ files avec les clés nommées "upload [0]" et "upload [1]" pour nos deux fichiers.

Nous devons maintenant combiner le tableau de courrier aplati et le tableau de fichiers et l'enregistrer en tant que données $ comme ceci:

$data = $new_post_array + $files;

La dernière étape consiste à envoyer la demande cURL:

$ch = curl_init();

curl_setopt_array($ch, array(
    CURLOPT_POST => 1,
    CURLOPT_URL => "https://api.externalserver.com/upload.php",
    CURLOPT_RETURNTRANSFER => 1,
    CURLINFO_HEADER_OUT => 1,
    CURLOPT_POSTFIELDS => $data
));

$result = curl_exec($ch);

curl_close ($ch);

Puisque $ data est désormais un tableau simple (plat), cURL envoie automatiquement cette requête POST avec le type de contenu: multipart / form-data

Dans upload.php sur le serveur externe, vous pouvez maintenant obtenir les données et les fichiers avec $ _POST et $ _FILES comme vous le feriez normalement.