Requête PHP CURL DELETE


100

J'essaye de faire une demande DELETE http en utilisant PHP et cURL.

J'ai lu comment le faire dans de nombreux endroits, mais rien ne semble fonctionner pour moi.

Voici comment je fais:

public function curl_req($path,$json,$req)
{
    $ch = curl_init($this->__url.$path);
    $data = json_encode($json);
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $req);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json','Content-Length: ' . strlen($data)));
    $result = curl_exec($ch);
    $result = json_decode($result);
    return $result;
}

Je continue ensuite et utilise ma fonction:

public function deleteUser($extid)
{
    $path = "/rest/user/".$extid."/;token=".$this->__token;
    $result = $this->curl_req($path,"","DELETE");
    return $result;

}

Cela me donne une ERREUR de serveur interne HTTP. Dans mes autres fonctions utilisant la même méthode curl_req avec GET et POST, tout se passe bien.

Alors qu'est-ce que je fais de mal?


3
L'erreur interne du serveur signifie qu'il y a eu un problème avec le script recevant votre demande.
Brad

Merci Brad - Je sais, je suppose que c'est parce que ce n'est pas envoyé en tant que demande DELETE. Si j'utilise un plugin client REST pour Firefox et envoie exactement la même requête avec DELETE, cela fonctionne bien. Il semble donc que cURL n'envoie pas la demande en tant que DELETE.
Bolli


Merci Marc, mais on dirait qu'il fait la même chose que moi? Est-il impossible d'envoyer des requêtes DELETE avec PHP? S'il y a un autre moyen sans cURL, je suis ouvert à l'utiliser également.
Bolli

Réponses:


216

J'ai finalement résolu ce problème moi-même. Si quelqu'un d'autre a ce problème, voici ma solution:

J'ai créé une nouvelle méthode:

public function curl_del($path)
{
    $url = $this->__url.$path;
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "DELETE");
    $result = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);

    return $result;
}

Mise à jour 2

Puisque cela semble aider certaines personnes, voici ma dernière méthode curl DELETE, qui renvoie la réponse HTTP dans un objet décodé JSON:

  /**
 * @desc    Do a DELETE request with cURL
 *
 * @param   string $path   path that goes after the URL fx. "/user/login"
 * @param   array  $json   If you need to send some json with your request.
 *                         For me delete requests are always blank
 * @return  Obj    $result HTTP response from REST interface in JSON decoded.
 */
public function curl_del($path, $json = '')
{
    $url = $this->__url.$path;
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "DELETE");
    curl_setopt($ch, CURLOPT_POSTFIELDS, $json);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    $result = curl_exec($ch);
    $result = json_decode($result);
    curl_close($ch);

    return $result;
}

pouvez-vous me dire comment nous appelons ajax au php (méthode: delete) qui contient ce code de suppression de curl et lui transmet la valeur d'ajax?
user1788736

@ user1788736 Je ne suis pas bon en Ajax, mais je suppose que vous pouvez créer un fichier PHP qui exécute cette méthode, et avec Ajax, envoyez vos données en utilisant POST à ​​ce fichier PHP. Si vous pensez que la méthode ci-dessus prête à confusion, regardez à nouveau. $ url est simplement le serveur avec lequel vous devez parler ( someserver.com ) et $ path est le truc après l'URL (/ quelque chose /). La seule raison pour laquelle je les sépare, c'est parce que je dois envoyer au même serveur tout le temps, mais avec des chemins dynamiques. J'espère que cela a du sens.
Bolli le

N'a pas besoin d'en-tête?
er.irfankhan11

J'utilise le même code, et le code http de retour de Paypal: 204 cela signifie supprimer avec succès. mais j'en ai reçu 400 en tout temps.
er.irfankhan11

1
@kuttoozz qui est une variable privée dans ma classe. C'est simplement l'URL à laquelle vous devez faire des demandes. Cela pourrait être quelque chose comme api.someurl.com et $ path est ce qui suit cette URL (/ quelque chose /). Vous pouvez simplement changer cette valeur en votre URL ou la supprimer et inclure l'URL complète dans la variable $ path. Cela a-t-il du sens?
Bolli

19

Pour appeler GET, POST, DELETE, PUT Tout type de demande, j'ai créé une fonction commune

function CallAPI($method, $api, $data) {
    $url = "http://localhost:82/slimdemo/RESTAPI/" . $api;
    $curl = curl_init($url);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);

    switch ($method) {
        case "GET":
            curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($data));
            curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "GET");
            break;
        case "POST":
            curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($data));
            curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "POST");
            break;
        case "PUT":
            curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($data));
            curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "PUT");
            break;
        case "DELETE":
            curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "DELETE"); 
            curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($data));
            break;
    }
    $response = curl_exec($curl);
    $data = json_decode($response);

    /* Check for 404 (file not found). */
    $httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
    // Check the HTTP Status code
    switch ($httpCode) {
        case 200:
            $error_status = "200: Success";
            return ($data);
            break;
        case 404:
            $error_status = "404: API Not found";
            break;
        case 500:
            $error_status = "500: servers replied with an error.";
            break;
        case 502:
            $error_status = "502: servers may be down or being upgraded. Hopefully they'll be OK soon!";
            break;
        case 503:
            $error_status = "503: service unavailable. Hopefully they'll be OK soon!";
            break;
        default:
            $error_status = "Undocumented error: " . $httpCode . " : " . curl_error($curl);
            break;
    }
    curl_close($curl);
    echo $error_status;
    die;
}

CALL Delete, méthode

$data = array('id'=>$_GET['did']);
$result = CallAPI('DELETE', "DeleteCategory", $data);

CALL Post Méthode

$data = array('title'=>$_POST['txtcategory'],'description'=>$_POST['txtdesc']);
$result = CallAPI('POST', "InsertCategory", $data);

CALL Get, méthode

$data = array('id'=>$_GET['eid']);
$result = CallAPI('GET', "GetCategoryById", $data);

CALL Put, méthode

$data = array('id'=>$_REQUEST['eid'],m'title'=>$_REQUEST['txtcategory'],'description'=>$_REQUEST['txtdesc']);
$result = CallAPI('POST', "UpdateCategory", $data);

bien joué. Juste une note: le code de réponse http pour la suppression est 204. Je pense que vous devriez considérer tous les codes 20x comme une bonne réponse :)
ryuujin

0

Ma propre demande de classe avec authentification WSSE

class Request {

    protected $_url;
    protected $_username;
    protected $_apiKey;

    public function __construct($url, $username, $apiUserKey) {
        $this->_url = $url;     
        $this->_username = $username;
        $this->_apiKey = $apiUserKey;
    }

    public function getHeader() {
        $nonce = uniqid();
        $created = date('c');
        $digest = base64_encode(sha1(base64_decode($nonce) . $created . $this->_apiKey, true));

        $wsseHeader = "Authorization: WSSE profile=\"UsernameToken\"\n";
        $wsseHeader .= sprintf(
            'X-WSSE: UsernameToken Username="%s", PasswordDigest="%s", Nonce="%s", Created="%s"', $this->_username, $digest, $nonce, $created
        );

        return $wsseHeader;
    }

    public function curl_req($path, $verb=NULL, $data=array()) {                    

        $wsseHeader[] = "Accept: application/vnd.api+json";
        $wsseHeader[] = $this->getHeader();

        $options = array(
            CURLOPT_URL => $this->_url . $path,
            CURLOPT_HTTPHEADER => $wsseHeader,
            CURLOPT_RETURNTRANSFER => true, 
            CURLOPT_HEADER => false             
        );                  

        if( !empty($data) ) {
            $options += array(
                CURLOPT_POSTFIELDS => $data,
                CURLOPT_SAFE_UPLOAD => true
            );                          
        }

        if( isset($verb) ) {
            $options += array(CURLOPT_CUSTOMREQUEST => $verb);                          
        }

        $ch = curl_init();
        curl_setopt_array($ch, $options);
        $result = curl_exec($ch);                   

        if(false === $result ) {
            echo curl_error($ch);
        }
        curl_close($ch);

        return $result; 
    }
}

use + = instaead of array_merge
Adriwan Kenoby

Cela fonctionne probablement, mais c'est une solution inutilement complexe au problème.
Samuel Lindblom

0

switch ($ method) {case "GET": curl_setopt ($ curl, CURLOPT_CUSTOMREQUEST, "GET"); Pause; case "POST": curl_setopt ($ curl, CURLOPT_CUSTOMREQUEST, "POST"); Pause; case "PUT": curl_setopt ($ curl, CURLOPT_CUSTOMREQUEST, "PUT"); Pause; case "DELETE": curl_setopt ($ curl, CURLOPT_CUSTOMREQUEST, "DELETE"); Pause; }


-19
    $json empty

public function deleteUser($extid)
{
    $path = "/rest/user/".$extid."/;token=".$this->__token;
    $result = $this->curl_req($path,"**$json**","DELETE");
    return $result;

}

Merci. Dans cet appel REST particulier, la partie JSON doit être vide, donc ce n'est pas un problème. Mais merci quand même
Bolli

Que veut $json emptydire ici? Ce n'est de toute façon pas dans la portée de cette fonction, donc l'utilisation de $jsonne fera rien.
halfer

J'ai demandé que cette réponse soit supprimée, mais un modérateur a dit non. L'affiche de cette réponse ne s'est de toute façon pas connectée depuis 2014.
halfer
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.