[Laravel 扩展包]在 Laravel 中快速管理临时文件
我最近有一个队列作业,需要将文件临时下载到服务器,进行处理,最后清理临时文件。这在 PHP 中并不困难,你可能已经使用以下方式开始:
file_put_contents('/tmp/' . $tmpFile, file_get_contents($video));
要使之更能跨平台兼容,获取你可用使用 PHP 内置的 sys_get_temp_dir()
函数获取临时文件使用的目录路径:
$basePath = rtrim(sys_get_temp_dir(), DIRECTORY_SEPARATOR);
$tmpPath = $basePath.$tmpFile;
// Download the file
// Process it
// Clean up
这很好,不过, Spatie 有一个简单且高效的包,它用一个名为 spatie/temporary-directory 小包很好地清洁了这个样板代码。
该包有一个类(以及两个异常类)并为创建和管理临时文件提供了很好的面向对象接口:
use Spatie\TemporaryDirectory\TemporaryDirectory;
$tmpDir = (new TemporaryDirectory())->create();
// Or using the make() static constructor
$tmpDir = TemporaryDirectory::make();
// Return a path inside the temporary directory
$tmpDir->path('659c896e52a29.mov');
// return /tmp/490784976-0213323001704757672/659c896e52a29.mov
通过处理视频文件的如下示例,可以使用 Laravel 的 HTTP 客户端的 sink()
方法将文件下载到临时目录:
use Illuminate\Support\Facades\Http;
use Spatie\TemporaryDirectory\TemporaryDirectory;
// Normalize the video and get the filename
$videoUrl = str($videoUrl)->replace(' ', '%20');
$tmpFile = $videoUrl->afterLast('/');
// Create a temporary directory and download a file to that path
$tmpDir = TemporaryDirectory::make();
$tmpPath = $tmpDir->path($tmpFile);
Http::sink($tmpPath)->throw()->get($videoUrl->toString());
// Process the file
// Cleanup the temporary file
$tmpFile->delete();
我们有一个封装过的、一致的方法来创建临时目录和其中的文件,并能够在之后进行清理。Spatie 还通过在创建对象时使用以下方法使清理更加方便:
$tmpDir = (new TemporaryDirectory())
->deleteWhenDestroyed()
->create();
// Or via `make()`
deleteWhenDestroyed()
会使用对象的 destruct()
方法删除目录,因此你不用担心之后的清理工作。
该包还有其他的便利,比如自定义目录名和位置,以及一个清空临时目录所有文件的方法。你可以在项目的 Readme 中查看该文档,请查看 Github 上的 spatie/temporary-directory 仓库。