PHP multipart form data PUT request?

后端 未结 5 1254
南笙
南笙 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:35

    For whom using Apiato (Laravel) framework: create new Middleware like file below, then declair this file in your laravel kernel file within the protected $middlewareGroups variable (inside web or api, whatever you want) like this:

    protected $middlewareGroups = [
        'web' => [],
        'api' => [HandlePutFormData::class],
    ];
    

    method() == 'POST' or $request->method() == 'GET') {
                return $next($request);
            }
            if (preg_match('/multipart\/form-data/', $request->headers->get('Content-Type')) or
                preg_match('/multipart\/form-data/', $request->headers->get('content-type'))) {
                $parameters = $this->decode();
    
                $request->merge($parameters['inputs']);
                $request->files->add($parameters['files']);
            }
    
            return $next($request);
        }
    
        public function decode()
        {
            $files = [];
            $data  = [];
            // Fetch content and determine boundary
            $rawData  = file_get_contents('php://input');
            $boundary = substr($rawData, 0, strpos($rawData, "\r\n"));
            // Fetch and process each part
            $parts = $rawData ? array_slice(explode($boundary, $rawData), 1) : [];
            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($rawHeaders, $content) = explode("\r\n\r\n", $part, 2);
                $content = substr($content, 0, strlen($content) - 2);
                // Parse the headers list
                $rawHeaders = explode("\r\n", $rawHeaders);
                $headers    = array();
                foreach ($rawHeaders 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(
                        '/^form-data; *name="([^"]+)"(; *filename="([^"]+)")?/',
                        $headers['content-disposition'],
                        $matches
                    );
                    $fieldName = $matches[1];
                    $fileName  = (isset($matches[3]) ? $matches[3] : null);
                    // If we have a file, save it. Otherwise, save the data.
                    if ($fileName !== null) {
                        $localFileName = tempnam(sys_get_temp_dir(), 'sfy');
                        file_put_contents($localFileName, $content);
                        $files = $this->transformData($files, $fieldName, [
                            'name'     => $fileName,
                            'type'     => $headers['content-type'],
                            'tmp_name' => $localFileName,
                            'error'    => 0,
                            'size'     => filesize($localFileName)
                        ]);
                        // register a shutdown function to cleanup the temporary file
                        register_shutdown_function(function () use ($localFileName) {
                            unlink($localFileName);
                        });
                    } else {
                        $data = $this->transformData($data, $fieldName, $content);
                    }
                }
            }
            $fields = new ParameterBag($data);
    
            return ["inputs" => $fields->all(), "files" => $files];
        }
    
        private function transformData($data, $name, $value)
        {
            $isArray = strpos($name, '[]');
            if ($isArray && (($isArray + 2) == strlen($name))) {
                $name = str_replace('[]', '', $name);
                $data[$name][]= $value;
            } else {
                $data[$name] = $value;
            }
            return $data;
        }
    }
    

    Pls note: Those codes above not all mine, some from above comment, some modified by me.

提交回复
热议问题