【问题标题】:Handling PUT/DELETE arguments in PHP在 PHP 中处理 PUT/DELETE 参数
【发布时间】:2011-01-06 02:47:47
【问题描述】:

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

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

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

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

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

$this->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;

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

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

【问题讨论】:

  • PUT 工作正常,只需 DELETE 参数即可担心设置。
  • 这个问题令人困惑。是发送 POST/DELETE参数,还是接收 POST/DELETE参数?

标签: php rest codeigniter curl http-headers


【解决方案1】:

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

【讨论】:

  • 如何在 api/server 端接收 POSTFIELDS?
【解决方案2】:

这里有一些代码可能对其他想要处理 PUT 和 DELETE 参数的人有所帮助。您可以通过$GLOBALS[] 设置$_PUT$_DELETE,但除非声明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;
    }
  }
}

【讨论】:

    【解决方案3】:

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

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

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

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

    【讨论】:

      【解决方案4】:

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

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

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

      【讨论】:

      • PUT 和 DELETE 都支持发送附加参数。您可以在使用 curl 时通过命令行执行此操作,但我无法弄清楚如何使用 PHP-cURL 发送。例如,对于 REST,我需要一种方法来标记我要删除的内容。如果我要删除用户 ID,我希望能够传递 ID 而不会弄乱 URL。像 Twitter 这样的 API 只支持 GET/POST,所以你可以把它放在 URL 中,但是其他 REST API 可能不支持这种东西,所以我需要为它发送一个删除参数。
      • 好的,我的 PUT 参数正常工作,我将 CURLOPT_PUT = TRUE 换成 CURLOPT_CUSTOMREQUEST = 'PUT' 并且工作正常。现在,我到底该如何设置 DELETE?
      • CURLOPT_CUSTOMREQUEST = 'DELETE',然后使用查询字符串作为参数可能
      • 关闭,正如我已经提到的,我试图避免在查询字符串中使用它们。事实证明,当使用 CURLOPT_CUSTOMREQUEST = 'DELETE.感谢您的反馈,但最后我自己解决了:-)
      • 你呢?那我什么都没帮忙?
      【解决方案5】:

      这是我的 DELETE for CI 版本。它接受 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;
                  }
              }
          }
      }
      

      【讨论】:

        【解决方案6】:

        这就是我解决删除问题的方式:

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

        ;) 它对我有用!

        【讨论】:

        • $_DELETE;?我只是得到错误未定义的变量:_DELETE
        猜你喜欢
        • 2013-12-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-02-26
        • 2017-06-14
        • 2013-09-27
        • 2011-06-27
        • 1970-01-01
        相关资源
        最近更新 更多