发新帖

[ThinkPHP] TP5上传文件中rule()函数的详细介绍

零下一度 4天前 52

TP5上传文件中rule()函数的详细介绍

在ThinkPHP 5中,rule()方法是think\File类的一个重要方法,用于设置上传文件的命名规则。下面是详细介绍:

一、rule()方法的基本语法

// 基本用法
$file->rule(规则)->move(路径);

二、参数类型

rule()方法接受多种类型的参数:

1. 字符串规则

// 使用内置规则名称
$file->rule('md5')->move('./uploads');
$file->rule('sha1')->move('./uploads');
$file->rule('uniqid')->move('./uploads');

2. 自定义字符串(固定文件名)

// 使用固定文件名
$file->rule('myfilename.jpg')->move('./uploads');
// 注意:如果文件已存在会被覆盖

3. 日期格式规则

// 使用日期时间作为文件名
$file->rule('date')->move('./uploads'); // 格式:Ymd/His_随机数

4. 闭包函数(最灵活)

$file->rule(function ($file) {
    // $file是当前文件对象
    // 可以自定义生成规则
    return 'custom_' . time() . '.' . $file->getExtension();
})->move('./uploads');

5. 空值(使用系统默认)

// 不设置rule()或设置为null,使用系统默认规则
$file->rule(null)->move('./uploads');
// 默认规则:date(日期+随机数)

三、系统内置规则详解

1. md5

$file->rule('md5')->move('./uploads');
// 生成规则:对文件内容进行md5加密
// 文件名示例:7d793037a0760186574b0282f2f435e7.jpg
// 优点:唯一性好,相同文件不会重复存储

2. sha1

$file->rule('sha1')->move('./uploads');
// 生成规则:对文件内容进行sha1加密
// 文件名示例:a94a8fe5ccb19ba61c4c0873d391e987982fbbd3.jpg
// 优点:安全性更高,唯一性好

3. uniqid

$file->rule('uniqid')->move('./uploads');
// 生成规则:基于微秒时间的唯一ID
// 文件名示例:6065b3c7a5f12.jpg
// 优点:生成速度快,适合高并发

4. date

$file->rule('date')->move('./uploads');
// 生成规则:日期+随机数
// 文件名格式:Ymd/His_随机数.扩展名
// 示例:20211231/235959_abc123.jpg
// 注意:这会生成日期子目录

四、实际应用示例

示例1:使用md5规则,避免重复上传相同文件

public function upload()
{
    $file = request()->file('image');
    
    $info = $file->validate([
            'size' => 1048576, // 1MB
            'ext'  => 'jpg,png,gif'
        ])
        ->rule('md5')  // 文件内容md5作为文件名
        ->move('./uploads');
    
    if ($info) {
        // 输出:7d793037a0760186574b0282f2f435e7.jpg
        echo $info->getSaveName();
    }
}

示例2:自定义前缀+时间戳

public function upload()
{
    $file = request()->file('avatar');
    
    $info = $file->rule(function () use ($file) {
        // 自定义规则:用户ID_时间戳.扩展名
        $userId = session('user_id');
        return 'avatar_' . $userId . '_' . time() . '.' . $file->getExtension();
    })->move('./uploads');
    
    if ($info) {
        // 输出:avatar_1001_1640995200.jpg
        echo $info->getSaveName();
    }
}

示例3:保持原始文件名,但防止覆盖

public function upload()
{
    $file = request()->file('document');
    
    $info = $file->rule(function ($file) {
        // 原始文件名+时间戳,防止覆盖
        $originalName = $file->getInfo('name');
        $name = pathinfo($originalName, PATHINFO_FILENAME);
        $ext = $file->getExtension();
        return $name . '_' . time() . '.' . $ext;
    })->move('./uploads/documents');
    
    if ($info) {
        // 输出:report_1640995200.pdf
        echo $info->getSaveName();
    }
}

示例4:多规则组合

public function upload()
{
    $file = request()->file('file');
    
    $info = $file
        ->validate(['size' => 5242880, 'ext' => 'pdf,doc,docx'])
        ->rule('uniqid')  // 使用uniqid生成唯一ID
        ->move('./uploads/files', true, false); // 不生成子目录
    
    if ($info) {
        echo $info->getSaveName();
    }
}

五、rule()方法与其他方法的配合

与validate()配合使用

$file->validate([
    'size' => 1048576,
    'ext'  => 'jpg,png,gif,jpeg'
])->rule('md5')->move('./uploads');

与move()方法的优先级

// 如果同时设置rule()和move()的第二个参数,以move()的第二个参数为准
$file->rule('md5')->move('./uploads', 'custom_name.jpg');
// 结果文件名:custom_name.jpg(rule()被覆盖)


最新回复 (0)
返回
零下一度
主题数
957
帖子数
0
注册排名
1