在 PHP 中处理 PUT/DELETE 参数

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2081894/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 04:55:55  来源:igfitidea点击:

Handling PUT/DELETE arguments in PHP

phprestcodeignitercurlhttp-headers

提问by Phil Sturgeon

I am working on my REST client library for CodeIgniterand I am struggling to work out how to send PUT and DELETE arguments in PHP.

我正在为 CodeIgniter开发我的REST 客户端库,我正在努力研究如何在 PHP 中发送 PUT 和 DELETE 参数。

In a few places I have seen people using the options:

在一些地方,我看到人们使用这些选项:

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

Annoyingly, this seems to do nothing. Is this the correct way to set PUT parameters?

令人讨厌的是,这似乎没有任何作用。这是设置 PUT 参数的正确方法吗?

If so, how do I set DELETE parameters?

如果是这样,我如何设置 DELETE 参数?

$this->option() is part of my library, it simply builds up an array of CURLOPT_XX constants and sends them to curl_setopt_array() when the built up cURL request is executed.

$this->option() 是我的库的一部分,它只是构建一个 CURLOPT_XX 常量数组,并在执行构建的 cURL 请求时将它们发送到 curl_setopt_array()。

I am attempting to read PUT and DELETE parameters using the following code:

我正在尝试使用以下代码读取 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;

There are two options here, I am approaching this in the wrong way or there is a bug somewhere in my libraries. If you could let me know if this should theoretically work I can just hammer away on debug until I solve it.

这里有两个选项,我以错误的方式处理这个问题,或者我的库中某处存在错误。如果你能让我知道这在理论上是否可行,我可以在调试之前进行调试,直到我解决它。

I dont want to waste any more time on an approach that is fundamentally wrong.

我不想再浪费时间在一种根本错误的方法上。

采纳答案by Phil Sturgeon

Instead of using CURLOPT_PUT = TRUEuse CURLOPT_CUSTOMREQUEST = 'PUT'and CURLOPT_CUSTOMREQUEST = 'DELETE'then just set values with CURLOPT_POSTFIELDS.

而不是使用CURLOPT_PUT = TRUE用途CURLOPT_CUSTOMREQUEST = 'PUT'CURLOPT_CUSTOMREQUEST = 'DELETE'然后只设置值时CURLOPT_POSTFIELDS

回答by Bryan Drewery

Here is some code which may be helpful for others wanting to handle PUT and DELETE params. You are able to set $_PUTand $_DELETEvia $GLOBALS[], but they will not be directly accessible in functions unless declared globalor accessed via $GLOBALS[]. To get around this, I've made a simple class for reading GET/POST/PUT/DELETE request arguments. This also populates $_REQUESTwith PUT/DELETE params.

这里有一些代码可能对其他想要处理 PUT 和 DELETE 参数的人有帮助。您可以设置$_PUT$_DELETEvia $GLOBALS[],但除非global通过声明或访问它们,否则它们将无法在函数中直接访问$GLOBALS[]。为了解决这个问题,我创建了一个简单的类来读取 GET/POST/PUT/DELETE 请求参数。这也填充$_REQUEST了 PUT/DELETE 参数。

This class will parse the PUT/DELETE params and support GET/POST as well.

此类将解析 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;
    }
  }
}

回答by Owen

Just remember, most webservers do not handle PUT & DELETE requests. Since you're making a library, I'd suggest thinking about accounting for this. Typically, there are two conventions you can use to mimic PUT & DELETE via POST.

请记住,大多数网络服务器不处理 PUT 和 DELETE 请求。既然你正在制作一个图书馆,我建议考虑考虑这一点。通常,您可以使用两种约定来通过 POST 模拟 PUT 和 DELETE。

  1. use a custom POST variable (ex. _METHOD=PUT) which overrides POST
  2. set a custom HTTP header (ex. X-HTTP-Method-Override: PUT)
  1. 使用覆盖 POST 的自定义 POST 变量(例如 _METHOD=PUT)
  2. 设置自定义 HTTP 标头(例如 X-HTTP-Method-Override: PUT)

Generally speaking, most RESTful services that don't allow PUT & DELETE directly will support at least one of those strategies. You can use cURL to set a custom header if you need via the CURLOPT_HTTPHEADERoption.

一般来说,大多数不允许直接执行 PUT 和 DELETE 的 RESTful 服务将至少支持其中一种策略。如果需要,您可以通过CURLOPT_HTTPHEADER选项使用 cURL 设置自定义标题。

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

回答by Adam Hopkinson

I think you're mixing your verbs - PUT is for putting a file, POST is for posting variables (although you can POST a file).

我认为您在混合动词 - PUT 用于放置文件,POST 用于发布变量(尽管您可以发布文件)。

To set the post variables, use CURLOPT_POSTFIELDSwith either a string of param1=val1&param2=val2or an associative array.

要设置 post 变量,请CURLOPT_POSTFIELDS与字符串param1=val1&param2=val2或关联数组一起使用。

To do a DELETE, you'll want to use the curl option CURLOPT_CUSTOMREQUEST

要执行 DELETE,您需要使用 curl 选项 CURLOPT_CUSTOMREQUEST

回答by Patrick Savalle

This is my version of the DELETE for CI. It accepts GET-style arguments for the DELETE, even same name arguments, i.e.: GET /some/url?id=1&id=2&id=3

这是我的 CI DELETE 版本。它接受 DELETE 的 GET 样式参数,甚至是同名参数,即: 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;
            }
        }
    }
}

回答by okobsamoht

This is how i sole my DELETE problem:

这就是我唯一的 DELETE 问题:

==>> in REST_Controller.phpi replace the delault _parse_delete()function by :

==>> 在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);
}

;) it works for me!

;) 这个对我有用!