编程

[Laravel 扩展包]在 Laravel 中快速管理临时文件

833 2024-03-18 20:38:00

我最近有一个队列作业,需要将文件临时下载到服务器,进行处理,最后清理临时文件。这在 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 仓库。