hyperf 上传文件遇到的问题

2 篇文章 0 订阅

安装扩展和使用细节参考官方文档即可,这里更多的是介绍一些遇到的问题:
https://hyperf.wiki/2.0/#/zh-cn/filesystem

安装:
首先执行
composer require hyperf/filesystem
使用阿里云 OSS 适配器时执行
composer require xxtime/flysystem-aliyun-oss
发布配置文件:
php bin/hyperf.php vendor:publish hyperf/filesystem

其次是验证文件上传的问题:
以前 laravel 的写法是直接在 controller里
类似:


public function uploadFile(Request $request){
    $rtn = RspHelper::makeJsonResponse();
    $validator = Validator::make($request->all(), [
        'type' => 'nullable|string',
        'file' => 'required|file', // 注意这里
    ]);
    if ($validator->fails()) {
        RspHelper::setErr($rtn, 'PARAM_ERROR');
        return response()->json($rtn);
    };

    $type = $request->input('type','attachment');
    $file = $request->file('file');
}

但是在 hyperf 里, $request->all() 并没有文件,只能获取到 get 和 post的值:
定义文件:vendor/hyperf/http-server/src/Request.php
你也可以继续追函数, 找到文件(vendor/hyperf/http-message/src/Server/Request.php 这里面定义了请求来以后 get post file cookie 等是如何赋值给 request的)

而在 laravel 里 $request->all() 是有添加 file的:
定义文件在: vendor/laravel/framework/src/Illuminate/Http/Concerns/InteractsWithInput.php
i n p u t = a r r a y r e p l a c e r e c u r s i v e ( input = array_replace_recursive( input=arrayreplacerecursive(this->input(), $this->allFiles());

于是我第一反应是 hyperf 有bug 然后做了修改并提了 PR 见:https://github.com/hyperf/hyperf/pull/2529
但是后来发现 在hyperf 的 FomRequest.php 中的函数: ValidationData 有主动处理过这个问题:

protected function validationData(): array
{
    return array_merge_recursive($this->all(), $this->getUploadedFiles());
}

而且还有 PR: https://github.com/hyperf-cloud/hyperf/pull/694
所以也就有了 我提的PR的对话。
那么针对这种情况上传文件的程序举例:
// 当然可以使用 merge ,但是我这里采用 自定义请求类的方式举例:

首先创建 请求类: php bin/hyperf.php gen:request UploadRequest
内容为:

<?php

declare(strict_types=1);

namespace App\Request;

use App\Constants\StatusCode;
use App\Exception\ApiException;
use Hyperf\Contract\ValidatorInterface;
use Hyperf\Validation\Request\FormRequest;
use Hyperf\Validation\ValidationException;

class UploadRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     */
    public function authorize(): bool
    {
        return true;
    }

    /**
     * Get the validation rules that apply to the request.
     */
    public function rules(): array
    {
        return [
            'type' => 'nullable|string',
            'file' => 'required|file',
        ];
    }

    public function messages(): array
    {
        return [
            'required' => ':attribute 必填',
            'file' => ':attribute 必须上传',
        ];
    }

  // 这里我是希望走到我自己定义的 异常处理,你如果没有自定义,去掉这个函数的重写即可。
    protected function failedValidation(ValidatorInterface $validator)
    {
        throw new ApiException(StatusCode::PARAM_ERROR, $validator->errors()->first());
    }
}

controller里使用:

use App\Request\UploadRequest;


public function upload(UploadRequest $request, ResponseInterface $response, Filesystem $filesystem)
{
    $type = $request->input('type','image');
    $file = $request->file('file');
    // $uploadData = $request->validated(); // 也可以使用这种方式获取参数
    
    if(!$file->isValid()){
        return '上传文件错误';
    }

    // XXXX 其他逻辑
}

OSS 的坑:
解决OSS 提示:

Notice: iconv(): Wrong charset, conversion from GBK' toUTF-8//IGNORE’ is not allowed in /hyperf-skeleton/hyperf-winkar-mall-admin/vendor/aliyuncs/oss-sdk-php/src/OSS/OssClient.php on line 3075

详细参见这里: https://github.com/aliyun/aliyun-oss-php-sdk/issues/101

docker file 添加:
RUN apk --no-cache --allow-untrusted --repository http://dl-cdn.alpinelinux.org/alpine/edge/community/ add gnu-libiconv
ENV LD_PRELOAD /usr/lib/preloadable_libiconv.so php

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值