Fassaden
- Einführung
- Wann zu verwenden Fassaden
- Fassaden So funktioniert es
- Echtzeit-Fassaden
- Fassade Referenzklasse
Fassaden stellen eine „Statik“ für den Servicecontainer der Anwendung bereit ” Schnittstelle. Laravel verfügt über viele Fassaden, die Zugriff auf die meisten Funktionen ermöglichen. Laravel-Fassaden sind eigentlich „statische Proxys“ für die zugrunde liegenden Klassen im Service-Container. Im Vergleich zu herkömmlichen statischen Methoden können sie bei ihrer Verwendung eine flexiblere, einfacher zu testende und elegantere Syntax bieten.
Alle Laravel-Fassaden werden im
-Namespace definiert. Daher können wir Facade problemlos verwenden:use Illuminate\Support\Facades\Cache; Route::get('/cache', function () { return Cache::get('key'); });
IlluminateSupportFacades
In der Laravel-Dokumentation gibt es viele Beispielcodes, die Facades verwenden, um verschiedene Funktionen des Frameworks zu demonstrieren. Wann werden Fassaden verwendet?
Fassaden bieten viele Vorteile. Sie bieten eine einfache, leicht zu merkende Syntax, die das manuelle Einfügen oder Konfigurieren langer Klassennamen überflüssig macht. Darüber hinaus machen sie das Testen aufgrund ihrer einzigartigen Aufrufe statischer PHP-Methoden sehr einfach.
Es gibt jedoch einige Dinge, die beim Einsatz von Fassaden besondere Aufmerksamkeit erfordern. Die Hauptgefahr bei der Verwendung von Fassaden ist die Erweiterung des Klassenumfangs. Da Fassaden sehr einfach zu verwenden sind und keine Injektion erfordern, können wir versehentlich viele Fassaden in einer einzelnen Klasse verwenden, wodurch die Klasse immer größer wird. Wenn jedoch die Abhängigkeitsinjektion verwendet wird, ist die Konstruktionsmethode umso länger, je mehr Klassen verwendet werden. Visuell fällt auf, dass diese Klasse etwas umfangreich ist. Achten Sie daher bei der Verwendung von Fassaden besonders auf die Kontrolle der Klassengröße, um den Umfang der Klasse kurz zu halten.
{tip} Bei der Entwicklung von Erweiterungspaketen von Drittanbietern, die mit Laravel interagieren, ist es am besten, Laravel-Verträge einzuschleusen, anstatt Facades zu verwenden. Da das Erweiterungspaket außerhalb von Laravel erstellt wird, können Sie Laravel Facades nicht zum Testen von Hilfsfunktionen
Facades im Vergleich zu Abhängigkeiten verwenden Injektion
Einer der Hauptvorteile der Abhängigkeitsinjektion ist die Möglichkeit, die Implementierung der injizierten Klasse auszutauschen. Sehr nützlich beim Testen, da Sie einen Mock oder Stub einfügen und verschiedene Methoden auf dem Stub geltend machen können.
Normalerweise ist es unmöglich, wirklich statische Methoden zu verspotten oder zu blockieren. Facades verwenden jedoch dynamische Methoden, um den Aufruf von im Servicecontainer analysierten Objektmethoden zu vertreten. Wir können Facades genauso testen wie das Testen injizierter Klasseninstanzen. Zum Beispiel wie die folgende Route:
use Illuminate\Support\Facades\Cache; Route::get('/cache', function () { return Cache::get('key'); });
Wir können den folgenden Testcode mit den Parametern schreiben, die wir zur Überprüfung der Cache::get
-Methode erwarten:
use Illuminate\Support\Facades\Cache; /** * 一个基础功能的测试。 * * @return void */ public function testBasicExample(){ Cache::shouldReceive('get') ->with('key') ->andReturn('value'); $this->visit('/cache') ->see('value'); }
Fassaden Im Vergleich zu Hilfsfunktionen
Zusätzlich zu Facades enthält Laravel auch verschiedene „Hilfsfunktionen“ zur Implementierung dieser allgemeinen Funktionen, wie z. B. das Generieren von Ansichten, das Auslösen von Ereignissen, die Aufgabenplanung oder das Senden von HTTP-Antworten. Für viele Nebenfunktionen gibt es entsprechende Fassaden. Beispielsweise bewirken die folgenden Fassaden und Hilfsfunktionen dasselbe:
return View::make('profile');return view('profile');
Es gibt keinen tatsächlichen Unterschied zwischen Fassaden und Hilfsfunktionen. Wenn Sie eine Hilfsfunktion verwenden, können Sie diese genau wie die entsprechende Fassade testen. Beispielsweise wird unten die folgende Route implementiert:
Route::get('/cache', function () { return cache('key');});
, und die Hilfsfunktion cache
ruft tatsächlich die Cache
-Methode der Fassade auf. Daher können wir, auch wenn wir eine Hilfsfunktion verwenden, dennoch den folgenden Testcode mit den Parametern schreiben, die wir zur Überprüfung der Methode erwarten: get
use Illuminate\Support\Facades\Cache; /** * 一个基础功能的测试用例。 * * @return void */ public function testBasicExample(){ Cache::shouldReceive('get') ->with('key') ->andReturn('value'); $this->visit('/cache') ->see('value'); }
So funktionieren Fassaden
In einer Laravel-Anwendung ist eine Fassade eine Klasse, die auf Objekte aus dem Container zugreifen kann. Die Kernkomponente ist die Klasse Facade
. Ob es sich um Laravels eigene Fassaden oder benutzerdefinierte Fassaden handelt, sie alle erben von der Klasse IlluminateSupportFacadesFacade
.
Facade
Die Basisklasse verwendet die magische Methode __callStatic()
, die erst aufgerufen wird, wenn das Objekt aus dem Container analysiert wird. Im folgenden Beispiel wird das Caching-System von Laravel aufgerufen. Beim Durchsuchen dieses Codes kann davon ausgegangen werden, dass die statische Methode Cache
in der Klasse get
aufgerufen wird:
<?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]); } }
Beachten Sie, dass wir im obigen Code die Cache
-Fassade „importieren“. Diese Fassade fungiert als Proxy für den Zugriff auf die zugrunde liegende Implementierung der IlluminateContractsCacheFactory
-Schnittstelle. Alle Aufrufe, die wir über die Fassade tätigen, werden an die zugrunde liegende Instanz des Laravel-Caching-Dienstes weitergeleitet.
Wenn wir uns die IlluminateSupportFacadesCache
-Klasse ansehen, werden Sie feststellen, dass es in der Klasse überhaupt keine get
statische Methode gibt:
class Cache extends Facade{ /** * 获取组件的注册名称。 * * @return string */ protected static function getFacadeAccessor() { return 'cache'; } }
Cache
Facade erbt die Facade-Klasse und definiert die getFacadeAccessor()
Methode. Die Funktion dieser Methode besteht darin, den Namen der Service-Container-Bindung zurückzugeben. Wenn der Benutzer eine statische Methode in der Cache
-Fassade aufruft, löst Laravel die cache
-Bindung aus dem Service-Container auf und führt die angeforderte Methode für dieses Objekt aus (in diesem Fall die get
-Methode).
Echtzeit-Fassaden
Mit Echtzeit-Fassaden können Sie jede Klasse in Ihrer Anwendung als eine Klasse behandeln Fassade. Um zu veranschaulichen, wie dies verwendet wird, schauen wir uns eine andere Methode an. Nehmen wir zum Beispiel an, unser Podcast
-Modell verfügt über eine publish
-Methode. Um jedoch einen Podcast zu veröffentlichen, müssen wir eine Publisher
-Instanz einfügen:
<?php namespace App; use App\Contracts\Publisher; use Illuminate\Database\Eloquent\Model; class Podcast extends Model{ /** * 发布 Podcast。 * * @param Publisher $publisher * @return void */ public function publish(Publisher $publisher) { $this->update(['publishing' => now()]); $publisher->publish($this); } }
Indem wir die Implementierung des Herausgebers in die Methode einfügen, können wir diesen Ansatz leicht testen, da wir den injizierten Herausgeber verspotten können. Allerdings müssen wir jedes Mal, wenn wir die publish
-Methode aufrufen, eine Herausgeberinstanz übergeben. Mit Live-Fassaden können wir die gleiche Testbarkeit aufrechterhalten, ohne Publisher
Instanzen explizit übergeben zu müssen. Um ein Echtzeit-Facade
zu generieren, stellen Sie die Facades im Namespace der importierten Klasse voran:
<?php namespace App; use Facades\App\Contracts\Publisher; use Illuminate\Database\Eloquent\Model; class Podcast extends Model{ /** * 发布 Podcast。 * * @return void */ public function publish() { $this->update(['publishing' => now()]); Publisher::publish($this); } }
Bei Verwendung einer Echtzeit-Fassade übergibt die Herausgeberimplementierung den Schnittstellen- oder Klassennamen mithilfe von Facades
Präfix, das danach erscheint. Löst das Problem des Service-Containers teilweise. Beim Testen können wir die integrierte Fassadentest-Hilfsfunktion von Laravel verwenden, um diesen Methodenaufruf zu simulieren:
<?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-Klassenreferenz
Unten finden Sie jede Facade-Klasse und die entsprechende zugrunde liegende Klasse. Dies ist ein Tool zum Auffinden der API-Dokumentation für eine bestimmte Facade-Klasse. Wichtige Informationen für Service-Container-Bindungen sind ebenfalls enthalten.
Fassade | Klasse | 服务容器绑定 |
---|---|---|
Ap p | IlluminateFoundationApplication | app |
Art isan | IlluminateContractsConsoleKernel | artisan |
Auth | IlluminateAuthAuthManager | auth |
Autor (Instanz) | IlluminateContractsAuthGuard | auth.driver |
Blade | IlluminateViewCompilersBladeCom Piler | blade.compiler |
Broadcast | IlluminateContractsBroadcastingFactory | |
Broadcast (Instanz) | IlluminateContractsBroadcastingBroadcaster | |
Bus | IlluminateCont ractsBusDispatcher | |
Cache | IlluminateCacheCacheManager | cache |
Cache (Instanz) | IlluminateCacheRepository | cache.store |
Config | IlluminateConfigRepository | config |
Cookie | IlluminateCookieCookieJar | cookie |
C rypt | IlluminateEncryptionEncrypter | encrypter |
DB | IlluminateDatabaseDatabaseManager | db |
DB (Instanz) | IlluminateDatabaseConnection | db.connection |
Event | IlluminateEventsDispatcher | events |
Datei | IlluminateFilesystemFilesystem | files |
Gate | IlluminateContr ActsAuthAccessGate | |
Hash | IlluminateContractsHashingHasher | hash |
Lang | IlluminateTranslationTranslator | translator |
Log | IlluminateLogLogManager | log |
IlluminateMailMailer | mailer | |
Benachrichtigung | IlluminateNotificationsChannelMana ger | |
Passwort | IlluminateAuthPasswordsPasswordBrokerManager | auth.password |
Passwort (Instanz) | IlluminateAuthPasswordsPasswordBroker | auth.password.broker |
Warteschlange | IlluminateQueueQueueManager | queue |
Warteschlange (Instanz) | IlluminateContractsQueueQueue | queue.connection |
Queue (Base Klasse) | IlluminateQueueQueue | |
Redirect | IlluminateRoutingRedire ctor | redirect |
Redis | IlluminateRedisRedisManager | redis |
Redis (Instanz) | IlluminateRedisConnectionsConnection | redis.connection |
Request | IlluminateHttpRequest | request |
Antwort | IlluminateContractsRoutingResponseFactory | |
Antwort (Instanz) | IlluminateHttpResponse | |
Rout e | IlluminateRoutingRouter | router |
Schema | IlluminateDatabaseSchemaBuilder | |
Sitzung | IlluminateSessionSessionManager | session |
Sitzung (Instanz) | IlluminateSessionStore | session.store |
Storage | IlluminateFilesystemFilesystemManager | filesystem |
Lagerung (Instanz) | IlluminateContractsFilesystemFilesystem | filesystem.disk |
URL | IlluminateRoutingU rlGenerator | url |
Validator | IlluminateValidationFactory | validator |
Validator (Instanz) | IlluminateValidationValidator | |
Ansicht | IlluminateViewFactory | view |
Ansicht (Instanz) | IlluminateViewView |