【问题标题】:get a PUT request with Codeigniter使用 Codeigniter 获取 PUT 请求
【发布时间】:2011-07-29 06:53:11
【问题描述】:

我现在遇到了 CodeIgniter 的问题:我使用 REST Controller library(非常棒)来创建 API,但我无法获得 PUT 请求...

这是我的代码:

function user_put() {
    $user_id = $this->get("id");
    echo $user_id;
    $username = $this->put("username");
    echo $username;
}

我使用 curl 发出请求:

curl -i -X PUT -d "username=test" http://[...]/user/id/1

user_id 已满,但用户名变量为空。但它适用于动词 POST 和 GET。 请问你有什么想法吗?

谢谢!

【问题讨论】:

  • 嘿@Shatter 你有机会验证这个吗?
  • 仍然有问题,$this->put('anything') 返回 false

标签: php codeigniter rest


【解决方案1】:

根据:http://net.tutsplus.com/tutorials/php/working-with-restful-services-in-codeigniter-2/我们应该咨询https://github.com/philsturgeon/codeigniter-restserver/blob/master/application/libraries/REST_Controller.php#L544看这个方法:

/**
 * Detect method
 *
 * Detect which method (POST, PUT, GET, DELETE) is being used
 * 
 * @return string 
 */
protected function _detect_method() {
  $method = strtolower($this->input->server('REQUEST_METHOD'));

  if ($this->config->item('enable_emulate_request')) {
    if ($this->input->post('_method')) {
      $method = strtolower($this->input->post('_method'));
    } else if ($this->input->server('HTTP_X_HTTP_METHOD_OVERRIDE')) {
      $method = strtolower($this->input->server('HTTP_X_HTTP_METHOD_OVERRIDE'));
    }      
  }

  if (in_array($method, array('get', 'delete', 'post', 'put'))) {
    return $method;
  }

  return 'get';
}

查看我们是否定义了 HTTP 标头 HTTP_X_HTTP_METHOD_OVERRIDE 并使用它来支持我们在网络上实现的实际动词。要在请求中使用它,您将指定标头 X-HTTP-Method-Override: method(因此 X-HTTP-Method-Override: put)以生成自定义方法覆盖。有时框架需要X-HTTP-Method 而不是X-HTTP-Method-Override,所以这因框架而异。

如果您通过 jQuery 执行此类请求,您可以将此块集成到您的 ajax 请求中:

beforeSend: function (XMLHttpRequest) {
   //Specify the HTTP method DELETE to perform a delete operation.
   XMLHttpRequest.setRequestHeader("X-HTTP-Method-Override", "DELETE");
}

【讨论】:

    【解决方案2】:

    您可以尝试先检测方法类型并区分不同的情况。如果您的控制器仅处理 REST 函数,则将获取所需的信息放入构造函数中可能会有所帮助。

    switch($_SERVER['REQUEST_METHOD']){
       case 'GET':
          $var_array=$this->input->get();
          ...
          break;
       case 'POST':
          $var_array=$this->input->post();
          ...
          break;
       case 'PUT':
       case 'DELETE':
          parse_str(file_get_contents("php://input"),$var_array);
          ...
          break;
       default:
          echo "I don't know how to handle this request.";
    }
    

    【讨论】:

      【解决方案3】:

      在 github 中查看这个问题

      PUT 参数仅适用于 JSON 格式

      https://github.com/chriskacerguis/codeigniter-restserver/issues/362

      【讨论】:

        【解决方案4】:

        在 CodeIgniter 4 中使用 getRawInput 检索数据并将其转换为数组。

        $data = $request->getRawInput();
        

        【讨论】:

          【解决方案5】:

          在官方代码点火器文档Using the Input Stream for Custom Request Methods中查看此链接

          这是 Code Igniter 的做法。

          如果请求的主体是form-urlencoded,只需调用下面的代码

          $var1 = $this->input->input_stream('var_key')
          // Or 
          $var1 = $this->security->xss_clean($this->input->input_stream('var_key'));
          

          【讨论】:

            【解决方案6】:

            Codeigniter put_stream 没有提供任何帮助,而是我不得不使用 php 输入流,因为可以将以下方法添加到助手中,从那里您可以在任何控制器中解析 put 请求:

            function parsePutRequest()
            {
                // Fetch content and determine boundary
                $raw_data = file_get_contents('php://input');
                $boundary = substr($raw_data, 0, strpos($raw_data, "\r\n"));
            
            // Fetch each part
            $parts = array_slice(explode($boundary, $raw_data), 1);
            $data = array();
            
            foreach ($parts as $part) {
                // If this is the last part, break
                if ($part == "--\r\n") break; 
            
                // Separate content from headers
                $part = ltrim($part, "\r\n");
                list($raw_headers, $body) = explode("\r\n\r\n", $part, 2);
            
                // Parse the headers list
                $raw_headers = explode("\r\n", $raw_headers);
                $headers = array();
                foreach ($raw_headers as $header) {
                    list($name, $value) = explode(':', $header);
                    $headers[strtolower($name)] = ltrim($value, ' '); 
                } 
            
                // Parse the Content-Disposition to get the field name, etc.
                if (isset($headers['content-disposition'])) {
                    $filename = null;
                    preg_match(
                        '/^(.+); *name="([^"]+)"(; *filename="([^"]+)")?/', 
                        $headers['content-disposition'], 
                        $matches
                    );
                    list(, $type, $name) = $matches;
                    isset($matches[4]) and $filename = $matches[4]; 
            
                    // handle your fields here
                    switch ($name) {
                        // this is a file upload
                        case 'userfile':
                            file_put_contents($filename, $body);
                            break;
            
                        // default for all other files is to populate $data
                        default: 
                            $data[$name] = substr($body, 0, strlen($body) - 2);
                            break;
                    } 
                }
            
            }
            return $data;
            

            }

            【讨论】:

              【解决方案7】:

              CodeIgniter 不支持读取传入的 PUT 请求,如果不是必需的,我会坚持为您的 API 使用 GET/POST,因为它可能没有必要。

              如果您确实需要阅读 PUT 请求,请查看 Accessing Incoming PUT Data from PHP

              【讨论】:

              • 这在 2011 年 4 月可能是准确的,但目前并不准确。
              猜你喜欢
              • 1970-01-01
              • 2022-08-19
              • 2018-12-20
              • 2017-03-10
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多