PHP multipart form data PUT request?

后端 未结 5 1259
南笙
南笙 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条回答
  •  旧时难觅i
    2020-11-29 07:23

    Please don't delete this again, it's helpful to a majority of people coming here! All previous answers were partial answers that don't cover the solution as a majority of people asking this question would want.

    This takes what has been said above and additionally handles multiple file uploads and places them in $_FILES as someone would expect. To get this to work, you have to add 'Script PUT /put.php' to your Virtual Host for the project per Documentation. I also suspect I'll have to setup a cron to cleanup any '.tmp' files.

    private function _parsePut(  )
    {
        global $_PUT;
    
        /* PUT data comes in on the stdin stream */
        $putdata = fopen("php://input", "r");
    
        /* Open a file for writing */
        // $fp = fopen("myputfile.ext", "w");
    
        $raw_data = '';
    
        /* Read the data 1 KB at a time
           and write to the file */
        while ($chunk = fread($putdata, 1024))
            $raw_data .= $chunk;
    
        /* Close the streams */
        fclose($putdata);
    
        // Fetch content and determine boundary
        $boundary = substr($raw_data, 0, strpos($raw_data, "\r\n"));
    
        if(empty($boundary)){
            parse_str($raw_data,$data);
            $GLOBALS[ '_PUT' ] = $data;
            return;
        }
    
        // 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;
                $tmp_name = null;
                preg_match(
                    '/^(.+); *name="([^"]+)"(; *filename="([^"]+)")?/',
                    $headers['content-disposition'],
                    $matches
                );
                list(, $type, $name) = $matches;
    
                //Parse File
                if( isset($matches[4]) )
                {
                    //if labeled the same as previous, skip
                    if( isset( $_FILES[ $matches[ 2 ] ] ) )
                    {
                        continue;
                    }
    
                    //get filename
                    $filename = $matches[4];
    
                    //get tmp name
                    $filename_parts = pathinfo( $filename );
                    $tmp_name = tempnam( ini_get('upload_tmp_dir'), $filename_parts['filename']);
    
                    //populate $_FILES with information, size may be off in multibyte situation
                    $_FILES[ $matches[ 2 ] ] = array(
                        'error'=>0,
                        'name'=>$filename,
                        'tmp_name'=>$tmp_name,
                        'size'=>strlen( $body ),
                        'type'=>$value
                    );
    
                    //place in temporary directory
                    file_put_contents($tmp_name, $body);
                }
                //Parse Field
                else
                {
                    $data[$name] = substr($body, 0, strlen($body) - 2);
                }
            }
    
        }
        $GLOBALS[ '_PUT' ] = $data;
        return;
    }
    

提交回复
热议问题