国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂

Facades

Facades


Facades

簡介

Facades 為應(yīng)用的 服務(wù)容器 提供了一個「靜態(tài)」 接口。Laravel 自帶了很多 Facades,可以訪問絕大部分功能。Laravel Facades 實際是服務(wù)容器中底層類的 「靜態(tài)代理」 ,相對于傳統(tǒng)靜態(tài)方法,在使用時能夠提供更加靈活、更加易于測試、更加優(yōu)雅的語法。

所有的 Laravel Facades 都定義在 Illuminate\Support\Facades 命名空間下。所以,我們可以輕松的使用 Facade :

use Illuminate\Support\Facades\Cache;
Route::get('/cache', function () {  
  return Cache::get('key');
  });

在 Laravel 文檔中,有很多示例代碼都會使用 Facades 來演示框架的各種功能。

何時使用 Facades

Facades 有很多優(yōu)點,它提供了簡單,易記的語法,從而無需手動注入或配置長長的類名。此外,由于他們對 PHP 靜態(tài)方法的獨特調(diào)用,使得測試起來非常容易。

然而,在使用 Facades 時,有些地方需要特別注意。使用 Facades 時最主要的危險就是會引起類作用范圍的膨脹。由于 Facades 使用起來非常簡單并且不需要注入,就會使得我們不經(jīng)意間在單個類中使用許多 Facades ,從而導(dǎo)致類變得越來越大。然而使用依賴注入的時候,使用的類越多,構(gòu)造方法就會越長,在視覺上注意到這個類有些龐大了。因此在使用 Facades 的時候,要特別注意控制類的大小,讓類的作用范圍保持短小。

{tip} 在開發(fā)與 Laravel 進行交互的第三方擴展包時,最好選擇注入 Laravel 契約 而不使用 Facades 。因為擴展包是在 Laravel 之外構(gòu)建,你無法使用 Laravel Facades 測試輔助函數(shù)

Facades 相較于依賴注入

依賴注入的主要好處之一是能交換注入類的實現(xiàn)。在測試的時候非常有用,因為你可以注入一個 mock 或者 stub,并斷言 stub 上的各種方法。

通常,真正的靜態(tài)方法是不可能 mock 或 stub 的。但是 Facades 使用動態(tài)方法對服務(wù)容器中解析出來的對象方法的調(diào)用進行了代理,我們也可以像測試注入類實例一樣測試 Facades。比如,像下面的路由:

use Illuminate\Support\Facades\Cache;
Route::get('/cache', function () {  
  return Cache::get('key');
 });

我們可以帶上我們期望的參數(shù)編寫下面的測試代碼來驗證 Cache::get 方法:

use Illuminate\Support\Facades\Cache;
/**
 * 一個基礎(chǔ)功能的測試。
 *
 * @return void
 */
 public function testBasicExample(){ 
    Cache::shouldReceive('get')   
          ->with('key')     
          ->andReturn('value');  
    $this->visit('/cache')   
        ->see('value');
    }

Facades 相較于輔助函數(shù)

除了 Facades,Laravel 還包含各種 『輔助函數(shù)』 來實現(xiàn)這些常用功能,比如生成視圖、觸發(fā)事件、任務(wù)調(diào)度或者發(fā)送 HTTP 響應(yīng)。許多輔助函數(shù)都有與之對應(yīng)的 Facades 。例如,下面這個 Facades 和輔助函數(shù)的作用是一樣的:

return View::make('profile');return view('profile');

Facade 和輔助函數(shù)之間沒有實際的區(qū)別。當(dāng)你使用輔助函數(shù)時,你可以像測試相應(yīng)的 Facade 那樣進行測試。例如,下面的路由:

Route::get('/cache', function () {    return cache('key');});

在底層實現(xiàn),輔助函數(shù) cache 實際是調(diào)用 Cache 這個 Facade 的 get 方法。因此,盡管我們使用的是輔助函數(shù),我們依然可以帶上我們期望的參數(shù)編寫下面的測試代碼來驗證該方法:

use Illuminate\Support\Facades\Cache;
/**
 * 一個基礎(chǔ)功能的測試用例。
 *
 * @return void
 */
 public function testBasicExample(){ 
    Cache::shouldReceive('get')  
           ->with('key')    
           ->andReturn('value'); 
    $this->visit('/cache')  
        ->see('value');
     }

Facades 工作原理

在 Laravel 應(yīng)用中,F(xiàn)acade 就是一個可以從容器訪問對象的類。其中核心的部件就是 Facade 類。不管是 Laravel 自帶的 Facades,還是自定義的 Facades,都繼承自 Illuminate\Support\Facades\Facade 類。

Facade 基類使用了__callStatic() 魔術(shù)方法,直到對象從容器中被解析出來后,才會進行調(diào)用。在下面的例子中,調(diào)用了 Laravel 的緩存系統(tǒng)。通過瀏覽這段代碼,可以假定在 Cache 類中調(diào)用了靜態(tài)方法 get

<?php
   namespace App\Http\Controllers;
   use App\Http\Controllers\Controller;
   use Illuminate\Support\Facades\Cache;
   class UserController extends Controller{   
    /**
     * 顯示給定用戶的信息。
     *
     * @param  int  $id
     * @return Response
     */   
      public function showProfile($id) 
         {       
           $user = Cache::get('user:'.$id); 
           return view('profile', ['user' => $user]);  
          }
      }

注意在上面這段代碼中,我們『導(dǎo)入』了 Cache Facade。這個 Facade 作為訪問 Illuminate\Contracts\Cache\Factory 接口底層實現(xiàn)的代理。我們使用 Facade 進行的任何調(diào)用都將傳遞給 Laravel 緩存服務(wù)的底層實例。

如果我們看一下 Illuminate\Support\Facades\Cache 這個類,你會發(fā)現(xiàn)類中根本沒有 get 這個靜態(tài)方法:

class Cache extends Facade{   
    /**
     * 獲取組件的注冊名稱。
     *
     * @return string
     */  
       protected static function getFacadeAccessor() { 
            return 'cache'; 
        }
     }

Cache Facade 繼承了 Facade 類,并且定義了 getFacadeAccessor() 方法。這個方法的作用是返回服務(wù)容器綁定的名稱。當(dāng)用戶調(diào)用 Cache Facade 中的任何靜態(tài)方法時,Laravel 會從 服務(wù)容器 中解析 cache 綁定以及該對象運行所請求的方法(在這個例子中就是 get 方法)。

實時 Facades

使用實時 Facades,你可以將應(yīng)用程序中的任何類視為 Facade。為了說明這是如何使用的,我們來看看另一種方法。例如,假設(shè)我們的 Podcast 模型有一個 publish 方法。然而,為了發(fā)布 Podcast,我們需要注入一個 Publisher 實例:

<?php
   namespace App;
   use App\Contracts\Publisher;
   use Illuminate\Database\Eloquent\Model;
   class Podcast extends Model{  
     /**
     * 發(fā)布 Podcast。
     *
     * @param  Publisher  $publisher
     * @return void
     */ 
        public function publish(Publisher $publisher) 
           {     
              $this->update(['publishing' => now()]); 
              $publisher->publish($this);   
             }
        }

將發(fā)布者的實現(xiàn)注入到該方法中,我們可以輕松地測試這種方法,因為我們可以模擬注入的發(fā)布者。但是,它要求我們每次調(diào)用 publish 方法時都要傳遞一個發(fā)布者實例。使用實時的 Facades,我們可以保持同樣的可測試性,而不需要顯式地通過 Publisher 實例。要生成實時 Facade,請在導(dǎo)入類的名稱空間中加上 Facades:

<?php
   namespace App;
   use Facades\App\Contracts\Publisher;
   use Illuminate\Database\Eloquent\Model;
   class Podcast extends Model{ 
    /**
     * 發(fā)布 Podcast。
     *
     * @return void
     */ 
        public function publish()  
          {   
               $this->update(['publishing' => now()]); 
                Publisher::publish($this);  
            }
       }

當(dāng)使用實時 Facade 時,發(fā)布者實現(xiàn)將通過使用 Facades 前綴后出現(xiàn)的接口或類名的部分來解決服務(wù)容器的問題。在測試時,我們可以使用 Laravel 的內(nèi)置 facade 測試輔助函數(shù)來模擬這種方法調(diào)用:

<?php
  namespace Tests\Feature;use App\Podcast;
  use Tests\TestCase;use Facades\App\Contracts\Publisher;
  use Illuminate\Foundation\Testing\RefreshDatabase;
  class PodcastTest extends TestCase{  
    use RefreshDatabase;   
    /**
     * 一個測試演示。
     *
     * @return void
     */  
       public function test_podcast_can_be_published()  
         {    
             $podcast = factory(Podcast::class)->create(); 
             Publisher::shouldReceive('publish')->once()->with($podcast);  
             $podcast->publish(); 
            }
      }

Facade 類參考

在下面你可以找到每個 Facade 類及其對應(yīng)的底層類。這是一個查找給定 Facade 類 API 文檔的工具。服務(wù)容器綁定 的關(guān)鍵信息也包含在內(nèi)。

FacadeClass服務(wù)容器綁定
AppIlluminate\Foundation\Applicationapp
ArtisanIlluminate\Contracts\Console\Kernelartisan
AuthIlluminate\Auth\AuthManagerauth
Auth (Instance)Illuminate\Contracts\Auth\Guardauth.driver
BladeIlluminate\View\Compilers\BladeCompilerblade.compiler
BroadcastIlluminate\Contracts\Broadcasting\Factory 
Broadcast (Instance)Illuminate\Contracts\Broadcasting\Broadcaster 
BusIlluminate\Contracts\Bus\Dispatcher 
CacheIlluminate\Cache\CacheManagercache
Cache (Instance)Illuminate\Cache\Repositorycache.store
ConfigIlluminate\Config\Repositoryconfig
CookieIlluminate\Cookie\CookieJarcookie
CryptIlluminate\Encryption\Encrypterencrypter
DBIlluminate\Database\DatabaseManagerdb
DB (Instance)Illuminate\Database\Connectiondb.connection
EventIlluminate\Events\Dispatcherevents
FileIlluminate\Filesystem\Filesystemfiles
GateIlluminate\Contracts\Auth\Access\Gate 
HashIlluminate\Contracts\Hashing\Hasherhash
LangIlluminate\Translation\Translatortranslator
LogIlluminate\Log\LogManagerlog
MailIlluminate\Mail\Mailermailer
NotificationIlluminate\Notifications\ChannelManager 
PasswordIlluminate\Auth\Passwords\PasswordBrokerManagerauth.password
Password (Instance)Illuminate\Auth\Passwords\PasswordBrokerauth.password.broker
QueueIlluminate\Queue\QueueManagerqueue
Queue (Instance)Illuminate\Contracts\Queue\Queuequeue.connection
Queue (Base Class)Illuminate\Queue\Queue 
RedirectIlluminate\Routing\Redirectorredirect
RedisIlluminate\Redis\RedisManagerredis
Redis (Instance)Illuminate\Redis\Connections\Connectionredis.connection
RequestIlluminate\Http\Requestrequest
ResponseIlluminate\Contracts\Routing\ResponseFactory 
Response (Instance)Illuminate\Http\Response 
RouteIlluminate\Routing\Routerrouter
SchemaIlluminate\Database\Schema\Builder 
SessionIlluminate\Session\SessionManagersession
Session (Instance)Illuminate\Session\Storesession.store
StorageIlluminate\Filesystem\FilesystemManagerfilesystem
Storage (Instance)Illuminate\Contracts\Filesystem\Filesystemfilesystem.disk
URLIlluminate\Routing\UrlGeneratorurl
ValidatorIlluminate\Validation\Factoryvalidator
Validator (Instance)Illuminate\Validation\Validator 
ViewIlluminate\View\Factoryview
View (Instance)Illuminate\View\View 
本文章首發(fā)在 LearnKu.com 網(wǎng)站上。