laravel 基礎教程 —— 文件系統

文件系統/云存儲

簡介

laravel 提供了一個強大的文件系統的抽象,這得益于 Frank de Jonge 所開發的 Flyststem PHP 包。laravel 的文件系統提供了對一些存儲驅動的支持,它們包括本地文件系統,Amazon S3,Rackspace 云存儲。更為奇妙的是,它可以通過存儲配置選項來切換這些存儲系統,因為 laravel 對它們提供了統一的 API 接口。

配置

文件系統的配置選項存儲在 config/filesystems.php 文件中。在這個文件中你可以對所有的磁盤進行配置。每個磁盤選項包含著其所使用的存儲驅動及其存儲位置。對于 laravel 默認支持的存儲驅動,在這個文件中都有相應的配置示例。所以,你可以簡單的在這個文件中修改配置選項就可以使用其強大的功能。

當然,你可以配置多個磁盤,甚至可以使多個磁盤使用相同的驅動。

公共磁盤

public 磁盤意味著其可以被公開的訪問。默認的 public 磁盤使用的是 local 驅動并且其存儲的文件位置是在 storage/app/public 目錄。如果你想要這個目錄下的文件可以在 web 中進行訪問,你需要創建一個 public/storagestorage/app/public 的符號鏈接。這個約定可以使公開訪問的文件保持存放在同一個目錄中并且可以在使用像 Envoyer 這種無痛持續部署系統時可以方便的共享整個部署過程。

當然,一旦文件被存儲并且建立了符號鏈接。你就可以通過 asset 幫助方法來生成文件的 URL:

echo asset('storage/file.txt')

本地驅動

當使用 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

FTP 驅動配置

laravel 的文件系統可以很好的支持 FTP 的集成,但是在默認的配置文件中并沒有給出示例。如果你需要配置 FTP 的文件系統,你可以使用下面的配置示例:

'ftp' => [
  'dirver' => 'ftp',
  'host' => 'ftp.example.com',
  'username' => 'your-username',
  'password' => 'your-password',

  // Optional FTP Settings...
  // 'port' => 21,
  // 'root' => '',
  // 'passive' => true,
  // 'ssl' => true,
  // 'timeout' => 30,
],

Rackspace 驅動配置

laravel 的文件系統可以很好的支持 Rackspace 的集成,但是在默認的配置文件中并沒有給出示例。如果你需要配置 Rackspace 文件系統,你可以使用下面的示例:

'rackspace' => [
  'driver' => 'rackspace',
  'username' => 'your-username',
  'key' => 'your-key',
  'container' => 'your-container',
  'endpoint' => 'https://identity.api.rackspacecloud.com/v2.0/',
  'region' => 'IAD',
  'url_type' => 'publicURL',
],

基礎用法

獲取磁盤實例

Storage 假面可以用來和你所配置的磁盤進行交互。比如,你可以使用它的 put 方法來將用戶的頭像圖片存儲到默認的磁盤。如果你在調用該方法的時候沒有在其之前使用 disk 方法的話,那么該方法會自動的將頭像傳遞到默認的磁盤:

<?php

namespace App\Http\Controllers;

use Storage;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;

class UserController extends Controller
{
  /**
   * Update teh avatar for the given user.
   *
   * @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 假面的 disk 方法來指定訪問的磁盤。當然,你可以使用鏈式的方法來進行持續的操作:

$disk = Storage::disk('s3');

$contents = Storage::disk('local')->get('file.jpg');

檢索文件

get 方法可以用來從所給定的文件中檢索出其內容。該方法會返回文件的原始字符串內容:

$contents = Storage::get('file.jpg');

exists 方法可以用來判斷所給定的文件是否存在于磁盤中:

$exists = Storage::disk('s3')->exists('file.jpg');

文件 URLs

當使用 local 或者 s3 驅動時,你可以使用 url 方法來獲得給定文件的 URL。如果你使用的是 local 驅動,那它只會簡單的在給定的路徑前增加 /storage 前綴以返回相對的文件路徑。如果你使用的是 s3 驅動,將會返回完整的遠端 RUL:

$url = Storage::url('file1.jpg');

注意:當使用的是 local 驅動時,一定要確保創建了 public/storagestorage/app/public 的符號鏈接。

文件元信息

size 方法可以用來獲取給定文件的字節大小:

$size = Storage::size('file1.jpg');

lastModified 方法會返回給定文件的最后修改時間,它使用的 是 UNIX 時間戳:

$time = Storage::lastModified('file1.jpg');

存儲文件

put 方法可以用來將文件存儲到磁盤。你可以傳遞一個 PHP 的 resourceput 方法,那么它會使用文件系統的底層流支持。在與大型文件交互時,推薦使用文件流:

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');

前置或追加內容到文件

prependappend 方法允許你輕松的往文件的起始或結束位置加入內容:

Storage::prepend('file.log', 'Prepended Text');

Storage::append('file.log', 'Appended Text');

文件可見性

你可以通過使用 getVisibilitysetVisibility 方法來進行文件可見性的檢索和設置。可見性是跨平臺的文件權限的抽象:

Storage::getVisibility('file.jpg');

Storage::setVisibility('file.jpg', 'public');

另外,你可以在使用 put 方法的同時設置文件的可見性。有效的可見性值是 publicprivate:

Storage::put('file.jpg', $contents, 'public');

刪除文件

delete 方法可以接受一個文件名或者文件名所組成的數組,它將從磁盤中刪除相應的文件:

Storage::delete('file.jpg');

Storage::delete(['file1.jpg', 'file2.jpg']);

目錄

從目錄中獲取所有文件

files 方法會返回所給定目錄中所有的文件所組成的數組。如果你想要在檢索到的文件中包含所給定目錄的子目錄。那么你需要使用 allFiles 方法:

$file = Storage::files($directory);

$files = Storage::allFiles($directory);

從給定的目錄中獲取所有的目錄

directories 方法可以返回所給定目錄下的所有子目錄所組成的數組。另外你可以使用 allDirectories 方法遞歸檢索子目錄:

$directories = Storage::directories($directory);

// Recursive...

$directories = Storage::allDirectories($directory);

創建目錄

makeDirectory 方法將創建給定的目錄,包括其所需要的子目錄:

Storage::makeDirectory($directory);

刪除一個目錄

最后,deleteDirectory 方法可以用來刪除一個目錄,并且其刪除磁盤中該目錄下所有的文件:

Storage::deleteDirectory($directory);

自定義文件系統

laravel 的文件系統對幾種常見的存儲系統提供了開箱即用的支持。事實上,文件系統并沒有限制你只使用所提供的這些。你可以自己創建一個適配器來構建一個自定義的驅動去支持你所期望使用的文件存儲系統。

你需要創建一個服務提供者來進行自定義文件存儲系統的構建。比如 DropboxServiceProvider。在提供者的 boot 方法中,你需要使用 Storage 假面的 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
{
  /**
   * Perform post-registration booting of services.
   *
   * @return void
   */
   public function boot()
   {
     Storage::extend('dropbox', function ($app, $config) {
       $client = new DropboxClient(
        $config['accessToken'], $config['clientIdentifier']
       );      

       return new Filesystem(new DropboxAdapter($client));
     });
   }

   /**
    * Register bindings in the container.
    *
    * @return void
    */
    public function register()
    {
      //
    }
}

extend 方法中的第一個參數應該是驅動的名稱,第二個參數是一個閉包,閉包接受 $app$config 變量。被解析的閉包必須返回一個 League\Flysystem\Filesystem 的實例。$config 變量包含了 config/filesystems.php 文件中指定磁盤的值。

一旦你創建了服務提供者并且注冊了這個擴展,你就可以在 config/filesystem.php 配置文件中使用 dropbox 驅動了。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,963評論 6 542
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,348評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,083評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,706評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,442評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,802評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,795評論 3 446
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,983評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,542評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,287評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,486評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,030評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,710評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,116評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,412評論 1 294
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,224評論 3 398
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,462評論 2 378

推薦閱讀更多精彩內容

  • Spring Cloud為開發人員提供了快速構建分布式系統中一些常見模式的工具(例如配置管理,服務發現,斷路器,智...
    卡卡羅2017閱讀 134,825評論 18 139
  • 當數據量增大到超出了單個物理計算機存儲容量時,有必要把它分開存儲在多個不同的計算機中。那些管理存儲在多個網絡互連的...
    單行線的旋律閱讀 1,940評論 0 7
  • 1、第八章 Samba服務器2、第八章 NFS服務器3、第十章 Linux下DNS服務器配站點,域名解析概念命令:...
    哈熝少主閱讀 3,763評論 0 10
  • Spring Boot 參考指南 介紹 轉載自:https://www.gitbook.com/book/qbgb...
    毛宇鵬閱讀 46,915評論 6 342
  • 其實寫作也就是把自己所想的寫出來, 有時候因為詞窮 而無法用文字盡心表達 讀書就是學習如何更好的表達自己內心想法的...
    多寶漁閱讀 383評論 4 2