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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个基本的docker-compose文件,用于在容器中运行一个Hyperf项目: ``` version: '3' services: app: build: context: . dockerfile: Dockerfile ports: - "9501:9501" volumes: - ./:/var/www/html environment: - APP_ENV=${APP_ENV} - DB_HOST=${DB_HOST} - DB_PORT=${DB_PORT} - DB_DATABASE=${DB_DATABASE} - DB_USERNAME=${DB_USERNAME} - DB_PASSWORD=${DB_PASSWORD} depends_on: - mysql mysql: image: mysql:5.7 ports: - "3306:3306" environment: - MYSQL_ROOT_PASSWORD=${DB_PASSWORD} - MYSQL_DATABASE=${DB_DATABASE} - MYSQL_USER=${DB_USERNAME} - MYSQL_PASSWORD=${DB_PASSWORD} ``` 在上面的docker-compose文件中,我们定义了两个服务:`app`和`mysql`。`app`服务用于运行我们的Hyperf项目,`mysql`服务用于运行MySQL数据库。 在`app`服务中,我们使用`build`指令来构建一个包含我们的Hyperf项目的Docker镜像。同时,我们使用`ports`指令将容器内的9501端口映射到主机的9501端口。我们还使用`volumes`指令将当前目录挂载到容器内的`/var/www/html`目录,以便在容器内运行项目。最后,我们使用`depends_on`指令将`app`服务依赖于`mysql`服务。 在`mysql`服务中,我们使用`image`指令来指定我们要使用的MySQL镜像。我们还使用`ports`指令将容器内的3306端口映射到主机的3306端口。最后,我们使用`environment`指令来设置MySQL的root密码、数据库名、用户名和密码。 请注意,上面的docker-compose文件仅适用于基本的Hyperf项目。如果您的项目需要其他服务(例如Redis或Elasticsearch),则需要相应地修改docker-compose文件以包含这些服务。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值