Richiesta PHP CURL DELETE


100

Sto cercando di eseguire una richiesta DELETE http utilizzando PHP e cURL.

Ho letto come farlo in molti posti, ma niente sembra funzionare per me.

Ecco come lo faccio:

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

Quindi vado avanti e uso la mia funzione:

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

}

Questo mi dà ERRORE server interno HTTP. Nelle mie altre funzioni che utilizzano lo stesso metodo curl_req con GET e POST, tutto va bene.

Allora cosa sto facendo di sbagliato?


3
L'errore interno del server indica che si è verificato un problema con lo script che ha ricevuto la tua richiesta.
Brad

Grazie Brad - Lo so, immagino sia perché non è inviato come richiesta DELETE. Se utilizzo un plug-in client REST per Firefox e invio la stessa identica richiesta con DELETE, funziona bene. Quindi sembra che cURL non invii la richiesta come DELETE.
Bolli


Grazie Marc, ma sembra che stia facendo la stessa cosa di me? È impossibile inviare richieste DELETE con PHP? Se c'è un altro modo senza cURL, sono disponibile a usarlo anche io.
Bolli

Risposte:


216

Alla fine l'ho risolto da solo. Se qualcun altro ha questo problema, ecco la mia soluzione:

Ho creato un nuovo metodo:

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

Aggiorna 2

Poiché questo sembra aiutare alcune persone, ecco il mio metodo DELETE curl finale, che restituisce la risposta HTTP nell'oggetto decodificato 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;
}

puoi dirmi come facciamo a chiamare ajax il php (metodo: delete) che contiene questo codice di cancellazione curl e gli passa il valore da ajax?
user1788736

@ user1788736 Non sono bravo con Ajax, ma immagino che potresti creare un file PHP che esegua questo metodo e con Ajax inviare i tuoi dati usando POST a quel file PHP. Se pensi che il metodo sopra sia confuso, guarda di nuovo. $ url è semplicemente il server con cui devi parlare ( someserver.com ) e $ path è il materiale dopo l'URL (/ qualcosa /). L'unico motivo per cui li ho divisi è perché devo inviare sempre allo stesso server, ma con percorsi dinamici. Spero che abbia un senso.
Bolli

Non serve l'intestazione?
er

Sto usando lo stesso codice e Paypal restituisce il codice http: 204 significa eliminare con successo. ma ho ricevuto 400 in tutto il tempo.
er Irfankhan11

1
@kuttoozz che è una variabile privata nella mia classe. È semplicemente l'URL a cui devi effettuare richieste. Potrebbe essere qualcosa come api.someurl.com e $ path è ciò che va dopo quell'URL (/ qualcosa /). Puoi semplicemente modificare quel valore nel tuo URL o rimuoverlo e includere l'URL completo nella variabile $ path. Ha senso?
Bolli

19

Per chiamare GET, POST, DELETE, PUT Tutti i tipi di richiesta, ho creato una funzione comune

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

Metodo di eliminazione CALL

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

Metodo CALL Post

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

CALL Get Method

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

Metodo Put CALL

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

molto bene. Solo una nota: il codice di risposta http per l'eliminazione è 204. Penso che dovresti considerare tutti i codici 20x come una buona risposta :)
ryuujin

0

La mia richiesta di classe con autenticazione 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; 
    }
}

utilizzare + = instaead di array_merge
Adriwan Kenoby

Probabilmente funziona, ma è una soluzione inutilmente complessa al problema.
Samuel Lindblom,

0

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


-19
    $json empty

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

}

Grazie. In questa particolare chiamata REST, la parte JSON deve essere vuota, quindi questo non è un problema. Ma grazie comunque
Bolli

Cosa $json emptysignifica qui? Non è comunque nell'ambito di questa funzione, quindi l'utilizzo di $jsonnon farà nulla.
halfer

Ho chiesto la cancellazione di questa risposta, ma un moderatore ha detto no. Il poster di questa risposta non si è comunque iscritto dal 2014.
halfer
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.