在PHP中处理PUT / DELETE参数
我正在为CodeIgniter的REST客户端库工作 ,我正在努力解决如何在PHP中发送PUT和DELETE参数。
在一些地方,我看到人们使用这些选项:
$this->option(CURLOPT_PUT, TRUE); $this->option(CURLOPT_POSTFIELDS, $params);
令人讨厌的是,这似乎什么都不做。 这是设置PUT参数的正确方法吗?
如果是这样,我该如何设置DELETE参数?
$ this-> option()是我的库的一部分,它只需构build一个CURLOPT_XX常量数组,并在执行构build的cURL请求时将它们发送到curl_setopt_array()。
我正在尝试使用下面的代码读取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;
这里有两个select,我用错误的方法来解决这个问题,或者在我的库中有一个错误。 如果你能让我知道这是否应该在理论上工作,我可以锤掉debugging,直到我解决它。
我不想浪费更多的时间在一个根本上错误的方法上。
而不是使用CURLOPT_PUT = TRUE
使用CURLOPT_CUSTOMREQUEST = 'PUT'
和CURLOPT_CUSTOMREQUEST = 'DELETE'
然后用CURLOPT_POSTFIELDS
设置值。
这里是一些代码,可能有助于其他人想要处理PUT和DELETE PARAMS。 您可以通过$GLOBALS[]
设置$_PUT
和$_DELETE
,但是除非声明为global
或通过$GLOBALS[]
访问,否则它们将不能在函数中直接访问。 为了解决这个问题,我做了一个简单的类来读取GET / POST / PUT / DELETE请求参数。 这也用PUT / DELETE参数填充$_REQUEST
。
这个类将parsingPUT / 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; } } }
请记住,大多数Web服务器不处理PUT和DELETE请求。 既然你正在build立一个图书馆,我build议你考虑一下这个问题。 通常,有两个约定可以用来通过POST模拟PUT和DELETE。
- 使用一个自定义的POSTvariables(例如_METHOD = PUT)来覆盖POST
- 设置一个自定义的HTTP头(例如X-HTTP-Method-Override:PUT)
一般来说,大多数不允许直接使用PUT和DELETE的RESTful服务至less会支持其中一种策略。 如果您需要通过CURLOPT_HTTPHEADER
选项,可以使用cURL来设置自定义标题。
// ex... curl_setopt($ch, CURLOPT_HTTPHEADER, array('X-HTTP-Method-Override: PUT') );
我认为你在混合你的动词 – PUT是放置文件,POST是发布variables(尽pipe你可以POST文件)。
要设置发布variables,请使用带有param1=val1¶m2=val2
或关联数组的string的CURLOPT_POSTFIELDS
。
要执行DELETE,您需要使用curl选项CURLOPT_CUSTOMREQUEST
这是我唯一的DELETE问题:
== >>在REST_Controller.php我replacedelault _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); }
;) 这个对我有用!
这是我对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; } } } }