在PHP中处理PUT / DELETE参数


84

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

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

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

令人讨厌的是,这似乎无济于事。这是设置PUT参数的正确方法吗?

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

$ this-> option()是我的库的一部分,它只是建立一个CURLOPT_XX常量数组,并在执行建立的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;

这里有两个选择,我以错误的方式处理此问题,或者我的库中某个地方存在错误。如果您可以让我知道这在理论上是否可行,那么我可以继续进行调试,直到解决为止。

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


PUT工作正常,只需删除参数即可担心现在设置。
Phil Sturgeon,2010年

1
这个问题令人困惑。是关于发送 POST/DELETE参数,还是接收 POST/DELETE参数?
jameshfisher 2014年

Answers:


68

而不是使用CURLOPT_PUT = TRUEuse CURLOPT_CUSTOMREQUEST = 'PUT'CURLOPT_CUSTOMREQUEST = 'DELETE'然后仅使用设置值CURLOPT_POSTFIELDS


如何在api /服务器端接收POSTFIELDS?
丹尼尔

48

这是一些代码,可能对希望处理PUT和DELETE参数的其他人很有帮助。您可以设置$_PUT$_DELETE通过$GLOBALS[],但是除非global通过声明或访问,否则不能直接在函数中访问它们$GLOBALS[]。为了解决这个问题,我制作了一个简单的类来读取GET / POST / PUT / DELETE请求参数。这也填充$_REQUESTPUT / 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

请记住,大多数Web服务器不处理PUT&DELETE请求。由于您正在制作图书馆,因此建议考虑考虑这一点。通常,有两种约定可用于通过POST模拟PUT和DELETE。

  1. 使用自定义的POST变量(例如_METHOD = PUT)覆盖POST
  2. 设置自定义HTTP标头(例如X-HTTP-Method-Override:PUT)

一般而言,大多数不允许直接执行PUT&DELETE的RESTful服务将至少支持其中一种策略。如果需要,可以使用cURL设置自定义标头CURLOPT_HTTPHEADER

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

3

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

要设置发布变量,请使用以下CURLOPT_POSTFIELDS任一字符串param1=val1&param2=val2或关联数组。

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


1
PUT和DELETE都支持发送其他参数。您可以在使用curl时通过命令行执行此操作,但是我无法确定如何使用PHP-cURL发送。例如,因为这是针对REST的,所以我需要一种方法来标记要删除的内容。如果要删除用户ID,则希望能够传递ID而又不会使URL混乱。像Twitter这样的API仅支持GET / POST,因此您可以将其放在URL中,但是其他REST API可能不支持这种事情,因此我需要为其发送delete参数。
Phil Sturgeon,2010年

1
好的,我有PUT参数正常工作,我将CURLOPT_CUSTOMREQUEST ='PUT'换成了CURLOPT_PUT = TRUE,那一切正常。现在,我该如何设置DELETE?
Phil Sturgeon,2010年

CURLOPT_CUSTOMREQUEST ='DELETE',然后使用查询字符串作为参数
Adam Hopkinson,2010年

1
结束语,正如我已经提到的,我试图避免在查询字符串中使用它们。原来,当使用CURLOPT_CUSTOMREQUEST ='DELETE时,可以将CURLOPT_POSTFIELDS与PUT和DELETE一起使用。感谢您的反馈,但最终我自己解决了:-)
Phil Sturgeon 2010年

2
你是否?那我什么都没有帮忙吗?
亚当·霍普金森

2

这是我的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;
            }
        }
    }
}

1

这是我唯一的DELETE问题:

== >>在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_
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.