Żą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?


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

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

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

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


-19
    $json empty

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

}

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
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.