文件系统 / 云存储
介绍
Laravel 提供了一个强大的文件系统抽象层,这要归功于 Frank de Jonge 的出色 Flysystem PHP 包。Laravel 的 Flysystem 集成为本地文件系统、Amazon S3 和 Rackspace 云存储提供了简单易用的驱动程序。更好的是,切换这些存储选项非常简单,因为每个系统的 API 都保持不变。
配置
文件系统配置文件位于 config/filesystems.php
。在此文件中,您可以配置所有的“磁盘”。每个磁盘代表一个特定的存储驱动程序和存储位置。配置文件中包含了每个支持的驱动程序的示例配置。因此,只需修改配置以反映您的存储偏好和凭据。
当然,您可以配置任意数量的磁盘,甚至可以有多个使用相同驱动程序的磁盘。
本地驱动程序
使用 local
驱动程序时,请注意所有文件操作都是相对于配置文件中定义的 root
目录的。默认情况下,此值设置为 storage/app
目录。因此,以下方法将文件存储在 storage/app/file.txt
中:
Storage::disk('local')->put('file.txt', 'Contents');
其他驱动程序的先决条件
在使用 S3 或 Rackspace 驱动程序之前,您需要通过 Composer 安装相应的软件包:
- Amazon S3:
league/flysystem-aws-s3-v3 ~1.0
- Rackspace:
league/flysystem-rackspace ~1.0
基本用法
获取磁盘实例
Storage
facade 可用于与任何已配置的磁盘交互。例如,您可以在 facade 上使用 put
方法将头像存储在默认磁盘上。如果在未先调用 disk
方法的情况下调用 Storage
facade 上的方法,则方法调用将自动传递给默认磁盘:
<?php
namespace App\Http\Controllers;
use Storage;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
class UserController extends Controller
{
/**
* 更新给定用户的头像。
*
* @param Request $request
* @param int $id
* @return Response
*/
public function updateAvatar(Request $request, $id)
{
$user = User::findOrFail($id);
Storage::put(
'avatars/'.$user->id,
file_get_contents($request->file('avatar')->getRealPath())
);
}
}
使用多个磁盘时,可以使用 Storage
facade 上的 disk
方法访问特定磁盘。当然,您可以继续链式调用方法以在磁盘上执行方法:
$disk = Storage::disk('s3');
$contents = Storage::disk('local')->get('file.jpg');
检索文件
get
方法可用于检索给定文件的内容。该方法将返回文件的原始字符串内容:
$contents = Storage::get('file.jpg');
has
方法可用于确定磁盘上是否存在给定文件:
$exists = Storage::disk('s3')->has('file.jpg');
文件元信息
size
方法可用于获取文件的大小(以字节为单位):
$size = Storage::size('file1.jpg');
lastModified
方法返回文件最后一次修改的 UNIX 时间戳:
$time = Storage::lastModified('file1.jpg');
存储文件
put
方法可用于将文件存储在磁盘上。您还可以将 PHP resource
传递给 put
方法,这将使用 Flysystem 的底层流支持。处理大文件时,强烈推荐使用流:
Storage::put('file.jpg', $contents);
Storage::put('file.jpg', $resource);
copy
方法可用于将现有文件复制到磁盘上的新位置:
Storage::copy('old/file1.jpg', 'new/file1.jpg');
move
方法可用于重命名或移动现有文件到新位置:
Storage::move('old/file1.jpg', 'new/file1.jpg');
在文件开头/结尾插入内容
prepend
和 append
方法允许您轻松地在文件的开头或结尾插入内容:
Storage::prepend('file.log', 'Prepended Text');
Storage::append('file.log', 'Appended Text');
删除文件
delete
方法接受单个文件名或要从磁盘中删除的文件数组:
Storage::delete('file.jpg');
Storage::delete(['file1.jpg', 'file2.jpg']);
目录
获取目录中的所有文件
files
方法返回给定目录中所有文件的数组。如果您希望检索给定目录中所有文件的列表,包括所有子目录,可以使用 allFiles
方法:
$files = Storage::files($directory);
$files = Storage::allFiles($directory);
获取目录中的所有目录
directories
方法返回给定目录中所有目录的数组。此外,您可以使用 allDirectories
方法获取给定目录及其所有子目录中的所有目录的列表:
$directories = Storage::directories($directory);
// 递归...
$directories = Storage::allDirectories($directory);
创建目录
makeDirectory
方法将创建给定目录,包括任何需要的子目录:
Storage::makeDirectory($directory);
删除目录
最后,deleteDirectory
方法可用于从磁盘中删除目录及其所有文件:
Storage::deleteDirectory($directory);
自定义文件系统
Laravel 的 Flysystem 集成为多个“驱动程序”提供了开箱即用的驱动程序;然而,Flysystem 并不限于这些,并且有许多其他存储系统的适配器。如果您想在 Laravel 应用程序中使用这些额外的适配器之一,可以创建自定义驱动程序。
为了设置自定义文件系统,您需要创建一个 服务提供者,例如 DropboxServiceProvider
。在提供者的 boot
方法中,您可以使用 Storage
facade 的 extend
方法定义自定义驱动程序:
<?php
namespace App\Providers;
use Storage;
use League\Flysystem\Filesystem;
use Dropbox\Client as DropboxClient;
use Illuminate\Support\ServiceProvider;
use League\Flysystem\Dropbox\DropboxAdapter;
class DropboxServiceProvider extends ServiceProvider
{
/**
* 执行服务的注册后引导。
*
* @return void
*/
public function boot()
{
Storage::extend('dropbox', function($app, $config) {
$client = new DropboxClient(
$config['accessToken'], $config['clientIdentifier']
);
return new Filesystem(new DropboxAdapter($client));
});
}
/**
* 在容器中注册绑定。
*
* @return void
*/
public function register()
{
//
}
}
extend
方法的第一个参数是驱动程序的名称,第二个是接收 $app
和 $config
变量的闭包。解析器闭包必须返回 League\Flysystem\Filesystem
的实例。$config
变量包含在 config/filesystems.php
中为指定磁盘定义的值。
一旦创建了注册扩展的服务提供者,您就可以在 config/filesystem.php
配置文件中使用 dropbox
驱动程序。