PHP CURL DELETE запит


100

Я намагаюся зробити DELETE http-запит за допомогою PHP та cURL.

Я читав, як це зробити в багатьох місцях, але ніби нічого не працює на мене.

Ось як я це роблю:

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

Потім я рухаюся вперед і використовую свою функцію:

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

}

Це дає мені помилку внутрішнього сервера HTTP. У інших моїх функціях, що використовують той самий метод curl_req з GET та POST, все йде добре.

Так що я роблю неправильно?


3
Внутрішня помилка сервера означає, що виникла проблема зі сценарієм отримання вашого запиту.
Бред

Дякую Бред - Я знаю, я думаю, що це тому, що його не надсилають як DELETE-запит. Якщо я використовую плагін клієнта REST для Firefox і надсилаю такий самий запит із DELETE, він працює чудово. Таким чином, це виглядає так, що cURL не надсилає запит як DELETE.
Боллі


Дякую Марку, але схоже, що він робить те саме, що і я? Чи неможливо надсилати DELETE запити за допомогою PHP? Якщо є інший спосіб з курсом CURL, я також готовий використовувати це.
Боллі

Відповіді:


216

Нарешті я сам це вирішив. Якщо хтось ще має цю проблему, ось моє рішення:

Я створив новий метод:

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

Оновлення 2

Оскільки це, здається, допомагає деяким людям, ось мій остаточний метод DELETE curl, який повертає відповідь HTTP у декодованому 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;
}

Ви можете мені сказати, як ми робимо виклик Ajax до php (метод: delete), який містить цей код видалення curl і передає його значення з ajax?
користувач1788736

@ user1788736 Я не добре в Ajax, але, мабуть, ви можете створити файл PHP, який виконує цей метод, і за допомогою Ajax надсилайте свої дані за допомогою POST у цей PHP-файл. Якщо ви вважаєте, що вищевказаний метод заплутаний, перегляньте ще раз. $ url s просто сервер, з яким потрібно поговорити ( someserver.com ), а $ path - це матеріал після URL-адреси (/ щось /). Єдина причина, за якою я їх розділяю, полягає в тому, що мені потрібно постійно відправляти на той же сервер, але з динамічними шляхами. Сподіваюся, що це має сенс.
Боллі

Не потрібен заголовок?
er.irfankhan11

Я використовую той самий код, і Paypal повертає http-код: 204, це означає, що успішно видалити. але я отримую 400 постійно.
er.irfankhan11

1
@kuttoozz - це приватна змінна в моєму класі. Це просто URL-адреса, до якої потрібно надсилати запити. Це може бути щось на зразок api.someurl.com, і $ path - це те, що йде за цією URL-адресою (/ something /). Ви можете просто змінити це значення на свою URL-адресу або видалити її та включити повну URL-адресу у змінну $ path. Чи має це сенс?
Боллі

19

Щоб зателефонувати GET, POST, DELETE, PUT Усі запити, я створив одну загальну функцію

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

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

CALL Post метод

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

НАЗВАЙТЕ Отримати метод

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

ПРИКЛАДИ Метод набору

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

молодець. Лише зауваження: http-код відповіді на видалення - 204. Я думаю, ви повинні вважати всі коди 20x як хорошу відповідь :)
ryuujin

0

Мій власний запит класу з аутентифікацією 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

Це, ймовірно, працює, але є надмірно складним рішенням проблеми.
Самуель Ліндблом

0

перемикач ($ метод) {випадок "GET": curl_setopt ($ curl, CURLOPT_CUSTOMREQUEST, "GET"); перерва; випадок "POST": curl_setopt ($ curl, CURLOPT_CUSTOMREQUEST, "POST"); перерва; випадок "PUT": curl_setopt ($ curl, CURLOPT_CUSTOMREQUEST, "PUT"); перерва; випадок "DELETE": curl_setopt ($ curl, CURLOPT_CUSTOMREQUEST, "DELETE"); перерва; }


-19
    $json empty

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

}

Дякую. У цьому конкретному дзвінку REST частина JSON повинна бути порожньою, тому це не проблема. Але все-таки спасибі
Боллі

Що $json emptyтут означає? Це все одно не входить у цю функцію, тому використання $jsonнічого не зробить.
півзахисник

Я попросив видалити цю відповідь, але модератор сказав "ні". Плакат цієї відповіді все одно не підписувався з 2014 року.
півзахисник
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.