解決GoogleDrive文件路徑混亂問題:使用flysystem-google-drive-ext實現無縫路徑轉換

可以通過一下地址學習composer學習地址

在使用 google drive 作為應用程序的存儲后端時,我們很快會遇到一個問題:google drive 使用唯一的 id 來標識每個文件和文件夾,而不是像傳統文件系統那樣使用直觀的路徑。這給集成帶來了很大的麻煩,因為我們需要在應用程序中維護這些 id,并且手動進行路徑轉換。

例如,我們可能需要在應用程序中顯示一個易于理解的路徑 /My Nice Dir/myFile.ext,但在 Google Drive 中,實際的“虛擬路徑”卻是 /Xa3X9GlR6EmbnY1RLVTk5VUtOVkk/0B3X9GlR6EmbnY1RLVTk5VUtOVkk。手動處理這些轉換不僅繁瑣,而且容易出錯。

masbug/flysystem-google-drive-ext 擴展包正是為了解決這個問題而生的。它是一個 Flysystem 適配器,能夠無縫地在“顯示路徑”和“虛擬路徑”之間進行轉換,隱藏了 Google Drive 的內部 ID 管理,讓我們可以像使用傳統文件系統一樣操作 Google Drive。

安裝

使用 composer 安裝非常簡單:

composer require masbug/flysystem-google-drive-ext

配置

首先,你需要從 Google 獲取 client ID、client secret 和 refresh Token。這些憑據用于授權你的應用程序訪問 Google Drive。具體步驟可以參考 Google 官方文檔。

獲取到憑據后,就可以使用 MasbugFlysystemGoogleDriveAdapter 創建適配器實例了:

use MasbugFlysystemGoogleDriveAdapter; use GoogleClient; use GoogleServiceDrive; use LeagueFlysystemFilesystem; use LeagueFlysystemConfig; use LeagueFlysystemVisibility;  $client = new Client(); $client->setClientId('[client_id]'); $client->setClientSecret('[client_secret]'); $client->refreshToken('[refresh_token]'); $client->setApplicationName('My Google Drive App');  $service = new Drive($client);  // 創建適配器 $adapter = new GoogleDriveAdapter($service, 'My_App_Root');  // 創建 Flysystem 實例 $fs = new Filesystem($adapter, new Config([Config::OPTION_VISIBILITY => Visibility::PRIVATE]));

在上面的代碼中,My_App_Root 指定了應用程序在 Google Drive 中使用的根目錄。

使用

現在,你可以像使用任何其他 Flysystem 適配器一樣使用 Google Drive 了。例如,列出根目錄下的所有文件和文件夾:

$contents = $fs->listContents('', true /* is_recursive */);

上傳文件:

use LeagueFlysystemLocalLocalFilesystemAdapter; use CarbonCarbon; use LeagueFlysystemUnableToWriteFile;  $local_filepath = '/home/user/downloads/file_to_upload.ext'; $remote_filepath = 'MyFolder/file.ext';  $localAdapter = new LocalFilesystemAdapter('/'); $localfs = new Filesystem($localAdapter, [Config::OPTION_VISIBILITY => Visibility::PRIVATE]);  try {     $time = Carbon::now();     $fs->writeStream($remote_filepath, $localfs->readStream($local_filepath), new Config());      $speed = !(float)$time->diffInSeconds() ? 0 :filesize($local_filepath) / (float)$time->diffInSeconds();     echo 'Elapsed time: '.$time->diffForHumans(null, true).php_EOL;     echo 'Speed: '. number_format($speed/1024,2) . ' KB/s'.PHP_EOL; } catch(UnableToWriteFile $e) {     echo 'UnableToWriteFile!'.PHP_EOL.$e->getMessage(); }

下載文件:

use LeagueFlysystemLocalLocalFilesystemAdapter; use CarbonCarbon; use LeagueFlysystemUnableToWriteFile;  $remote_filepath = 'MyFolder/file.ext'; $local_filepath = '/home/user/downloads/file.ext';  $localAdapter = new LocalFilesystemAdapter('/'); $localfs = new Filesystem($localAdapter, [Config::OPTION_VISIBILITY => Visibility::PRIVATE]);  try {     $time = Carbon::now();     $localfs->writeStream($local_filepath, $fs->readStream($remote_filepath), new Config());      $speed = !(float)$time->diffInSeconds() ? 0 :filesize($local_filepath) / (float)$time->diffInSeconds();     echo 'Elapsed time: '.$time->diffForHumans(null, true).PHP_EOL;     echo 'Speed: '. number_format($speed/1024,2) . ' KB/s'.PHP_EOL; } catch(UnableToWriteFile $e) {     echo 'UnableToWriteFile!'.PHP_EOL.$e->getMessage(); }

laravel 中使用

masbug/flysystem-google-drive-ext 也可以很方便地集成到 Laravel 框架中。

  1. 配置 .env 文件:

    在 .env 文件中添加 Google Drive 的憑據:

    FILESYSTEM_CLOUD=google GOOGLE_DRIVE_CLIENT_ID=xxx.apps.googleusercontent.com GOOGLE_DRIVE_CLIENT_SECRET=xxx GOOGLE_DRIVE_REFRESH_TOKEN=xxx GOOGLE_DRIVE_FOLDER=
  2. 配置 config/filesystems.php 文件:

    在 config/filesystems.php 文件中添加一個名為 google 的 disk:

    'disks' => [     // ...     'google' => [         'driver' => 'google',         'clientId' => env('GOOGLE_DRIVE_CLIENT_ID'),         'clientSecret' => env('GOOGLE_DRIVE_CLIENT_SECRET'),         'refreshToken' => env('GOOGLE_DRIVE_REFRESH_TOKEN'),         'folder' => env('GOOGLE_DRIVE_FOLDER'), // without folder is root of drive or team drive     ],     // ... ],
  3. 注冊 Service Provider:

    在 app/Providers/AppServiceProvider.php 文件中,添加以下代碼:

    namespace AppProviders;  use IlluminateSupportFacadesStorage; use IlluminateSupportServiceProvider; use LeagueFlysystemFilesystem; use MasbugFlysystemGoogleDriveAdapter; use GoogleClient; use GoogleServiceDrive; use IlluminateFilesystemFilesystemAdapter;  class AppServiceProvider extends ServiceProvider {     public function boot()     {         Storage::extend('google', function ($app, $config) {             $client = new Client();             $client->setClientId($config['clientId']);             $client->setClientSecret($config['clientSecret']);             $client->refreshToken($config['refreshToken']);             $service = new Drive($client);             $adapter = new GoogleDriveAdapter($service, $config['folder'] ?? '/');             $driver = new Filesystem($adapter);              return new FilesystemAdapter($driver, $adapter);         });     } }

現在,你可以像這樣訪問 Google Drive:

use IlluminateSupportFacadesStorage;  $googleDisk = Storage::disk('google');  // 上傳文件 $googleDisk->put('MyFolder/file.ext', file_get_contents('/path/to/local/file.ext'));  // 下載文件 $contents = $googleDisk->get('MyFolder/file.ext');

優勢

  • 無縫路徑轉換: 自動處理 Google Drive 的虛擬路徑和顯示路徑之間的轉換,簡化了開發過程。
  • 易于集成: 可以輕松地集成到現有的 Flysystem 代碼中。
  • 支持 Team Drive: 支持連接到 Team Drive,方便團隊協作。
  • 支持共享文件夾: 支持連接到與您共享的文件夾。
  • 流式上傳/下載: 支持直接從流中上傳和下載文件,避免將數據復制到內存中,提高了性能。

局限性

  • 重復文件名: Google Drive 允許用戶創建具有相同顯示名稱的文件和文件夾。在這種情況下,適配器會選擇最舊的實例。
  • 并發使用: 并發使用同一個 Google Drive 可能會導致意外問題,因為文件/文件夾標識符和文件對象會被大量緩存。

總結

masbug/flysystem-google-drive-ext 擴展包是一個強大的工具,可以幫助我們更輕松地將應用程序與 Google Drive 集成。它通過無縫的路徑轉換,簡化了文件管理,提高了開發效率。如果你正在使用 Google Drive 作為應用程序的存儲后端,那么這個擴展包絕對值得一試。

? 版權聲明
THE END
喜歡就支持一下吧
點贊15 分享