PHP multipart form data PUT request?

后端 未结 5 1256
南笙
南笙 2020-11-29 06:35

I\'m writing a RESTful API. I\'m having trouble with uploading images using the different verbs.

Consider:

I have an object which can be created/modified/del

5条回答
  •  被撕碎了的回忆
    2020-11-29 07:21

    First of all, $_FILES is not populated when handling PUT requests. It is only populated by PHP when handling POST requests.

    You need to parse it manually. That goes for "regular" fields as well:

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

    At each iteration, the $data array will be populated with your parameters, and the $headers array will be populated with the headers for each part (e.g.: Content-Type, etc.), and $filename will contain the original filename, if supplied in the request and is applicable to the field.

    Take note the above will only work for multipart content types. Make sure to check the request Content-Type header before using the above to parse the body.

提交回复
热议问题