PHP多部分表单数据PUT请求?

标签 php http codeigniter rest curl

我正在编写 RESTful API。我在使用不同的动词上传图片时遇到了问题。

考虑:

我有一个对象,可以通过对 URL 的 post/put/delete/get 请求来创建/修改/删除/查看。当有文件要上传时,请求是多部分形式,或者当只有文本要处理时,请求是 application/xml。

为了处理与我正在做的对象关联的图像上传:

    if(isset($_FILES['userfile'])) {
        $data = $this->image_model->upload_image();
        if($data['error']){
            $this->response(array('error' => $error['error']));
        }
        $xml_data = (array)simplexml_load_string( urldecode($_POST['xml']) );           
        $object = (array)$xml_data['object'];
    } else {
        $object = $this->body('object');
    }

这里的主要问题是在尝试处理放置请求时,显然 $_POST 不包含放置数据(据我所知!)。

作为引用,这是我构建请求的方式:

curl -F userfile=@./image.png -F xml="<xml><object>stuff to edit</object></xml>" 
  http://example.com/object -X PUT

有人知道如何在我的 PUT 请求中访问 xml 变量吗?

最佳答案

首先,$_FILES 在处理 PUT 请求时不会被填充。它仅在处理 POST 请求时由 PHP 填充。

您需要手动解析它。这也适用于“常规”字段:

// 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;
        } 
    }

}

在每次迭代中,$data 数组将填充您的参数,$headers 数组将填充每个部分的标题(例如:Content-Type 等),并且 $filename 将包含原始文件名,如果在请求中提供并且适用于该字段。

请注意,以上仅适用于 multipart 内容类型。在使用上述内容解析正文之前,请务必检查请求的 Content-Type header 。

关于PHP多部分表单数据PUT请求?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9464935/

相关文章:

mysql - MYSQL 中的 KEY slug(slug) 是什么意思?

php - 如何将变量中的每个数字增加 5?

c - 在 Nginx 中使用 C 处理 HTTP 请求

php - 在某些情况下,php 中的图像会出现错误

c# - 如何在 AngularJS 中将参数传递给 DELETE?

http - 池连接每次都连接?

php - codeigniter路由问题

php - Codeigniter 无法加载库类

php - 读取 MySQL blob 字段并转换为 Android Webservice 的 JSON

php - 如何在 php 中自动将当前日期更新为 1 周到服务器