Skip to content
全部文档

文件上传

简介

文件上传字段基于 Filepond

php
use Filament\Forms\Components\FileUpload;

FileUpload::make('attachment')
文件上传文件上传

TIP

Filament 也支持 spatie/laravel-medialibrary。更多信息请参阅我们的 插件文档

DANGER

默认情况下,FileUpload 接受所配置磁盘内的任意字符串路径——字段值由客户端控制,被篡改的请求可以提交同一磁盘上的其他任意文件。若磁盘上存放了多个用户、租户或记录的文件,请对该字段调用 ->preventFilePathTampering()(或通过 FileUpload::configureUsing() 全局应用),或在磁盘/目录层面隔离上传,使字段只能指向当前所有者的文件。

配置存储磁盘与目录

默认情况下,文件会上传到 配置文件 中定义的存储磁盘。你也可以设置 FILESYSTEM_DISK 环境变量来更改。

TIP

为正确预览图片及其他文件,FilePond 要求文件与应用同源提供,或具备适当的 CORS 响应头。请确保 APP_URL 环境变量正确,或修改 filesystem 驱动以设置正确的 URL。若文件托管在 S3 等独立域名上,请确保已配置 CORS 响应头。

要更改特定字段的磁盘与目录,以及文件可见性,请使用 disk()directory()visibility() 方法。默认情况下,文件以 private 可见性上传到存储磁盘,除非磁盘设置为 public

php
use Filament\Forms\Components\FileUpload;

FileUpload::make('attachment')
    ->disk('s3')
    ->directory('form-attachments')
    ->visibility('public')

TIP

除了允许静态值外,disk()directory()visibility() 方法也接受函数以动态计算。你可以将各种工具作为参数注入到这些函数中。

WARNING

默认可见性由磁盘名称的字面字符串匹配决定:名称恰好为 public 的磁盘视为公开可见,其他磁盘名称默认 private。因此,若自定义磁盘恰好命名为 public,即使底层配置为私有也会被当作公开;而名称不同的自定义公开磁盘则默认私有。为避免混淆,请为自定义磁盘使用明确名称,或在每个字段上显式设置 visibility()

INFO

若文件被移除,由开发者负责从磁盘删除,因为 Filament 无法知晓它们是否还被其他地方依赖。一种自动做法是监听 模型事件

上传多个文件

你也可以上传多个文件。这会以 JSON 存储 URL:

php
use Filament\Forms\Components\FileUpload;

FileUpload::make('attachments')
    ->multiple()

你也可以传入布尔值,以控制是否允许一次上传多个文件:

php
use Filament\Forms\Components\FileUpload;

FileUpload::make('attachments')
    ->multiple(FeatureFlag::active())

TIP

除了允许静态值外,multiple() 方法也接受函数以动态计算。你可以将各种工具作为参数注入到该函数中。

若使用 Eloquent 保存文件 URL,请务必在模型属性上添加 array 类型转换

php
use Illuminate\Database\Eloquent\Model;

class Message extends Model
{
    /**
     * @return array<string, string>
     */
    protected function casts(): array
    { 
        return [
            'attachments' => 'array',
        ];
    }

    // ...
}

控制最大并行上传数

你可以使用 maxParallelUploads() 方法控制最大并行上传数:

php
use Filament\Forms\Components\FileUpload;

FileUpload::make('attachments')
    ->multiple()
    ->maxParallelUploads(1)

这会将并行上传数限制为 1。若未设置,将使用 FilePond 默认值,即 2

TIP

除了允许静态值外,maxParallelUploads() 方法也接受函数以动态计算。你可以将各种工具作为参数注入到该函数中。

控制文件名

默认情况下,新上传的文件会生成随机文件名,以确保永不与现有文件冲突。

控制文件名的安全影响

在使用 preserveFilenames()getUploadedFileNameForStorageUsing() 方法之前,请了解其安全影响。若允许用户以自有文件名上传,存在被利用以上传恶意文件的可能。即使使用 acceptedFileTypes() 方法限制可上传类型也仍适用,因为它使用 Laravel 的 mimetypes 规则,只校验 mime 类型、不校验扩展名,而 mime 类型可被篡改。

这特别与 TemporaryUploadedFile 对象上的 getClientOriginalName() 方法有关,而 preserveFilenames() 会使用该方法。默认情况下,Livewire 为每个上传文件生成随机文件名,并根据文件的 mime 类型确定扩展名。

localpublic 文件系统磁盘上使用这些方法时,若攻击者以欺骗性 mime 类型上传 PHP 文件,应用将面临远程代码执行风险。使用 S3 磁盘可防范这一特定攻击向量,因为 S3 不会像本地存储那样由服务器执行 PHP 文件。

若使用 localpublic 磁盘,建议使用 storeFileNamesIn() 方法 将原始文件名存入数据库单独列,并在文件系统中保留随机生成的文件名。这样既能向用户展示原始文件名,又能保持文件系统安全。

除上述安全问题外,还应意识到:允许用户以自有文件名上传可能导致与现有文件冲突,并增加存储管理难度。若未将文件限定到特定目录,用户可能上传同名文件并覆盖他人内容,因此这些功能在任何情况下都只应向受信任用户开放。

保留原始文件名

DANGER

使用此功能前,请确保已阅读 安全影响

要保留上传文件的原始文件名,请使用 preserveFilenames() 方法:

php
use Filament\Forms\Components\FileUpload;

FileUpload::make('attachment')
    ->preserveFilenames()

你也可以传入布尔值,以控制是否保留原始文件名:

php
use Filament\Forms\Components\FileUpload;

FileUpload::make('attachment')
    ->preserveFilenames(FeatureFlag::active())

TIP

除了允许静态值外,preserveFilenames() 方法也接受函数以动态计算。你可以将各种工具作为参数注入到该函数中。

生成自定义文件名

DANGER

使用此功能前,请确保已阅读 安全影响

你可以使用 getUploadedFileNameForStorageUsing() 方法完全自定义文件名的生成方式,并在闭包中根据已上传的 $file 返回字符串:

php
use Livewire\Features\SupportFileUploads\TemporaryUploadedFile;

FileUpload::make('attachment')
    ->getUploadedFileNameForStorageUsing(
        fn (TemporaryUploadedFile $file): string => (string) str($file->getClientOriginalName())
            ->prepend('custom-prefix-'),
    )

TIP

你可以将各种工具作为参数注入到传递给 getUploadedFileNameForStorageUsing() 的函数中。

单独存储原始文件名

你可以使用 storeFileNamesIn() 方法保留随机生成的文件名,同时仍存储原始文件名:

php
use Filament\Forms\Components\FileUpload;

FileUpload::make('attachments')
    ->multiple()
    ->storeFileNamesIn('attachment_file_names')

attachment_file_names 现在会存储上传文件的原始文件名,以便在提交表单时保存到数据库。若使用 multiple() 上传多个文件,请确保也在该 Eloquent 模型属性上添加 array 类型转换

TIP

除了允许静态值外,storeFileNamesIn() 方法也接受函数以动态计算。你可以将各种工具作为参数注入到该函数中。

授权已有文件路径

FileUpload 字段的值是字符串或字符串数组,包含所配置磁盘上的文件路径。与其他 Livewire 表单字段值一样,它由客户端控制:请求可被拦截,以将提交的路径改为同一磁盘上的其他任意文件。若字段指向不得被其他用户访问的资源——共享磁盘上的私有文档,或按用户划分的目录——攻击者就可能让记录引用(并为其提供签名 URL)他人的文件。

Filament 默认允许这种行为,因为合法功能会依赖它——例如将字段设为预上传模板文件的操作,或「从另一条记录复制」按钮。若没有任何字段依赖此类流程,请对该字段调用 preventFilePathTampering() 以启用内置检查:

php
use Filament\Forms\Components\FileUpload;

FileUpload::make('avatar')
    ->preventFilePathTampering()

Filament 会将每个提交的字符串路径与从记录最初加载的值进行比较(通过字段名对应属性的 $record->getOriginal())。不匹配的路径会使字段校验失败,因此记录绝不会以被篡改的值保存。新上传的文件始终可通过,字段仍可清空,对于 multiple() 字段则逐条检查。

WARNING

preventFilePathTampering() 需要表单上有一条记录。若没有——例如在创建页上——除非 allowFilePathUsing 回调批准,否则每个提交的字符串路径都会校验失败。新上传不受影响。

要在不逐字段重复的情况下,对应用中每个 FileUpload 应用此检查,请在服务提供者的 boot() 方法中调用 configureUsing()

php
use Filament\Forms\Components\FileUpload;

FileUpload::configureUsing(function (FileUpload $component): void {
    $component->preventFilePathTampering();
});

单个字段仍可通过调用 preventFilePathTampering(false) 退出。

用回调允许额外文件路径

若应用合法引用了记录上不存在的路径——例如选择预上传模板文件的按钮——请传入 allowFilePathUsing 参数予以批准。已批准的路径会绕过校验错误:

php
use Filament\Forms\Components\FileUpload;

FileUpload::make('avatar')
    ->preventFilePathTampering(
        allowFilePathUsing: fn (string $file): bool => str_starts_with($file, 'templates/'),
    )

TIP

你可以将各种工具作为参数注入到传递给 allowFilePathUsing 的函数中。

校验错误消息可通过 validationMessages() 使用 tampered 键自定义:

php
use Filament\Forms\Components\FileUpload;

FileUpload::make('avatar')
    ->preventFilePathTampering()
    ->validationMessages([
        'tampered' => 'The selected attachment is not permitted.',
    ])

头像模式

你可以使用 avatar() 方法为文件上传字段启用头像模式:

php
use Filament\Forms\Components\FileUpload;

FileUpload::make('avatar')
    ->avatar()

这将只允许上传图片,并在上传后以紧凑圆形布局显示,非常适合头像。

启用头像模式的文件上传启用头像模式的文件上传

此功能与 圆形裁剪器 搭配效果很好。

图片编辑器

你可以使用 imageEditor() 方法为文件上传字段启用图片编辑器:

php
use Filament\Forms\Components\FileUpload;

FileUpload::make('image')
    ->image()
    ->imageEditor()

上传图片后,点击铅笔图标即可打开编辑器。也可以点击已有图片上的铅笔图标打开编辑器;保存时会移除并重新上传该图片。

带裁剪控件的文件上传图片编辑器带裁剪控件的文件上传图片编辑器

你也可以传入布尔值,以控制是否启用图片编辑器:

php
use Filament\Forms\Components\FileUpload;

FileUpload::make('image')
    ->image()
    ->imageEditor(FeatureFlag::active())

TIP

除了允许静态值外,imageEditor() 方法也接受函数以动态计算。你可以将各种工具作为参数注入到该函数中。

允许用户按宽高比裁剪图片

你可以使用 imageEditorAspectRatioOptions() 方法,允许用户按一组特定宽高比裁剪图片:

php
use Filament\Forms\Components\FileUpload;

FileUpload::make('image')
    ->image()
    ->imageEditor()
    ->imageEditorAspectRatioOptions([
        '16:9',
        '4:3',
        '1:1',
    ])

也可以通过传入 null 作为选项,允许用户不选择宽高比,即「自由裁剪」:

php
use Filament\Forms\Components\FileUpload;

FileUpload::make('image')
    ->image()
    ->imageEditor()
    ->imageEditorAspectRatioOptions([
        null,
        '16:9',
        '4:3',
        '1:1',
    ])

TIP

除了允许静态值外,imageEditorAspectRatioOptions() 方法也接受函数以动态计算。你可以将各种工具作为参数注入到该函数中。

设置图片编辑器模式

你可以使用 imageEditorMode() 方法更改图片编辑器模式,接受 123。这些选项在 Cropper.js 文档 中有说明:

php
use Filament\Forms\Components\FileUpload;

FileUpload::make('image')
    ->image()
    ->imageEditor()
    ->imageEditorMode(2)

TIP

除了允许静态值外,imageEditorMode() 方法也接受函数以动态计算。你可以将各种工具作为参数注入到该函数中。

自定义图片编辑器空白填充色

默认情况下,图片编辑器会将图片周围的空白区域设为透明。你可以使用 imageEditorEmptyFillColor() 方法自定义:

php
use Filament\Forms\Components\FileUpload;

FileUpload::make('image')
    ->image()
    ->imageEditor()
    ->imageEditorEmptyFillColor('#000000')

TIP

除了允许静态值外,imageEditorEmptyFillColor() 方法也接受函数以动态计算。你可以将各种工具作为参数注入到该函数中。

设置图片编辑器视口尺寸

你可以使用 imageEditorViewportWidth()imageEditorViewportHeight() 方法更改图片编辑器视口尺寸,它们会生成可跨设备尺寸使用的宽高比:

php
use Filament\Forms\Components\FileUpload;

FileUpload::make('image')
    ->image()
    ->imageEditor()
    ->imageEditorViewportWidth('1920')
    ->imageEditorViewportHeight('1080')

TIP

除了允许静态值外,imageEditorViewportWidth()imageEditorViewportHeight() 方法也接受函数以动态计算。你可以将各种工具作为参数注入到这些函数中。

允许用户圆形裁剪图片

你可以使用 circleCropper() 方法允许用户以圆形裁剪图片:

php
use Filament\Forms\Components\FileUpload;

FileUpload::make('image')
    ->image()
    ->avatar()
    ->imageEditor()
    ->circleCropper()

avatar() 方法 搭配最为合适,后者会以紧凑圆形布局渲染图片。

你也可以传入布尔值,以控制是否启用圆形裁剪器:

php
use Filament\Forms\Components\FileUpload;

FileUpload::make('image')
    ->image()
    ->avatar()
    ->imageEditor()
    ->circleCropper(FeatureFlag::active())

TIP

除了允许静态值外,circleCropper() 方法也接受函数以动态计算。你可以将各种工具作为参数注入到该函数中。

强制特定宽高比

若需确保所有上传图片符合特定宽高比,可将 imageAspectRatio() 校验方法automaticallyOpenImageEditorForAspectRatio() 结合。当用户上传的图片不符合所需宽高比时,会自动打开简化的图片编辑器,允许在保存前裁剪:

php
use Filament\Forms\Components\FileUpload;

FileUpload::make('banner')
    ->image()
    ->imageAspectRatio('16:9')
    ->automaticallyOpenImageEditorForAspectRatio()

需要裁剪时出现的编辑器仅显示裁剪区域与保存/取消按钮——不包含使用 imageEditor() 时出现的完整编辑控件(旋转、位置输入等)。这提供了专注于获得正确宽高比的精简体验。

若希望用户使用完整的图片编辑器控件,可同时启用两者:

php
use Filament\Forms\Components\FileUpload;

FileUpload::make('banner')
    ->image()
    ->imageEditor()
    ->imageAspectRatio('16:9')
    ->automaticallyOpenImageEditorForAspectRatio()

两者都启用时,宽高比不匹配仍会自动打开图片编辑器,但用户还会在每张已上传图片上看到编辑按钮,并可使用全部编辑控件。

你也可以传入布尔值,以控制是否启用宽高比编辑器:

php
use Filament\Forms\Components\FileUpload;

FileUpload::make('banner')
    ->image()
    ->imageAspectRatio('16:9')
    ->automaticallyOpenImageEditorForAspectRatio(FeatureFlag::active())

TIP

除了允许静态值外,automaticallyOpenImageEditorForAspectRatio() 方法也接受函数以动态计算。你可以将各种工具作为参数注入到该函数中。

INFO

automaticallyOpenImageEditorForAspectRatio() 方法只能与单一宽高比一起使用。若需允许多个宽高比,请仅用 imageAspectRatio() 做校验,并考虑结合 imageEditor()imageEditorAspectRatioOptions(),让用户选择偏好比例。

INFO

启用 multiple() 时,automaticallyOpenImageEditorForAspectRatio() 方法不可用。

不使用编辑器裁剪与调整图片尺寸

Filepond 允许在上传前裁剪并调整图片尺寸,无需单独编辑器。你可以使用 automaticallyResizeImagesToHeight()automaticallyResizeImagesToWidth() 方法自定义此行为。要使这些方法生效,应设置 automaticallyResizeImagesMode()——取值为 forcecovercontain

php
use Filament\Forms\Components\FileUpload;

FileUpload::make('image')
    ->image()
    ->automaticallyCropImagesToAspectRatio('16:9')
    ->automaticallyResizeImagesMode('cover')
    ->automaticallyResizeImagesToWidth('1920')
    ->automaticallyResizeImagesToHeight('1080')

要启用特定宽高比的自动裁剪,请使用 automaticallyCropImagesToAspectRatio() 方法。若同时用 imageAspectRatio() 做校验并希望自动裁剪使用相同比例,可无参调用 automaticallyCropImagesToAspectRatio()

php
use Filament\Forms\Components\FileUpload;

FileUpload::make('image')
    ->image()
    ->imageAspectRatio('16:9')
    ->automaticallyCropImagesToAspectRatio()
    ->automaticallyResizeImagesMode('cover')
    ->automaticallyResizeImagesToWidth('1920')
    ->automaticallyResizeImagesToHeight('1080')

TIP

除了允许静态值外,automaticallyResizeImagesMode()automaticallyCropImagesToAspectRatio()automaticallyResizeImagesToHeight()automaticallyResizeImagesToWidth() 方法也接受函数以动态计算。你可以将各种工具作为参数注入到这些函数中。

WARNING

使用自动图片裁剪时,裁剪会在无用户交互的情况下自动应用。用户无法选择保留图片的哪一部分。若希望用户控制裁剪方式,请改用 automaticallyOpenImageEditorForAspectRatio()

更改文件上传区域外观

你也可以更改 Filepond 组件的整体外观。这些方法的可用选项见 Filepond 网站

php
use Filament\Forms\Components\FileUpload;

FileUpload::make('attachment')
    ->imagePreviewHeight('250')
    ->loadingIndicatorPosition('left')
    ->panelAspectRatio('2:1')
    ->panelLayout('integrated')
    ->removeUploadedFileButtonPosition('right')
    ->uploadButtonPosition('left')
    ->uploadProgressIndicatorPosition('left')

TIP

除了允许静态值外,这些方法也接受函数以动态计算。你可以将各种工具作为参数注入到这些函数中。

以网格显示文件

你可以通过设置 panelLayout() 使用 Filepond grid 布局

php
use Filament\Forms\Components\FileUpload;

FileUpload::make('attachments')
    ->multiple()
    ->panelLayout('grid')
网格布局的文件上传网格布局的文件上传

TIP

除了允许静态值外,panelLayout() 方法也接受函数以动态计算。你可以将各种工具作为参数注入到该函数中。

重新排序文件

你也可以使用 reorderable() 方法允许用户重新排序已上传的文件:

php
use Filament\Forms\Components\FileUpload;

FileUpload::make('attachments')
    ->multiple()
    ->reorderable()

使用此方法时,FilePond 可能将新上传的文件添加到列表开头而非末尾。要修复这一点,请使用 appendFiles() 方法:

php
use Filament\Forms\Components\FileUpload;

FileUpload::make('attachments')
    ->multiple()
    ->reorderable()
    ->appendFiles()

你也可以向 reorderable()appendFiles() 方法传入布尔值,以控制文件是否可重新排序,以及新文件是否应追加到列表末尾:

php
use Filament\Forms\Components\FileUpload;

FileUpload::make('attachments')
    ->multiple()
    ->reorderable(FeatureFlag::active())
    ->appendFiles(FeatureFlag::active())

TIP

除了允许静态值外,reorderable()appendFiles() 方法也接受函数以动态计算。你可以将各种工具作为参数注入到这些函数中。

在新标签页打开文件

你可以使用 openable() 方法为每个文件添加在新标签页打开的按钮:

php
use Filament\Forms\Components\FileUpload;

FileUpload::make('attachments')
    ->multiple()
    ->openable()

你也可以传入布尔值,以控制文件是否可在新标签页打开:

php
use Filament\Forms\Components\FileUpload;

FileUpload::make('attachments')
    ->multiple()
    ->openable(FeatureFlag::active())

TIP

除了允许静态值外,openable() 方法也接受函数以动态计算。你可以将各种工具作为参数注入到该函数中。

可在新标签页打开的文件上传可在新标签页打开的文件上传

自定义打开文件时使用的 URL

默认情况下,「打开」按钮链接到 FilePond 中用于显示文件的同一 URL。若需要不同的 URL——例如签名 URL、不同域名上的 URL,或由 Spatie Media Library 的图片生成器 生成的 PDF 缩略图等派生文件 URL——可使用 getOpenableFileUrlUsing() 方法:

php
use Filament\Forms\Components\FileUpload;

FileUpload::make('attachments')
    ->multiple()
    ->openable()
    ->getOpenableFileUrlUsing(fn (string $file): string => Storage::disk('s3')->temporaryUrl($file, now()->addMinutes(5)))

该函数接收已存储的 $file 路径,并必须返回点击「打开」按钮时应使用的 URL。返回 null 则回退到默认 URL。

TIP

getOpenableFileUrlUsing() 方法也接受带工具注入的函数。除标准工具外,$file 参数包含已存储的文件路径。

下载文件

若希望改为为每个文件添加下载按钮,可使用 downloadable() 方法:

php
use Filament\Forms\Components\FileUpload;

FileUpload::make('attachments')
    ->multiple()
    ->downloadable()

你也可以传入布尔值,以控制文件是否可下载:

php
use Filament\Forms\Components\FileUpload;

FileUpload::make('attachments')
    ->multiple()
    ->downloadable(FeatureFlag::active())

TIP

除了允许静态值外,downloadable() 方法也接受函数以动态计算。你可以将各种工具作为参数注入到该函数中。

可下载的文件上传可下载的文件上传

自定义下载文件时使用的 URL

默认情况下,下载按钮链接到 FilePond 中用于显示文件的同一 URL。若需要不同的 URL——例如带 Content-Disposition: attachment 头的签名 URL,或预览渲染派生图片时指向原文件的 URL——可使用 getDownloadableFileUrlUsing() 方法:

php
use Filament\Forms\Components\FileUpload;

FileUpload::make('attachments')
    ->multiple()
    ->downloadable()
    ->getDownloadableFileUrlUsing(fn (string $file): string => route('attachments.download', ['path' => $file]))

该函数接收已存储的 $file 路径,并必须返回点击下载按钮时应使用的 URL。返回 null 则回退到默认 URL。

TIP

getDownloadableFileUrlUsing() 方法也接受带工具注入的函数。除标准工具外,$file 参数包含已存储的文件路径。

预览文件

默认情况下,部分文件类型可在 FilePond 中预览。若希望禁用所有文件的预览,可使用 previewable(false) 方法:

php
use Filament\Forms\Components\FileUpload;

FileUpload::make('attachments')
    ->multiple()
    ->previewable(false)

TIP

除了允许静态值外,previewable() 方法也接受函数以动态计算。你可以将各种工具作为参数注入到该函数中。

提交表单时移动而非复制文件

默认情况下,文件会先上传到 Livewire 的临时存储目录,再在提交表单时复制到目标目录。若希望改为移动文件(前提是临时上传与永久文件存储在同一磁盘),可使用 moveFiles() 方法:

php
use Filament\Forms\Components\FileUpload;

FileUpload::make('attachment')
    ->moveFiles()

你也可以传入布尔值,以控制是否移动文件:

php
use Filament\Forms\Components\FileUpload;

FileUpload::make('attachment')
    ->moveFiles(FeatureFlag::active())

TIP

除了允许静态值外,moveFiles() 方法也接受函数以动态计算。你可以将各种工具作为参数注入到该函数中。

阻止永久存储文件

若希望在提交表单时阻止永久存储文件,可使用 storeFiles(false) 方法:

php
use Filament\Forms\Components\FileUpload;

FileUpload::make('attachment')
    ->storeFiles(false)

提交表单时,将返回临时文件上传对象,而非永久存储的文件路径。这非常适合导入的 CSV 等临时文件。

TIP

除了允许静态值外,storeFiles() 方法也接受函数以动态计算。你可以将各种工具作为参数注入到该函数中。

WARNING

除非使用 previewable(false),否则图片、视频和音频文件不会在表单预览中显示已存储的文件名。这是由于 FilePond 预览插件的限制。

根据 EXIF 数据校正图片方向

默认情况下,FilePond 会根据 EXIF 数据自动校正图片方向。若希望禁用此行为,可使用 orientImagesFromExif(false) 方法:

php
use Filament\Forms\Components\FileUpload;

FileUpload::make('attachment')
    ->orientImagesFromExif(false)

TIP

除了允许静态值外,orientImagesFromExif() 方法也接受函数以动态计算。你可以将各种工具作为参数注入到该函数中。

隐藏移除文件按钮

也可以使用 deletable(false) 隐藏移除已上传文件的按钮:

php
use Filament\Forms\Components\FileUpload;

FileUpload::make('attachment')
    ->deletable(false)

TIP

除了允许静态值外,deletable() 方法也接受函数以动态计算。你可以将各种工具作为参数注入到该函数中。

阻止粘贴文件

你可以使用 pasteable(false) 方法禁用通过剪贴板粘贴文件的能力:

php
use Filament\Forms\Components\FileUpload;

FileUpload::make('attachment')
    ->pasteable(false)

TIP

除了允许静态值外,pasteable() 方法也接受函数以动态计算。你可以将各种工具作为参数注入到该函数中。

阻止获取文件信息

表单加载时,会自动检测文件是否存在、大小以及类型。这些都在后端完成。使用远程存储且文件较多时,这可能很耗时。你可以使用 fetchFileInformation(false) 方法禁用此功能:

php
use Filament\Forms\Components\FileUpload;

FileUpload::make('attachment')
    ->fetchFileInformation(false)

TIP

除了允许静态值外,fetchFileInformation() 方法也接受函数以动态计算。你可以将各种工具作为参数注入到该函数中。

自定义上传中消息

你可以使用 uploadingMessage() 方法自定义表单提交按钮上显示的上传中消息:

php
use Filament\Forms\Components\FileUpload;

FileUpload::make('attachment')
    ->uploadingMessage('Uploading attachment...')

TIP

除了允许静态值外,uploadingMessage() 方法也接受函数以动态计算。你可以将各种工具作为参数注入到该函数中。

文件上传校验

除了 校验 页面列出的全部规则外,还有专门针对文件上传的额外规则。

由于 Filament 由 Livewire 驱动并使用其文件上传系统,你还应参阅 config/livewire.php 中的默认 Livewire 文件上传校验规则。这也控制了 12MB 的文件大小上限。

INFO

这些校验规则大多仅适用于新上传的文件。在添加校验规则之前已上传的现有文件不会被重新校验。

文件类型校验

DANGER

默认情况下,FileUpload 接受任意文件类型,与 Laravel 的 file 校验规则相同。在由可执行 PHP 的 Web 服务器提供的 localpublic 磁盘上,这意味着用户可以上传 .php 文件并使其作为代码执行——即远程代码执行。除非有明确理由,否则应始终调用 acceptedFileTypes()(或 image())并传入明确的 MIME 类型列表。这样做还会通过 mimetypes 校验规则启用 Laravel 对 PHP 系列扩展名(.php.phtml.phar 等)的内置拦截,拒绝那些客户端提供的文件名本会以可执行代码落盘的文件。

你可以使用 acceptedFileTypes() 方法并传入 MIME 类型数组,以限制可上传的文件类型。

php
use Filament\Forms\Components\FileUpload;

FileUpload::make('document')
    ->acceptedFileTypes(['application/pdf'])

TIP

除了允许静态值外,acceptedFileTypes() 方法也接受函数以动态计算。你可以将各种工具作为参数注入到该函数中。

你也可以使用 image() 方法作为允许所有图片 MIME 类型的简写。

php
use Filament\Forms\Components\FileUpload;

FileUpload::make('image')
    ->image()
带图片预览的文件上传带图片预览的文件上传

自定义 MIME 类型映射

某些文件格式在上传时可能无法被浏览器正确识别。Filament 允许你使用 mimeTypeMap() 方法为特定文件扩展名手动定义 MIME 类型:

php
use Filament\Forms\Components\FileUpload;

FileUpload::make('designs')
    ->acceptedFileTypes([
        'x-world/x-3dmf',
        'application/vnd.sketchup.skp',
    ])
    ->mimeTypeMap([
        '3dm' => 'x-world/x-3dmf',
        'skp' => 'application/vnd.sketchup.skp',
    ]);

TIP

除了允许静态值外,mimeTypeMap() 方法也接受函数以动态计算。你可以将各种工具作为参数注入到该函数中。

文件大小校验

你也可以以千字节为单位限制上传文件的大小:

php
use Filament\Forms\Components\FileUpload;

FileUpload::make('attachment')
    ->minSize(512)
    ->maxSize(1024)

TIP

除了允许静态值外,minSize()maxSize() 方法也接受函数以动态计算。你可以将各种工具作为参数注入到这些函数中。

上传大文件

若上传大文件时遇到问题,例如浏览器控制台中 HTTP 请求以 422 状态失败,可能需要调整配置。

在服务器的 php.ini 文件中增大最大文件大小可能解决问题:

ini
post_max_size = 120M
upload_max_filesize = 120M

Livewire 也会在上传前校验文件大小。要发布 Livewire 配置文件,请运行:

bash
php artisan livewire:publish --config

最大上传大小可在 temporary_file_uploadrules 键中调整。此处规则使用 KB,120MB 即 122880KB:

php
'temporary_file_upload' => [
    // ...
    'rules' => ['required', 'file', 'max:122880'],
    // ...
],

图片尺寸校验

你可以使用 rule() 方法配合 Laravel 的 Rule::dimensions() 限制上传图片的尺寸:

php
use Filament\Forms\Components\FileUpload;
use Illuminate\Validation\Rule;

FileUpload::make('photo')
    ->image()
    ->rule(Rule::dimensions()->minWidth(800)->minHeight(600))
php
use Filament\Forms\Components\FileUpload;
use Illuminate\Validation\Rule;

FileUpload::make('photo')
    ->image()
    ->rule(Rule::dimensions()->maxWidth(1920)->maxHeight(1080))

你可以组合最小与最大约束:

php
use Filament\Forms\Components\FileUpload;
use Illuminate\Validation\Rule;

FileUpload::make('photo')
    ->image()
    ->rule(
        Rule::dimensions()
            ->minWidth(800)
            ->minHeight(600)
            ->maxWidth(1920)
            ->maxHeight(1080)
    )

INFO

这些尺寸校验规则仅适用于新上传的文件。在添加校验规则之前已上传的现有文件不会被重新校验。

图片宽高比校验

你可以使用 imageAspectRatio() 方法限制上传图片的宽高比:

php
use Filament\Forms\Components\FileUpload;

FileUpload::make('banner')
    ->image()
    ->imageAspectRatio('16:9')

你可以通过传入数组允许多个宽高比:

php
use Filament\Forms\Components\FileUpload;

FileUpload::make('banner')
    ->image()
    ->imageAspectRatio(['16:9', '4:3', '1:1'])

TIP

除了允许静态值外,imageAspectRatio() 方法也接受函数以动态计算。你可以将各种工具作为参数注入到该函数中。

你也可以使用 Rule::dimensions() 指定可接受的宽高比范围:

php
use Filament\Forms\Components\FileUpload;
use Illuminate\Validation\Rule;

FileUpload::make('banner')
    ->image()
    ->rule(Rule::dimensions()->minRatio(4 / 3)->maxRatio(16 / 9))

INFO

这些宽高比校验规则仅适用于新上传的文件。在添加校验规则之前已上传的现有文件不会被重新校验。

TIP

若希望帮助用户满足宽高比要求,而不仅仅是拒绝无效上传,可考虑在 imageAspectRatio() 旁使用 automaticallyOpenImageEditorForAspectRatio()。当上传图片不符合所需比例时,会自动打开裁剪编辑器。或者,可使用 automaticallyCropImagesToAspectRatio() 在无用户交互的情况下自动将图片裁剪为所需比例。

文件数量校验

你可以使用 minFiles()maxFiles() 方法自定义可上传的文件数量:

php
use Filament\Forms\Components\FileUpload;

FileUpload::make('attachments')
    ->multiple()
    ->minFiles(2)
    ->maxFiles(5)

TIP

除了允许静态值外,minFiles()maxFiles() 方法也接受函数以动态计算。你可以将各种工具作为参数注入到这些函数中。