PHP : Envoyer un fichier avec WP_Http

Le 11 novembre 2013 — par

Pour mon extension Posts to ADN j’avais besoin d’utiliser la classe WP_Http pour envoyer des fichiers.

C’est très simple avec cURL, il suffit basiquement de mettre le chemin complet du fichier avec un @ devant pour déclencher l’upload (avec l’option cURL « upload » associée). Il n’y a rien de tel avec WP_Http et pour assurer la compatibilité avec tous les hébergements on ne peut pas juste se contenter de cURL.

Il faut donc recréer le payload entier et l’envoyer au serveur en POST.

J’ai fait une fonction qui émule le comportement de cURL avec le @ devant le nom du fichier, ainsi l’appel de la fonction se fait ainsi par exemple1 :

wordpress_upload_file(
    'http://www.example.com',
    array(
        'title' => 'My picture',
        'picture' => '@/path/to/my/image.png'
    )
);

Très simple, n’est-ce pas ? La fonction est ci-dessous. N’hésitez pas à la réutiliser (en changeant le préfixe wordpress_ ou à intégrer dans une classe pour éviter tout conflit) :

function wordpress_upload_file( $url, $params = array() ) {

    $data     = null;
    $request  = new WP_Http;
    $boundary = uniqid();
    $payload  = '';

    foreach ( $params as $name => $value ) {

        if ( preg_match( '/^@(.+)$/', $value, $r ) && file_exists( $r[1] ) ) {

            $payload .= '--' . $boundary;
            $payload .= "rn";
            $payload .= 'Content-Disposition: form-data; name="' . $name . '"; filename="' . basename( $r[1] ) . '"' . "rn";
            $payload .= 'Content-Type: ' . $r[2] . "rn";
            $payload .= "rn";
            $payload .= file_get_contents( $r[1] );
            $payload .= "rn";

        } else {

            $payload .= '--' . $boundary;
            $payload .= "rn";
            $payload .= 'Content-Disposition: form-data; name="' . $name . '"' . "rnrn";
            $payload .= $value;
            $payload .= "rn";

        }

    }

    $payload .= '--' . $boundary . '--';

    $result = $request->request(
        $url,
        array(
            'method' => 'POST',
            'body' => $payload,
            'headers' => array(
                'Content-type' => 'multipart/form-data; boundary=' . $boundary,
            )
        )
    );

    if ( is_array( $result ) && isset( $result['response']['code'] ) && 200 === $result['response']['code'] ) {

        $data = $result['body'];

    }

    return $data;

}

Si le retour n’est pas nul et que le code de réponse HTTP est synonyme de succès, vous récupérez la réponse du serveur. À modifier bien sûr pour gérer les différentes erreurs qui pourraient arriver en fonction du service avec lequel vous communiquez.


  1. Désolé pour la tronche de la syntaxe, ce sont les Coding Standards de WordPress

S'abonner au flux RSS du blog
Recevoir les nouveaux articles par e-mail :