文件附件

October CMS Documentation Docs

文件附件

模型可以使用 多态关联 的子集来支持文件附件。 $attachOne$attachMany 关联设计用于将文件链接到称为"附件"的数据库记录。 几乎所有情况下,System\Models\File 模型都用于维护这种关系,其中对文件的引用作为记录存储在 system_files 表中,并且与父模型具有多态关联。

在下面的示例中,模型有一个 Avatar 附件模型和许多照片附件模型。

单个文件附件:

public $attachOne = [
    'avatar' => 'System\Models\File'
];

多个文件附件:

public $attachMany = [
    'photos' => 'System\Models\File'
];

注意:确保模型的数据库表中没有与附件关联使用相同名称的属性。 如果是这样,则会导致命名冲突并产生问题。

受保护的附件被上传到应用程序的 uploads/protected 目录,从 Web 直接访问无法访问该目录。 通过将 public 参数设置为 false 来定义受保护的文件附件:

public $attachOne = [
    'avatar' => ['System\Models\File', 'public' => false]
];

# 创建新附件

对于单一的附加关联($attachOne),您可以通过模型关联直接创建一个附件,方法是使用 Input::file 方法设置其值,该方法从上传输入中读取文件数据。

$model->avatar = Input::file('file_input');

您还可以将字符串传递给 data 属性,其中包含本地文件的绝对路径。

$model->avatar = '/path/to/somefile.jpg';

有时,直接从(原始)数据创建文件实例也可能很有用:

$file = (new System\Models\File)->fromData('Some content', 'sometext.txt');

对于多个附加关联($attachMany),您可以在关联上使用create方法,注意文件对象与data属性相关联。 如果您愿意,这种方法也可以用于单数关系。

$model->avatar()->create(['data' => Input::file('file_input')]);

或者,您可以事先准备一个文件模型,然后手动关联关系。 请注意,必须使用is_public这种方法设置显式属性。

$file = new System\Models\File;
$file->data = Input::file('file_input');
$file->is_public = true;
$file->save();

$model->avatar()->add($file);

您还可以从 URL 添加文件。 要使用此方法,您需要安装 cURL PHP 扩展。

$file = new System\Models\File;
$file->fromUrl('https://example.com/uploads/public/path/to/avatar.jpg');

$user->avatar()->add($file);

有时您可能需要更改文件名。 您可以通过使用第二个方法参数来做到这一点。

$file->fromUrl('https://example.com/uploads/public/path/to/avatar.jpg', 'somefilename.jpg');

# 查看附件

getPath 方法返回上传的公共文件的完整 URL。 以下代码将打印类似 example.com/uploads/public/path/to/avatar.jpg

echo $model->avatar->getPath();

返回多个附件文件路径:

foreach ($model->photos as $photo) {
    echo $photo->getPath();
}

getLocalPath 方法将返回本地文件系统中上传文件的绝对路径。

echo $model->avatar->getLocalPath();

要直接输出文件内容,请使用 output 方法,这将包括下载文件所需的头文件:

echo $model->avatar->output();

您可以使用 getThumb 方法调整图像大小。 该方法采用 3 个参数 - 图像宽度、图像高度和选项参数。

widthheight 参数应指定为数字或 auto 字词,以实现自动比例缩放。

echo $model->avatar->getThumb(100, 100, ['mode' => 'crop']);

在页面上显示图像。

<img src="{{ model.avatar.getThumb(100, 100, {'mode':'exact', 'quality': 80, 'extension': 'webp'}) }}" alt="Description Image" />

图像调整器文章 上阅读有关 getThumb 可用选项的更多信息。

# 用法示例

本节展示了模型附件功能的完整使用示例——从定义模型中的关联到在页面上显示上传的图像。

在您的模型中定义与 System\Models\File 类的关系,例如:

class Post extends Model
{
    public $attachOne = [
        'featured_image' => 'System\Models\File'
    ];
}

构建一个用于上传文件的表单:

<?= Form::open(['files' => true]) ?>

    <input name="example_file" type="file">

    <button type="submit">上传文件</button>

<?= Form::close() ?>

在服务器上处理上传的文件并将其附加到模型:

// 查找博客文章模型
$post = Post::find(1);

// 保存博客文章模型的特色图片
if (Input::hasFile('example_file')) {
    $post->featured_image = Input::file('example_file');
}

或者,您可以使用 延迟绑定 来延迟关联:

// 查找博客文章模型
$post = Post::find(1);

// 在上面的 HTML 表单中查找回发数据"example_file"
$fileFromPost = Input::file('example_file');

// 如果存在,将其保存为带有延迟会话密钥的特色图像
if ($fileFromPost) {
    $post->featured_image()->create(['data' => $fileFromPost], $sessionKey);
}

在页面上显示上传的文件:

// 再次找到博客帖子模型
$post = Post::find(1);

// 寻找特色图片地址,否则使用默认的
if ($post->featured_image) {
    $featuredImage = $post->featured_image->getPath();
}
else {
    $featuredImage = 'http://placehold.it/220x300';
}

<img src="<?= $featuredImage ?>" alt="Featured Image" />

如果需要访问文件的所有者,可以使用 File 模型的 attachment 属性:

public $morphTo = [
    'attachment' => []
];

例子:

$user = $file->attachment;

有关更多信息,请阅读 多态关联

# 验证示例

下面的示例使用 数组验证 来验证 $attachMany 关联。

use System\Models\File;
use Model;

class Gallery extends Model
{
    use \October\Rain\Database\Traits\Validation;

    public $attachMany = [
        'photos' => File::class
    ];

    public $rules = [
        'photos'   => 'required',
        'photos.*' => 'image|max:1000|dimensions:min_width=100,min_height=100'
    ];

    /* 其他一些代码 */
}

有关上面使用的 attribute.* 语法的更多信息,请参阅 验证数组