模型可以使用多态关联的一个子集来支持文件附件。$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');您还可以使用 URL 通过 fromUrl 方法添加文件。要使用此方法,您需要安装 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 参数.
width 和 height 参数应指定为一个数字或 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.* 语法的更多信息,请参阅有关验证数组的验证文章。