模型可以使用 多态关系 的一个子集来支持文件附件。$attachOne 或 $attachMany 关系旨在将文件链接到称为“附件”的数据库记录。在几乎所有情况下,System\Models\File 模型都用于维护此关系,其中文件的引用作为记录存储在 system_files 表中,并与父模型具有多态关系。
在以下示例中,模型具有单个 Avatar 附件模型和多个 Photo 附件模型。
单个文件附件:
public $attachOne = [
'avatar' => \System\Models\File::class
];多个文件附件:
public $attachMany = [
'photos' => \System\Models\File::class
];为避免命名冲突,请确保您的模型数据库表没有一个与您的附件关系同名的属性。
受保护的附件会上传到应用程序的 uploads/protected 目录,该目录无法从 Web 端直接访问。通过将 public 属性设置为 false 来定义受保护的文件附件。
public $attachOne = [
'avatar' => [\System\Models\File::class, 'public' => false]
];对于单一附件关系 ($attachOne), 你可以直接通过模型关系创建附件, 通过使用 files 函数设置其值, 该函数从输入上传中读取文件数据。
$model->avatar = files('file_input');要从本地路径关联新文件,请使用 System\Models\File 模型和 fromFile 方法。
$model->avatar = (new File)->fromFile('/path/to/somefile.jpg');要直接从(原始)数据创建文件,请使用 fromData 方法来传递内容(第一个参数)和一个文件名(第二个参数)。
$model->avatar = (new File)->fromData('Some content', 'sometext.txt');你也可以使用 fromUrl 方法从 URL 添加文件。要使用此方法,你需要安装 cURL PHP 扩展。
$model->avatar = (new File)->fromUrl('https://example.tld/path/to/avatar.jpg');可选地,您可以指定一个自定义的文件名(第二个参数)。
$model->avatar = (new File)->fromUrl('https://example.tld/avatar.jpg', 'customname.jpg');对于多个附加关系 ($attachMany),您可以从 files() 函数传递一个值数组。
$model->photos = (array) files('multi_file');您可以使用 create 方法来代替将文件附加到现有关系上,请注意文件对象与 data 属性关联。如果您愿意,此方法也可用于单一关系。
$model->photos()->create(['data' => files('file_input')]);你可以使用关系上的 add 方法直接操作一个 System\Models\File 模型。
$model->photos()->add(
$model->photos()->make()->fromFile('/path/to/somefile.jpg')
);或者,你可以事先准备一个 File 模型,然后手动关联该关系。请注意,使用此方法时必须显式设置 is_public 属性。
$file = new \System\Models\File;
$file->data = files('file_input');
$file->is_public = true;
$file->save();
$model->photos()->add($file);getUrl 方法返回已上传的公共文件的完整 URL。以下代码将打印类似 example.tld/uploads/public/path/to/avatar.jpg。
echo $model->avatar->getUrl();返回多个附件文件路径。
foreach ($model->photos as $photo) {
echo $photo->getUrl();
}使用 Twig 在页面上显示文件。
<img src="{{ model.avatar.url }}" alt="Description Image" />getLocalPath 方法将返回本地文件系统中一个上传文件的绝对路径。如果使用 S3 等外部驱动程序,此方法会将内容下载到本地文件系统中的临时位置。
echo $model->avatar->getLocalPath();您可以使用 getThumbUrl 方法调整图片大小. 该方法接受 3 个参数 - 图片宽度, 图片高度 和 options 参数.
宽度和高度参数应指定为一个数字或auto字样,用于自动按比例缩放。
echo $model->avatar->getThumbUrl(100, 100, ['mode' => 'crop']);使用 Twig 在页面上显示图片。
<img src="{{ model.avatar.thumbUrl(100, 100, { mode: 'exact', quality: 80, extension: 'webp' }) }}" alt="Description Image" />在图片尺寸调整器文章中阅读更多关于 getThumbUrl 的可用选项。
要直接输出文件内容,使用 output 方法,这会返回一个 响应对象 该对象将包含在浏览器中显示文件所需的头信息
return $model->avatar->output();你可以通过链式调用 send 方法将内容输出到浏览器。
$model->avatar->output()->send();返回 download 方法以将文件作为响应下载。
return $model->avatar->download();本节展示了模型附件功能的一个完整使用示例 - 从在模型中定义关系到在页面上显示上传的图片。
在 您 的模型中 定义 一 个关系 到 该 System\Models\File 类, 例如 :
class Post extends Model
{
public $attachOne = [
'featured_image' => \System\Models\File::class
];
}构建一个用于上传文件的表单:
<?= Form::open(['files' => true]) ?>
<input name="example_file" type="file">
<button type="submit">Upload File</button>
<?= Form::close() ?>在服务器上处理上传的文件并将其附加到一个模型:
// Find the Blog Post model
$post = Post::find(1);
// Save the featured image of the Blog Post model
if (Input::hasFile('example_file')) {
$post->featured_image = Input::file('example_file');
}或者,您可以使用 延迟绑定 来延迟关系。
// Find the Blog Post model
$post = Post::find(1);
// Look for the postback data 'example_file' in the HTML form above
$fileFromPost = Input::file('example_file');
// If it exists, save it as the featured image with a deferred session key
if ($fileFromPost) {
$post->featured_image()->create(['data' => $fileFromPost], $sessionKey);
}在页面上显示上传的文件:
<?php
// Find the Blog Post model again
$post = Post::find(1);
// Look for the featured image address, otherwise use a default one
if ($post->featured_image) {
$featuredImage = $post->featured_image->getUrl();
}
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.* 语法的更多信息,请参阅验证文章中关于验证数组的内容。