djiele/multipart

解析 HTTP multipart/form-data 请求体。对 REST API 有用。

7.3.1-stable 2020-08-05 10:19 UTC

This package is auto-updated.

Last update: 2024-09-05 19:31:09 UTC


README

  • 这个类在开发 REST API 时变得必要,因为没有访问服务器配置并安装 "apfd" 扩展(Linux 模块)(Windows)。这个类解析 HTTP multipart/form-data 请求体,并尝试填充 $_FILES$_POST,就像 PHP 所做的那样。这个想法是能够处理非常大的文件而不会出现内存溢出。使用 php://input 流以 8192 字节的块读取,并直接写入磁盘,因此内存占用非常小。

目前没有检查 'post_max_size'、'upload_max_filesize'、'max_file_uploads' 和 'max_input_vars'。也许在未来版本中,将执行这些检查以符合服务器配置。

安装

您可以通过 composer 安装此包

composer require djiele/multipart dev-master
简单用法
require_once __DIR__'./vendor/autoload.php';
use Djiele\Http\MultipartHandler;
$mh = new MultipartHandler();
$mh->populateGlobals();
echo var_export($_POST, true), PHP_EOL;
echo var_export($_FILES, true), PHP_EOL;
在框架中使用此包

只需在框架启动的初期实例化该类。您必须确保在脚本或应用程序的末尾销毁类对象。否则,上传的文件将在您的脚本处理之前被析构函数删除。对于 Laravel 或 Symfony 这样的框架,我通常将处理程序实例化为 'app' 或 'kernel' 的公共成员。

Laravel 示例代码

在 public/index.php 中,在创建应用程序之后,可以添加以下小代码

|--------------------------------------------------------------------------
| Turn On The Lights
|--------------------------------------------------------------------------
|
| We need to illuminate PHP development, so let us turn on the lights.
| This bootstraps the framework and gets it ready for use, then it
| will load up this application so that we can run it and send
| the responses back to the browser and delight our users.
|
*/

$app = require_once __DIR__.'/../bootstrap/app.php';

### multipartHandler call if request is PUT, PATCH, OR DELETE
if (
	isset($_SERVER['REQUEST_METHOD']) 
	&& in_array($_SERVER['REQUEST_METHOD'], ['PUT', 'PATCH', 'DELETE'])
) {
    $app->multipartHandler = new Djiele\Http\MultipartHandler();
    $app->multipartHandler->populateGlobals();
}
###

在此步骤中,$_POST$_FILES 超全局变量已填充,就像 PHP 使用常规 POST 方法一样。然后框架可以填充 Request->files 集合,并允许您像平常一样使用 UploadedFile 对象。请注意,您不能使用 'move' 方法,因为它使用 PHP 的原生函数 'move_uploaded_file',该函数检查文件是否在 POST 请求期间上传。您可以使用 UploadedFile::store() 或 UploadedFile::storeAs(),然后删除临时文件。


$request->file('id')->storeAs('somedir', $uploadedFile->getClientOriginalName());
unlink($uploadedFile->getPathName());

symfony 示例代码

在文件 public/index.php 中,在创建内核之后,添加相同的小代码

use Symfony\Component\Debug\Debug;
use Symfony\Component\HttpFoundation\Request;
use Djiele\Http\MultipartHandler;

require dirname(__DIR__).'/config/bootstrap.php';

if ($_SERVER['APP_DEBUG']) {
    umask(0000);

    Debug::enable();
}

if ($trustedProxies = $_SERVER['TRUSTED_PROXIES'] ?? $_ENV['TRUSTED_PROXIES'] ?? false) {
    Request::setTrustedProxies(explode(',', $trustedProxies), Request::HEADER_X_FORWARDED_ALL ^ Request::HEADER_X_FORWARDED_HOST);
}

if ($trustedHosts = $_SERVER['TRUSTED_HOSTS'] ?? $_ENV['TRUSTED_HOSTS'] ?? false) {
    Request::setTrustedHosts([$trustedHosts]);
}

$kernel = new Kernel($_SERVER['APP_ENV'], (bool) $_SERVER['APP_DEBUG']);

### multipartHandler call if request is PUT, PATCH, OR DELETE
if (
    isset($_SERVER['REQUEST_METHOD']) 
    && in_array($_SERVER['REQUEST_METHOD'], ['PUT', 'PATCH', 'DELETE'])
) {
    $kernel->multipartHandler = new MultipartHandler();
    $kernel->multipartHandler->populateGlobals();
}
###

$request = Request::createFromGlobals();
$response = $kernel->handle($request);
$response->send();
$kernel->terminate($request, $response);

与 Laravel 相同的评论和注意事项

就这样!