如何使用PUT方法创建API?CodeIgniter3开发PUT请求常见问题咨询
PUT请求相关问题解答(含CodeIgniter 3实操方案)
问题1:发送PUT请求时需使用param、form-data还是二者均可?
- 二者均可,HTTP规范没有对PUT请求的传参形式做强制限制:
- param即URL查询参数,是?key=value形式的URL后缀参数,所有HTTP请求方法(含GET/POST/PUT/DELETE)都天然支持该传参方式
- form-data属于请求体编码格式的一种,PUT请求本身支持携带任意格式的请求体,所以完全可以用form-data传递参数
问题2:各类请求是否都支持同时在param和form-data中传递数据?
- 是,所有标准HTTP请求方法都支持同时在URL查询参数、请求体(含form-data、JSON等任意编码格式)中传递数据,二者属于完全独立的传参通道,互不冲突。服务端会分别从URL和请求体中解析对应参数,不会出现互相覆盖的情况。
问题3:PUT请求同时提交基础信息与附件的实现方案(适配CodeIgniter 3框架)
通用实现逻辑
PUT请求上传附件和POST逻辑一致,统一采用multipart/form-data作为请求体编码格式即可:
- 基础信息作为form-data的普通字段传递
- 附件作为form-data的文件类型字段传递
- 需放在URL的参数仍按常规方式写在param中即可
CodeIgniter 3 适配方案
PHP原生仅自动解析POST请求的form-data格式,PUT请求的form-data需要手动解析后才能被CI3识别,实操步骤如下:
- 在项目入口文件
index.php头部添加PUT请求解析逻辑:
if ($_SERVER['REQUEST_METHOD'] == 'PUT') { $input = fopen('php://input', 'r'); $raw_data = ''; while ($chunk = fread($input, 1024)) { $raw_data .= $chunk; } fclose($input); $boundary = substr($raw_data, 0, strpos($raw_data, "\r\n")); if (empty($boundary)) { parse_str($raw_data, $GLOBALS['_PUT']); } else { $parts = array_slice(explode($boundary, $raw_data), 1); $data = []; foreach ($parts as $part) { if ($part == "--\r\n") break; $part = ltrim($part, "\r\n"); list($raw_headers, $body) = explode("\r\n\r\n", $part, 2); $raw_headers = explode("\r\n", $raw_headers); $headers = []; foreach ($raw_headers as $header) { list($name, $value) = explode(':', $header); $headers[strtolower($name)] = ltrim($value, ' '); } if (isset($headers['content-disposition'])) { preg_match('/form-data; name="([^"]+)"(; filename="([^"]+)")?/', $headers['content-disposition'], $matches); $name = $matches[1]; $filename = isset($matches[3]) ? $matches[3] : null; if (!is_null($filename)) { $tmp_file = tempnam(sys_get_temp_dir(), 'put_upload'); file_put_contents($tmp_file, substr($body, 0, strlen($body) - 2)); $data[$name] = [ 'name' => $filename, 'tmp_name' => $tmp_file, 'size' => filesize($tmp_file), 'error' => 0 ]; $GLOBALS['_FILES'][$name] = $data[$name]; } else { $data[$name] = substr($body, 0, strlen($body) - 2); } } } $GLOBALS['_PUT'] = $data; } }
- 控制器中直接调用解析后的参数和文件即可,用法和原生POST传参一致:
// 获取URL查询参数 $param = $this->input->get('自定义参数名'); // 获取PUT请求体普通字段 $base_info = $GLOBALS['_PUT']['基础信息字段名']; // 处理上传附件 $this->load->library('upload'); $config['upload_path'] = './自定义上传目录/'; $config['allowed_types'] = 'gif|jpg|png|pdf'; // 按需配置允许的文件类型 $this->upload->initialize($config); if ($this->upload->do_upload('附件字段名')) { $file_info = $this->upload->data(); // 获取上传成功的文件信息 }
内容的提问来源于stack exchange,提问作者Shubham Rawat
相关产品推荐
相关产品推荐

