图片/文件上传

未匹配的标注
本文档最新版为 2.x,旧版本可能放弃维护,推荐阅读最新版!

图片/文件上传

数据表单通过以下的调用来生成图片/文件上传表单,支持本地和云存储的文件上传。上传组件是基于webuploader实现的,具体的使用配置可参考webuploader官方文档

文件或图片上传表单字段请不要在模型中设置访问器修改器拼接域名,如有相关需求可参考文件/图片域名拼接

$form->file('file_column');
$form->image('image_column');

本地上传

先添加存储配置,config/filesystems.php 添加一项disk:


'disks' => [
    ... ,

    'admin' => [
        'driver' => 'local',
        'root' => public_path('uploads'),
        'visibility' => 'public',
        'url' => env('APP_URL').'/uploads',
    ],
],

设置上传的路径为public/uploads(public_path(‘uploads’))。

然后选择上传的disk,打开config/admin.php找到:


'upload'  => [

    'disk' => 'admin',

    'directory'  => [
        'image'  => 'images',
        'file'   => 'files',
    ]
],

disk设置为上面添加的admindirectory.imagedirectory.file分别为用$form->image($column)$form->file($column)上传的图片和文件的上传目录。

当然你也可以在代码中指定disk

$form->file('file')->disk('your disk name');

云盘上传

如果需要上传到云存储,需要安装对应laravel storage的适配器,拿七牛云存储举例

首先安装 zgldh/qiniu-laravel-storage

同样配置好disk,在config/filesystems.php 添加一项:

'disks' => [
    ... ,
    'qiniu' => [
        'driver'  => 'qiniu',
        'domains' => [
            'default'   => 'xxxxx.com1.z0.glb.clouddn.com', //你的七牛域名
            'https'     => 'dn-yourdomain.qbox.me',         //你的HTTPS域名
            'custom'    => 'static.abc.com',                //你的自定义域名
         ],
        'access_key'=> '',  //AccessKey
        'secret_key'=> '',  //SecretKey
        'bucket'    => '',  //Bucket名字
        'notify_url'=> '',  //持久化处理回调地址
        'url'       => 'http://of8kfibjo.bkt.clouddn.com/',  // 填写文件访问根url
    ],
],

然后修改dcat-admin的上传配置,打开config/admin.php找到:


'upload'  => [

    'disk' => 'qiniu',

    'directory'  => [
        'image'  => 'image',
        'file'   => 'file',
    ],
],

disk选择上面配置的qiniu,或:

$form->file('file')->disk('qiniu');

公共方法

存储驱动 (disk)

修改文件上传源

$form->file('file')->disk('your disk name');

上传路径 (move)

修改上传路径

$form->file('file')->move('public/upload/image1/');

文件名称 (name)

修改上传文件名称

$form->file('file')->name('test.text');

$form->image('picture')->name(function ($file) {
    return 'test.'.$file->guessExtension();
});

随机名称 (uniqueName)

使用随机生成文件名 (md5(uniqid()).extension)

$form->image('picture')->uniqueName();

禁止页面删除文件 (替换上传)

通过disableRemove方法可以禁止用户从页面点击删除服务器上的文件,可以实现图片覆盖上传效果。

$form->file($column[, $label])->disableRemove();

自动上传 (autoUpload)

Since v1.5.2

开启这个功能之后选择完文件之后会立即自动上传,页面将不再显示上传按钮,使用方法如下

$form->file('file')->autoUpload();

$form->image('img')->autoUpload();

禁止删除 (retainable)

Since v1.5.2

开启这个功能之后文件将不会从服务器删除

$form->file('file')->retainable();

$form->image('img')->retainable();

storagePermission

设置上传文件的权限

$form->image('picture')->storagePermission(777);

限制上传文件类型

限制上传文件的类型

$form->file('file')->accept('jpg,png,gif,jpeg');

// 可以指定 mimeTypes, 多个用逗号分割
$form->file('file')->accept('jpg,png,gif,jpeg', 'image/*');

disableChunked

禁用分块上传

$form->file('file')->disableChunked();

分块大小(chunkSize)

分块大小,单位为KB,默认5MB

// 设置为 1MB
$form->file('file')->chunkSize(1024);

文件大小(maxSize)

设置单个文件最大大小,单位为Kb,默认大小为10M

同时应该保证php.ini配置文件的upload_max_filesize参数值必须大于这个方法设置的值。

// 设置单个文件最大为1Mb
$form->file('file')->maxSize(1024);

并发上传线程数 (threads)

设置并发上传线程数,默认3

$form->file('file')->threads(5);

自定义上传接口 (url)

通过url可以设置自定义上传接口

$form->file('file')->url('users/files');

系统提供了Dcat\Admin\Traits\HasUploadedFile这个trait来帮助开发者更轻松地处理上传文件,用法如下

Since v1.0.1 自定义了上传接口之后,上传文件和删除文件功能默认都在同一个接口内处理,并且删除完文件之后需要点击提交按钮对表单数据进行保存。

<?php

namespace App\Admin\Controllers;

use Dcat\Admin\Traits\HasUploadedFile;

class FileController
{
    use HasUploadedFile;

    public function handle()
    {
        $disk = $this->disk('local');

        // 判断是否是删除文件请求
        if ($this->isDeleteRequest()) {
            // 删除文件并响应
            return $this->deleteFileAndResponse($disk);
        }

        // 获取上传的文件
        $file = $this->file();

        // 获取上传的字段名称
        $column = $this->uploader()->upload_column;

        $dir = 'my-images';
        $newName = $column.'-我的文件名称.'.$file->getClientOriginalExtension();

        $result = $disk->putFileAs($dir, $file, $newName);

        $path = "{$dir}/$newName";

        return $result
            ? $this->responseUploaded($path, $disk->url($path))
            : $this->responseErrorMessage('文件上传失败');
    }
}

在你的路由文件app\Admin\routes.php中加上

$router->any('users/files', 'FileController@handle');

deleteUrl

修改删除已上传文件路径,此方法一般不需要修改

$form->file('file')->deleteUrl('file/delete');

disableAutoSave

禁止上传文件后自动保存文件路径到数据库,此方法一般不需要修改

$form->file('file')->disableAutoSave();

配置 (options)

自定义webuploader配置

$form->file('file')->options(['disableGlobalDnd' => true]);

可排序 (sortable)

此方法仅针对多图/文件上传表单有效

Since v1.3.0

$form->multipleImage('images')->sortable();

文件/图片域名拼接

文件或图片上传表单字段请不要在模型中设置访问器修改器拼接域名,如果你需要在访问的时候拼接完整域名,可以在模型中定义一个public方法

<?php

use Illuminate\Support\Str;
use Illuminate\Support\Facades\Storage;

class YourModel extends Model
{
    // 定义一个public方法访问图片或文件
    public function getImage()
    {
        if (Str::contains($this->image, '//')) {
            return $this->image;
        }

        return Storage::disk('admin')->url($this->image);
    }
}

保存域名

Since v1.5.0

如果你需要保存文件域名到数据表,可以使用saveFullUrl方法

$form->image('avatar')->saveFullUrl();

$form->file('...')->saveFullUrl();

图片上传内置方法

压缩、裁切、添加水印等

可以使用压缩、裁切、添加水印等各种方法,需要先安装intervention/image.

更多使用方法请参考[Intervention]:

$form->image($column[, $label]);

// 修改图片上传路径和文件名
$form->image($column[, $label])->move($dir, $name);

// 剪裁图片
$form->image($column[, $label])->crop(int $width, int $height, [int $x, int $y]);

// 加水印
$form->image($column[, $label])->insert($watermark, 'center');

限制上传图片的尺寸

设置文件上传尺寸限制

参数: array 单位为像素

  • width 指定宽度
  • height 指定高度
  • min_width 最小宽度
  • min_height 最小高度
  • max_width 最大宽度
  • max_height 最大高度
  • ratio 宽高比 (width/height)
// 上传宽度为100-300像素之间的图片
$form->image('img')->dimensions(['min_width' = 100, 'max_width' => 300]);

把图片/文件路径保存在其他数据表

通过下面的方法可以把图片或文件的路径保存在单独的附件表,而当前的图片/文件字段只保存ID

这里的示例用的是单图上传表单,如果是多图的话可以按这个思路自行调整。

图片/文件表结构

CREATE TABLE `images` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `path` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '',
  `created_at` timestamp NULL DEFAULT NULL,
  `updated_at` timestamp NULL DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

使用

$form->image('image1')
    ->saving(function ($value) use ($form) {
        if ($form->isEditing() && ! $value) {
            // 编辑页面,删除图片逻辑
            Image::destroy($form->model()->image1);

            return;
        }

        // 新增或编辑页面上传图片
        if ($value) {
            $model = Image::where('path', $value)->first();
        }

        if (empty($model)) {
            $model = new Image();
        }

        $model->path = $value;

        $model->save();

        return $model->getKey();
    })
    ->customFormat(function ($v) {
        if (! $v) {
            return;
        }

        return Image::find((array) $v)->pluck('path')->toArray();
    });

文件上传失败或无法访问?

如果你发现无法上传文件,那么通常有几下几点原因:

  1. Laravel文件上传配置没配对,请检查admin.upload.disk参数,如果你不了解laravel文件上传功能,请阅读文档Laravel - 文件存储
  2. 文件过大,需要调整php.iniupload_max_filesize参数
  3. 文件上传目录没有写权限
  4. php没有安装或没有开启fileinfo扩展

如果你的文件上传成功了,却无法正常访问,那么可能是.env配置文件中的APP_URL参数没有设置正确。

本文章首发在 LearnKu.com 网站上。

上一篇 下一篇
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
讨论数量: 7
发起讨论 只看当前版本


肌无力猛男
dcat admin数据表单上传文件成功,但是报错
1 个点赞 | 24 个回复 | 问答 | 课程版本 2.x
Senkorl
dcat-admin表单 上传avif格式的图片报错
1 个点赞 | 18 个回复 | 问答 | 课程版本 2.x
xylp
dcat 图片上传报错
0 个点赞 | 11 个回复 | 问答 | 课程版本 2.x
jxdr
为什么文件上传只可以传一个文件, 图片可以传多个?
0 个点赞 | 5 个回复 | 代码速记 | 课程版本 2.x
daliu