PHP CURL DELETE Anfrage

100

Ich versuche, eine DELETE http-Anfrage mit PHP und cURL zu machen.

Ich habe an vielen Stellen gelesen, wie es geht, aber nichts scheint für mich zu funktionieren.

So mache ich es:

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

Ich gehe dann voran und benutze meine Funktion:

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

}

Dies gibt mir HTTP internen Server FEHLER. In meinen anderen Funktionen, die dieselbe curl_req-Methode mit GET und POST verwenden, läuft alles gut.

Also, was mache ich falsch?

Bolli
quelle
3
Der interne Serverfehler bedeutet, dass ein Problem mit dem Skript aufgetreten ist, das Ihre Anfrage empfangen hat.
Brad
Danke Brad - ich weiß, ich denke, es liegt daran, dass es nicht als DELETE-Anfrage gesendet wird. Wenn ich ein REST-Client-Plugin für Firefox verwende und genau dieselbe Anfrage mit DELETE sende, funktioniert es einwandfrei. Es scheint also, als würde cURL die Anfrage nicht als DELETE senden.
Bolli
Danke Marc, aber es scheint, als würde er dasselbe tun wie ich? Ist es unmöglich, DELETE-Anfragen mit PHP zu senden? Wenn es einen anderen Weg ohne CURL gibt, bin ich auch offen dafür.
Bolli

Antworten:

216

Ich habe das endlich selbst gelöst. Wenn jemand anderes dieses Problem hat, ist hier meine Lösung:

Ich habe eine neue Methode erstellt:

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

Update 2

Da dies einigen Leuten zu helfen scheint, ist hier meine letzte Curl-DELETE-Methode, die die HTTP-Antwort in einem JSON-dekodierten Objekt zurückgibt:

  /**
 * @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;
}
Bolli
quelle
Kannst du mir sagen, wie wir einen Ajax-Aufruf an das PHP (Methode: delete) ausführen, das diesen Löschcurl-Code enthält, und ihm den Wert von Ajax übergeben?
user1788736
@ user1788736 Ich bin nicht gut in Ajax, aber ich denke, Sie könnten eine PHP-Datei erstellen, die diese Methode ausführt, und mit Ajax Ihre Daten per POST an diese PHP-Datei senden. Wenn Sie der Meinung sind, dass die oben beschriebene Methode verwirrend ist, schauen Sie noch einmal. $ url ist einfach der Server, mit dem Sie sprechen müssen ( someserver.com ), und $ path ist das Zeug nach der URL (/ Something /). Der einzige Grund, warum ich diese aufteilte, ist, dass ich die ganze Zeit an denselben Server senden muss, aber mit dynamischen Pfaden. Hoffe das macht Sinn.
Bolli
Benötigen Sie keinen Header?
er.irfankhan11
Ich verwende den gleichen Code und Paypal gibt den http-Code zurück: 204 bedeutet, dass er erfolgreich gelöscht wurde. aber ich habe immer 400 erhalten.
er.irfankhan11
1
@kuttoozz das ist eine private Variable in meiner Klasse. Es ist einfach die URL, an die Sie Anfragen stellen müssen. Es könnte so etwas wie api.someurl.com sein und $ path ist das, was nach dieser URL (/ etwas /) steht. Sie können diesen Wert einfach in Ihre URL ändern oder entfernen und die vollständige URL in die Variable $ path aufnehmen. Ist das sinnvoll?
Bolli
19

Um GET, POST, DELETE, PUT aufzurufen, habe ich eine gemeinsame Funktion erstellt

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-Methode

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

CALL Post-Methode

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

CALL Get-Methode

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

CALL Put-Methode

$data = array('id'=>$_REQUEST['eid'],m'title'=>$_REQUEST['txtcategory'],'description'=>$_REQUEST['txtdesc']);
$result = CallAPI('POST', "UpdateCategory", $data);
Juned Ansari
quelle
gut gemacht. Nur eine Anmerkung: Der http-Antwortcode zum Löschen ist 204. Ich denke, Sie sollten alle 20x-Codes als gute Antwort betrachten :)
Ryuujin
0

Meine eigene Klassenanfrage mit wsse-Authentifizierung

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; 
    }
}
Adriwan Kenoby
quelle
benutze + = instaead von array_merge
Adriwan Kenoby
Das funktioniert wahrscheinlich, ist aber eine unnötig komplexe Lösung für das Problem.
Samuel Lindblom
0

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

Peter Ahumuza
quelle
-19
    $json empty

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

}
UZSTYLE GROUP
quelle
Vielen Dank. In diesem speziellen REST-Aufruf muss der JSON-Teil leer sein, daher ist dies kein Problem. Aber trotzdem danke
Bolli
Was $json emptybedeutet hier? Es ist ohnehin nicht im Geltungsbereich dieser Funktion enthalten, sodass die Verwendung von $jsonnichts bewirkt.
halfer
Ich habe darum gebeten, dass diese Antwort gelöscht wird, aber ein Moderator hat Nein gesagt. Das Poster dieser Antwort hat sich seit 2014 ohnehin nicht mehr angemeldet.
halfer