Żądanie PHP CURL DELETE

100

Próbuję wykonać żądanie DELETE http przy użyciu PHP i cURL.

Czytałem, jak to zrobić w wielu miejscach, ale wydaje mi się, że nic nie działa.

Oto jak to robię:

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

Następnie idę dalej i używam mojej funkcji:

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

}

To daje mi błąd wewnętrznego serwera HTTP. W moich innych funkcjach używających tej samej metody curl_req z GET i POST wszystko idzie dobrze.

Więc co robię źle?

Bolli
źródło
3
Wewnętrzny błąd serwera oznacza, że ​​wystąpił problem ze skryptem, który odebrał Twoje żądanie.
Brad
Dzięki Brad - wiem, myślę, że to dlatego, że nie jest wysyłane jako żądanie DELETE. Jeśli używam wtyczki klienta REST dla przeglądarki Firefox i wyślę dokładnie to samo żądanie za pomocą funkcji DELETE, działa dobrze. Więc wygląda na to, że cURL nie wysyła żądania jako DELETE.
Bolli
Dzięki Marc, ale wydaje się, że robi to samo co ja? Czy nie jest możliwe wysyłanie żądań DELETE za pomocą PHP? Jeśli istnieje inny sposób bez cURL, jestem otwarty, aby go również użyć.
Bolli

Odpowiedzi:

216

W końcu sam to rozwiązałem. Jeśli ktoś ma ten problem, oto moje rozwiązanie:

Stworzyłem nową metodę:

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

Zaktualizuj 2

Ponieważ wydaje się to pomagać niektórym osobom, oto moja ostateczna metoda curl DELETE, która zwraca odpowiedź HTTP w zdekodowanym obiekcie 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;
}
Bolli
źródło
Czy możesz mi powiedzieć, jak wywołujemy AJAX do php (metoda: usuń), które przechowują ten kod kasowania curl i przekazują jego wartość z AJAX?
user1788736
@ user1788736 Nie jestem dobry w Ajax, ale myślę, że możesz stworzyć plik PHP, który wykonuje tę metodę, a za pomocą Ajax wysłać dane za pomocą POST do tego pliku PHP. Jeśli uważasz, że powyższa metoda jest myląca, spójrz ponownie. $ url to po prostu serwer, z którym musisz porozmawiać ( someserver.com ), a $ path to zawartość po adresie URL (/ coś /). Jedynym powodem, dla którego je rozdzieliłem, jest to, że muszę przez cały czas wysyłać do tego samego serwera, ale z dynamicznymi ścieżkami. Mam nadzieję, że to ma sens.
Bolli
Nie potrzebuje nagłówka?
er.irfankhan11
Używam tego samego kodu, a kod http zwrotny Paypal: 204 oznacza to pomyślne usunięcie. ale dostałem 400 przez cały czas.
er.irfankhan11
1
@kuttoozz to prywatna zmienna w mojej klasie. To po prostu adres URL, do którego należy wysyłać żądania. Może to być coś takiego jak api.someurl.com, a $ path jest tym, co znajduje się po tym adresie URL (/ coś /). Możesz po prostu zmienić tę wartość na swój adres URL lub usunąć ją i dołączyć pełny adres URL do zmiennej $ path. Czy to ma sens?
Bolli
19

Aby wywołać GET, POST, DELETE, PUT wszelkiego rodzaju żądania, stworzyłem jedną wspólną funkcję

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 Usuń metodę

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

Metoda CALL Post

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

ZADZWOŃ Uzyskaj metodę

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

CALL Put Method

$data = array('id'=>$_REQUEST['eid'],m'title'=>$_REQUEST['txtcategory'],'description'=>$_REQUEST['txtdesc']);
$result = CallAPI('POST', "UpdateCategory", $data);
Juned Ansari
źródło
dobra robota. Tylko uwaga: kod odpowiedzi http dla usunięcia to 204. Myślę, że wszystkie kody 20x należy traktować jako dobrą odpowiedź :)
ryuujin
0

Moje własne żądanie klasy z uwierzytelnianiem 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; 
    }
}
Adriwan Kenoby
źródło
użyj + = instaead z array_merge
Adriwan Kenoby
To prawdopodobnie działa, ale jest niepotrzebnie złożonym rozwiązaniem problemu.
Samuel Lindblom
0

przełącznik ($ metoda) {case "GET": curl_setopt ($ curl, CURLOPT_CUSTOMREQUEST, "GET"); przerwa; sprawa "POST": curl_setopt ($ curl, CURLOPT_CUSTOMREQUEST, "POST"); przerwa; sprawa "PUT": curl_setopt ($ curl, CURLOPT_CUSTOMREQUEST, "PUT"); przerwa; case "DELETE": curl_setopt ($ curl, CURLOPT_CUSTOMREQUEST, "DELETE"); przerwa; }

Peter Ahumuza
źródło
-19
    $json empty

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

}
GRUPA UZSTYLE
źródło
Dzięki. W tym konkretnym wywołaniu REST część JSON musi być pusta, więc nie stanowi to problemu. Ale i tak dzięki
Bolli
Co to $json emptyznaczy? I tak nie jest objęty zakresem tej funkcji, więc użycie $jsonnic nie da.
halfer
Poprosiłem o usunięcie tej odpowiedzi, ale moderator powiedział, że nie. Plakat z tą odpowiedzią i tak nie zarejestrował się od 2014 roku.
halfer