Обробка аргументів PUT / DELETE у PHP


84

Я працюю над своєю клієнтською бібліотекою REST для CodeIgniter, і я намагаюся знайти, як надсилати аргументи PUT та DELETE у PHP.

Десь у кількох місцях я бачив людей, які використовують такі варіанти:

$this->option(CURLOPT_PUT, TRUE);
$this->option(CURLOPT_POSTFIELDS, $params);

Прикро, але це, здається, нічого не робить. Це правильний спосіб встановити параметри PUT?

Якщо так, то як мені встановити параметри ВИДАЛИТИ?

$ this-> option () є частиною моєї бібліотеки, вона просто створює масив констант CURLOPT_XX і надсилає їх curl_setopt_array () при виконанні вбудованого запиту curl.

Я намагаюся прочитати параметри PUT та DELETE, використовуючи такий код:

        case 'put':
            // Set up out PUT variables
            parse_str(file_get_contents('php://input'), $this->_put_args);
        break;

        case 'delete':
            // Set up out PUT variables
            parse_str(file_get_contents('php://input'), $this->_delete_args);
        break;

Тут є два варіанти, я підходжу до цього неправильно або десь у моїх бібліотеках є помилка. Якщо ви могли б повідомити мене, чи це теоретично має спрацювати, я міг би просто налагодити налагодження, поки не вирішу.

Я не хочу витрачати більше часу на підхід, який є принципово неправильним.


PUT працює нормально, просто ВИДАЛІТЬ параметри, щоб турбуватися про встановлення зараз.
Філ Стерджен

1
Це питання бентежить. Це стосується надсилання POST / DELETEпараметрів або отримання POST / DELETEпараметрів?
jameshfisher

Відповіді:


68

Замість того, щоб використовувати CURLOPT_PUT = TRUEuse, CURLOPT_CUSTOMREQUEST = 'PUT' а CURLOPT_CUSTOMREQUEST = 'DELETE'потім просто встановити значення за допомогою CURLOPT_POSTFIELDS.


Як отримати POSTFIELDS на стороні api / сервера?
Даніель

48

Ось деякий код, який може бути корисним для інших, хто хоче обробляти параметри PUT та DELETE. Ви можете встановити $_PUTі $_DELETEчерез $GLOBALS[], але вони не будуть безпосередньо доступні у функціях, якщо вони не будуть оголошені globalабо доступні через $GLOBALS[]. Щоб обійти це, я створив простий клас для читання аргументів запиту GET / POST / PUT / DELETE. Це також заповнюється $_REQUESTпараметрами PUT / DELETE.

Цей клас буде аналізувати параметри PUT / DELETE і також підтримувати GET / POST.

class Params {
  private $params = Array();

  public function __construct() {
    $this->_parseParams();
  }

  /**
    * @brief Lookup request params
    * @param string $name Name of the argument to lookup
    * @param mixed $default Default value to return if argument is missing
    * @returns The value from the GET/POST/PUT/DELETE value, or $default if not set
    */
  public function get($name, $default = null) {
    if (isset($this->params[$name])) {
      return $this->params[$name];
    } else {
      return $default;
    }
  }

  private function _parseParams() {
    $method = $_SERVER['REQUEST_METHOD'];
    if ($method == "PUT" || $method == "DELETE") {
        parse_str(file_get_contents('php://input'), $this->params);
        $GLOBALS["_{$method}"] = $this->params;
        // Add these request vars into _REQUEST, mimicing default behavior, PUT/DELETE will override existing COOKIE/GET vars
        $_REQUEST = $this->params + $_REQUEST;
    } else if ($method == "GET") {
        $this->params = $_GET;
    } else if ($method == "POST") {
        $this->params = $_POST;
    }
  }
}

16

Тільки пам’ятайте, що більшість веб-серверів не обробляють запити PUT & DELETE. Оскільки ви створюєте бібліотеку, я б запропонував подумати про те, щоб це врахувати. Як правило, є дві конвенції, якими можна імітувати PUT & DELETE через POST.

  1. використовувати користувацьку змінну POST (наприклад, _METHOD = PUT), яка замінює POST
  2. встановити власний заголовок HTTP (наприклад, X-HTTP-Method-Override: PUT)

Взагалі кажучи, більшість служб RESTful, які не дозволяють ПУТИ І ВИДАЛИТИ безпосередньо, підтримуватимуть принаймні одну з цих стратегій. Ви можете використовувати cURL, щоб встановити власний заголовок, якщо вам це потрібно, за допомогою CURLOPT_HTTPHEADERопції.

// ex...
curl_setopt($ch, CURLOPT_HTTPHEADER, array('X-HTTP-Method-Override: PUT') );

3

Я думаю, що ви змішуєте свої дієслова - PUT - для розміщення файлу, POST - для розміщення змінних (хоча ви можете POST файл).

Щоб встановити змінні post, використовуйте CURLOPT_POSTFIELDSабо рядок param1=val1&param2=val2або асоціативний масив.

Щоб виконати ВИДАЛЕННЯ, ви захочете скористатися опцією завивки CURLOPT_CUSTOMREQUEST


1
PUT та DELETE підтримують надсилання додаткових аргументів. Ви можете зробити це за допомогою командного рядка під час роботи з curl, але я не можу зрозуміти, як надсилати за допомогою PHP-cURL. Наприклад, оскільки це стосується REST, мені потрібен спосіб позначити те, що я видаляю. Якщо я видаляю ідентифікатор користувача, я хочу мати можливість передавати ідентифікатор, не захаращуючи URL-адресу. API, такі як Twitter, підтримують лише GET / POST, щоб ви могли помістити це в URL-адресу, але інші API REST можуть не підтримувати подібні речі, тому мені потрібно надіслати для цього параметр видалення.
Філ Стерджен

1
Добре, у мене працюють параметри PUT, я поміняв CURLOPT_PUT = TRUE на CURLOPT_CUSTOMREQUEST = 'PUT', і це працює нормально. Тепер, як, блін, мені встановити ВИДАЛИТИ?
Філ Стерджен

CURLOPT_CUSTOMREQUEST = 'ВИДАЛИТИ', потім використовуйте рядок запиту для параметрів, можливо
Адам Гопкінсон,

1
Закрити, я намагався уникати їх використання у рядку запиту, як я вже згадував. Виявляється, ви можете використовувати CURLOPT_POSTFIELDS з PUT і DELETE, коли використовуєте CURLOPT_CUSTOMREQUEST = 'DELETE. Дякую за ваш відгук, але врешті-решт я сам вирішив :-)
Філ Стерджен

2
Ти що? Я тоді зовсім не допомагав?
Адам Гопкінсон

2

Це моя версія DELETE для CI. Він приймає аргументи в стилі GET для DELETE, навіть аргументи з однаковим іменем, тобто: GET / some / url? Id = 1 & id = 2 & id = 3

protected function _parse_delete()
{
    $query = $_SERVER['QUERY_STRING'];
    if ( !empty( $query ) )
    {
        foreach( explode('&', $query ) as $param )
        {
            list($k, $v) = explode('=', $param);
            $k = urldecode($k);
            $v = urldecode($v);
            if ( isset( $this->_delete_args[$k] ) )
            {
                if ( is_scalar( $this->_delete_args[$k] ) )
                {
                    $this->_delete_args[$k] = array( $this->_delete_args[$k] );
                }
                $this->_delete_args[$k][] = $v ;
            }
            else
            {
                $this->_delete_args[$k] = $v;
            }
        }
    }
}

1

Ось як я вирішую лише проблему ВИДАЛЕННЯ:

== >> у REST_Controller.php я замінюю функцію delault _parse_delete () на:

protected function _parse_delete()
{
    $this->_delete_args = $_DELETE;
    $this->request->format and $this->request->body = file_get_contents('php://input');
    // Set up out DELETE variables (which shouldn't really exist, but sssh!)
    parse_str(file_get_contents('php://input'), $this->_delete_args);
}

;) у мене це працює!


1
$ _DELETE ;? Я просто отримую невизначену змінну з помилкою: _DELETE
Valor_
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.