使用Codeigniter接收PUT请求

9

我现在遇到了一个CodeIgniter的问题:我使用REST Controller库(非常棒)来创建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

用户ID已经满了,但用户名变量为空。但是,POST和GET动词可以使用。请问您有任何想法吗?
谢谢!

嘿,@Shatter,你有没有机会验证这个? - jcolebrand
仍有错误,$this->put('anything') 返回 false。 - Syl
7个回答

10

根据: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,如果有,则使用它代替在Web上实现的实际动词。要在请求中使用它,您需要指定标头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");
}

6

你可以先尝试检测方法类型,然后区分不同的情况。如果您的控制器只处理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
在CodeIgniter 4中使用getRawInput,它将检索数据并将其转换为数组。
$data = $request->getRawInput();

2

2

Codeigniter的put_stream没有提供帮助,相反我不得不使用PHP输入流。你可以将以下方法添加到helpers中,然后在任何控制器中解析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;

}


1

请查看官方Code Igniter文档中的链接使用输入流进行自定义请求方法

这是Code Igniter的做法。

如果请求主体是表单url编码的,请调用以下内容

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

-3

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

如果您确实需要读取PUT请求,请查看从PHP访问传入的PUT数据


这可能在2011年4月是准确的,但现在已经不准确了。 - jcolebrand

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接