19、Hyperf 3 快速使用 - Hypref 3 文件上传

作者: 温新

分类: 【Hyperf 3 基础系列】

阅读: 421

时间: 2023-04-25 15:10:33

hi,我是温新,一名 PHPer

Hypref 版本:Hyperf 3.0

学习目标:掌握文件上传

这篇案例将使用请求 中的方法进行文件上传操作。

第一步:创建控制器

<?php

namespace App\Controller\Test;

use Hyperf\HttpServer\Annotation\Controller;
use Hyperf\HttpServer\Annotation\GetMapping;
use Hyperf\HttpServer\Annotation\PostMapping;
use Hyperf\HttpServer\Contract\RequestInterface;
use Hyperf\HttpServer\Contract\ResponseInterface;
use Hyperf\View\RenderInterface;
use function Hyperf\ViewEngine\view;

#[Controller]
class ImageController
{

    #[GetMapping('/images/create')]
    public function create(RenderInterface $render)
    {

        return $render->render('images.create');
    }

    #[PostMapping('/images/store')]
    public function store(RequestInterface $request)
    {
        if ($request->hasFile('file')) {
            $file = $request->file('file');
            $newFileName = date('YmdHis') . uniqid() . '.' . $file->getExtension();

            if (move_uploaded_file($file->getRealPath(), $newFileName)) {
                return ['message'=>'上传成功'];
            }
            // 上传报错
            //$file->moveTo('/uploads/' . $newFileName);
        }
        return '请选择图片';
    }
}

第二步:创建视图

<!-- /storage/view/images/create.blade.php -->
<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>上传图片</title>
    <link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/5.2.3/css/bootstrap.css" rel="stylesheet">
</head>
<body>

    <div class="container mt-3">
        <form action="/images/store" method="post" enctype="multipart/form-data">
            <div class="mb-3">
                <label for="formFileSm" class="form-label">图片上传</label>
                <input class="form-control form-control-sm" id="formFileSm" type="file" name="file">
            </div>
            <button type="submit" class="btn btn-primary">提交</button>
        </form>
    </div>
</body>
</html>

关于错误

1、使用文档中介绍的方法 moveTo 上传文件,出现致命错误,错误中所提示的目录我已经创建,但仍旧报错。错误信息如下:

[ERROR] rename(/tmp/swoole.upfile.5rTy4D,/uploads/aaa.jpg): No such file or directory[167] in /www/learn-hypref31/vendor/hyperf/http-message/src/Upload/UploadedFile.php
[ERROR] #0 [internal function]: Hyperf\ExceptionHandler\Listener\ErrorExceptionHandler::Hyperf\ExceptionHandler\Listener\{closure}()

2、查看 moveTo 方法的实现,使用的是 move_uploaded_file,源码如下:

public function moveTo($targetPath)
{
    $this->validateActive();

    if (! $this->isStringNotEmpty($targetPath)) {
        throw new InvalidArgumentException('Invalid path provided for move operation');
    }

    if ($this->tmpFile) {
        $this->moved = php_sapi_name() == 'cli' ? rename($this->tmpFile, $targetPath) : move_uploaded_file($this->tmpFile, $targetPath);
    }

    if (! $this->moved) {
        throw new RuntimeException(sprintf('Uploaded file could not be move to %s', $targetPath));
    }
}

于是,我直接在控制器中使用 move_uploaded_file 进行上传,此时,文件上传成功。

使用官方文档中的 moveTo 方法为什么会报错,原因暂时不清,后续会查阅资料。

请登录后再评论