在PHP中处理PUT / DELETE参数

时间:2010-01-17 17:26:03

标签: php rest codeigniter curl http-headers

我正在研究REST client library for CodeIgniter,我正在努力研究如何在PHP中发送PUT和DELETE参数。

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

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

令人讨厌的是,这似乎什么都不做。这是设置PUT参数的正确方法吗?

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

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

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

这里有两个选项,我以错误的方式接近这个或者我的库中有一个错误。如果你能告诉我这是否理论上有效,我可以直接调试,直到我解决它。

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

6 个答案:

答案 0 :(得分:68)

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

答案 1 :(得分:48)

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

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

答案 2 :(得分:16)

请记住,大多数网络服务器都不处理PUT&amp;删除请求。既然你正在建立一个图书馆,我建议考虑解决这个问题。通常,您可以使用两种约定来模拟PUT和amp;通过POST删除。

  1. 使用自定义POST变量(例如_METHOD = PUT)覆盖POST
  2. 设置自定义HTTP标头(例如X-HTTP-Method-Override:PUT)
  3. 一般来说,大多数RESTful服务不允许PUT&amp;直接删除将至少支持其中一个策略。如果需要,可以使用cURL通过CURLOPT_HTTPHEADER选项设置自定义标题。

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

答案 3 :(得分:3)

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

要设置发布变量,请将CURLOPT_POSTFIELDSparam1=val1&param2=val2字符串或关联数组一起使用。

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

答案 4 :(得分:1)

这就是我唯一的DELETE问题:

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

;)它对我有用!

答案 5 :(得分:1)

这是我的CI版DELETE版本。它接受DELETE的GET样式参数,甚至是同名参数,即:GET / some / url?id = 1&amp; id = 2&amp; 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;
            }
        }
    }
}