對laravel核心概念的粗俗理解


1、Laravel 好比如是裝了葯的 葯箱,專門處理人們的問題、治病。

2、人們喜歡把我的葯箱叫做 service container 服務容器

3、把我的葯箱里面的一塊一塊的小格子叫 service provider 服務提供者。在這些小格子里可以放置不同的葯。

4、有的人用到我的時候,會在我的小格子或者是他們自制的格子里面放置自己制作的葯。

  有些葯有副作用,比如可以治療肚子疼又能治療頭痛,這樣肚子疼、頭不疼的患者吃了可能對頭產生不良影響。

  所以我定了一份合同契約讓放進來的葯有個規范。並且我內置的葯也是有契約來規范約束我自己。他們把我的這個合同稱為 contract 契約

5、有些葯片很難看,可以把它用糖衣包裝起來,這樣小孩子更容易吞食使用。

  我里面很多葯都用了這種包裝,葯效沒增加,但是更容易使用。

  人們后期添加的葯也可以自制包裝。這種包裝稱之為 facade 門面

一、葯箱(服務容器)

綁定,解析,解析事件(類似於在葯瓶中放葯,取葯,取葯事項)。

放葯(綁定)

基礎綁定

$this->app->bind('HelpSpot\API', function ($app) { return new HelpSpot\API($app->make('HttpClient')); }); 

綁定單例

$this->app->singleton('HelpSpot\API', function ($app) { return new HelpSpot\API($app->make('HttpClient')); }); 

綁定實例

$api = new HelpSpot\API(new HttpClient); $this->app->instance('HelpSpot\API', $api); 

綁定實例時給定初始化數據

$this->app->when('App\Http\Controllers\UserController') ->needs('$variableName') ->give($value); // 利用上下文給綁定設置初始數據 

舉個栗子

interface Fruit { public function color(); } class Apple implements Fruit { public $color; public function __construct($color){ $this->color = $color; } public function color(){ return $this->color; } } app()->bind('Fruit', 'Apple'); app()->when('Apple')->needs('$color')->give('red'); echo app('Fruit')->color(); 

綁定接口到實例

$this->app->bind( 'App\Contracts\EventPusher', 'App\Services\RedisEventPusher' ); 

根據上下文提供不同的綁定

$this->app->when(PhotoController::class) ->needs(Filesystem::class) ->give(function () { return Storage::disk('local'); }); $this->app->when([VideoController::class, UploadController::class]) ->needs(Filesystem::class) ->give(function () { return Storage::disk('s3'); }); 

給綁定設置標簽

$this->app->bind('SpeedReport', function () { // }); $this->app->bind('MemoryReport', function () { // }); $this->app->tag(['SpeedReport', 'MemoryReport'], 'reports'); $this->app->bind('ReportAggregator', function ($app) { return new ReportAggregator($app->tagged('reports')); }); 

當 Service 已經被解析,extend 方法可以用來修改解析出來的實例 $service

$this->app->extend(Service::class, function ($service, $app) { return new DecoratedService($service); }); 
拿葯(解析)
$this->app->make('HelpSpot\API'); app()->make('HelpSpot\API'); resolve('HelpSpot\API'); app('HelpSpot\API'); app()['HelpSpot\API'] app()->get('HelpSpot\API') public function xxx(HelpSpot\API $users) 
// 注入依賴 $api = $this->app->makeWith('HelpSpot\API', ['id' => 1]); $api = app('HelpSpot\API', ['id' => 1]); $api = resolve('HelpSpot\API', ['id' => 1]); 
# laravel 實現了 PSR-11 接口,所以就可以用該接口的類型提示解析 use Psr\Container\ContainerInterface; Route::get('/', function (ContainerInterface $container) { $service = $container->get('Service'); // }); 
容器事件

容器解析任何對象時調用

$this->app->resolving(function ($object, $app) { }); 

容器解析 HelpSpot\API 時調用

$this->app->resolving(HelpSpot\API::class, function ($api, $app) { }); 

二、葯箱里的小格子(服務提供者)

制作一個服務提供者
  1. php artisan make:provider RiakServiceProvider
  2. 服務提供者主要由兩個方法:register 和 boot 。register 只負責綁定一些東西到容器(放葯)。boot 可以使用類型提示解析等來完成任意你想做的事情,這些都歸功於容器調用所有服務提供者的register方法之后才去調用boot方法。
  3. config/app.phpproviders數組中注冊服務提供者。
制作一個延遲服務提供者

如果只是綁定服務到服務容器,可以設置為延遲(實現 DeferrableProvider 接口),在項目真正需要用到之前不會注冊。

class RiakServiceProvider extends ServiceProvider implements DeferrableProvider { public function register() { $this->app->singleton(Connection::class, function ($app) { return new Connection(config('riak')); }); } public function provides() { return [Connection::class]; } } 

三、Facades

不要在一個類中,用太多的facades。過於臃腫的情況下應該將大類分解成幾個小類。

優點

方便測試(輔助函數和 facades 沒什么區別,測試方法也是一樣的)。

Route::get('/cache', function () { return Cache::get('key'); // === return cache('key'); }); 
public function testBasicExample() { Cache::shouldReceive('get') ->with('key') ->andReturn('value'); $this->visit('/cache') ->see('value'); } 
實時的 facades

原生用法 vs 實時用法

# 原生用法 class Podcast use App\Contracts\Publisher; public function publish(Publisher $publisher) { $this->update(['publishing' => now()]); $publisher->publish($this); } 
# 實時用法 use Facades\App\Contracts\Publisher; Publisher::publish($this); 

測試實時的 facades

use Facades\App\Contracts\Publisher; Publisher::shouldReceive('publish')->once()->with($podcast); 
facades 列表
Facade Class Service Container Binding
App Illuminate\Foundation\Application app
Artisan Illuminate\Contracts\Console\Kernel artisan
Auth Illuminate\Auth\AuthManager auth
Auth (Instance) Illuminate\Contracts\Auth\Guard auth.driver
Blade Illuminate\View\Compilers\BladeCompiler blade.compiler
Broadcast Illuminate\Contracts\Broadcasting\Factory  
Broadcast (Instance) Illuminate\Contracts\Broadcasting\Broadcaster  
Bus Illuminate\Contracts\Bus\Dispatcher  
Cache Illuminate\Cache\CacheManager cache
Cache (Instance) Illuminate\Cache\Repository cache.store
Config Illuminate\Config\Repository config
Cookie Illuminate\Cookie\CookieJar cookie
Crypt Illuminate\Encryption\Encrypter encrypter
DB Illuminate\Database\DatabaseManager db
DB (Instance) Illuminate\Database\Connection db.connection
Event Illuminate\Events\Dispatcher events
File Illuminate\Filesystem\Filesystem files
Gate Illuminate\Contracts\Auth\Access\Gate  
Hash Illuminate\Contracts\Hashing\Hasher hash
Lang Illuminate\Translation\Translator translator
Log Illuminate\Log\LogManager log
Mail Illuminate\Mail\Mailer mailer
Notification Illuminate\Notifications\ChannelManager  
Password Illuminate\Auth\Passwords\PasswordBrokerManager auth.password
Password (Instance) Illuminate\Auth\Passwords\PasswordBroker auth.password.broker
Queue Illuminate\Queue\QueueManager queue
Queue (Instance) Illuminate\Contracts\Queue\Queue queue.connection
Queue (Base Class) Illuminate\Queue\Queue  
Redirect Illuminate\Routing\Redirector redirect
Redis Illuminate\Redis\RedisManager redis
Redis (Instance) Illuminate\Redis\Connections\Connection redis.connection
Request Illuminate\Http\Request request
Response Illuminate\Contracts\Routing\ResponseFactory  
Response (Instance) Illuminate\Http\Response  
Route Illuminate\Routing\Router router
Schema Illuminate\Database\Schema\Builder  
Session Illuminate\Session\SessionManager session
Session (Instance) Illuminate\Session\Store session.store
Storage Illuminate\Filesystem\FilesystemManager filesystem
Storage (Instance) Illuminate\Contracts\Filesystem\Filesystem filesystem.disk
URL Illuminate\Routing\UrlGenerator url
Validator Illuminate\Validation\Factory validator
Validator (Instance) Illuminate\Validation\Validator  
View Illuminate\View\Factory view
View (Instance) Illuminate\View\View  

四、Contracts

Facades 和 Contracts 沒有什么值得注意的區別,但是當你開發第三方包的時候,最好使用 Contracts,這樣有利於你編寫測試,否則如果使用 Facades,因為是第三方包,將不能訪問 facade 測試函數。

使用方法

在構造函數中類型提示注入就行了。

Contracts 列表
Contract References Facade
Illuminate\Contracts\Auth\Access\Authorizable  
Illuminate\Contracts\Auth\Access\Gate Gate
Illuminate\Contracts\Auth\Authenticatable  
Illuminate\Contracts\Auth\CanResetPassword  
Illuminate\Contracts\Auth\Factory Auth
Illuminate\Contracts\Auth\Guard Auth::guard()
Illuminate\Contracts\Auth\PasswordBroker Password::broker()
Illuminate\Contracts\Auth\PasswordBrokerFactory Password
Illuminate\Contracts\Auth\StatefulGuard  
Illuminate\Contracts\Auth\SupportsBasicAuth  
Illuminate\Contracts\Auth\UserProvider  
Illuminate\Contracts\Bus\Dispatcher Bus
Illuminate\Contracts\Bus\QueueingDispatcher Bus::dispatchToQueue()
Illuminate\Contracts\Broadcasting\Factory Broadcast
Illuminate\Contracts\Broadcasting\Broadcaster Broadcast::connection()
Illuminate\Contracts\Broadcasting\ShouldBroadcast  
Illuminate\Contracts\Broadcasting\ShouldBroadcastNow  
Illuminate\Contracts\Cache\Factory Cache
Illuminate\Contracts\Cache\Lock  
Illuminate\Contracts\Cache\LockProvider  
Illuminate\Contracts\Cache\Repository Cache::driver()
Illuminate\Contracts\Cache\Store  
Illuminate\Contracts\Config\Repository Config
Illuminate\Contracts\Console\Application  
Illuminate\Contracts\Console\Kernel Artisan
Illuminate\Contracts\Container\Container App
Illuminate\Contracts\Cookie\Factory Cookie
Illuminate\Contracts\Cookie\QueueingFactory Cookie::queue()
Illuminate\Contracts\Database\ModelIdentifier  
Illuminate\Contracts\Debug\ExceptionHandler  
Illuminate\Contracts\Encryption\Encrypter Crypt
Illuminate\Contracts\Events\Dispatcher Event
Illuminate\Contracts\Filesystem\Cloud Storage::cloud()
Illuminate\Contracts\Filesystem\Factory Storage
Illuminate\Contracts\Filesystem\Filesystem Storage::disk()
Illuminate\Contracts\Foundation\Application App
Illuminate\Contracts\Hashing\Hasher Hash
Illuminate\Contracts\Http\Kernel  
Illuminate\Contracts\Mail\MailQueue Mail::queue()
Illuminate\Contracts\Mail\Mailable  
Illuminate\Contracts\Mail\Mailer Mail
Illuminate\Contracts\Notifications\Dispatcher Notification
Illuminate\Contracts\Notifications\Factory Notification
Illuminate\Contracts\Pagination\LengthAwarePaginator  
Illuminate\Contracts\Pagination\Paginator  
Illuminate\Contracts\Pipeline\Hub  
Illuminate\Contracts\Pipeline\Pipeline  
Illuminate\Contracts\Queue\EntityResolver  
Illuminate\Contracts\Queue\Factory Queue
Illuminate\Contracts\Queue\Job  
Illuminate\Contracts\Queue\Monitor Queue
Illuminate\Contracts\Queue\Queue Queue::connection()
Illuminate\Contracts\Queue\QueueableCollection  
Illuminate\Contracts\Queue\QueueableEntity  
Illuminate\Contracts\Queue\ShouldQueue  
Illuminate\Contracts\Redis\Factory Redis
Illuminate\Contracts\Routing\BindingRegistrar Route
Illuminate\Contracts\Routing\Registrar Route
Illuminate\Contracts\Routing\ResponseFactory Response
Illuminate\Contracts\Routing\UrlGenerator URL
Illuminate\Contracts\Routing\UrlRoutable  
Illuminate\Contracts\Session\Session Session::driver()
Illuminate\Contracts\Support\Arrayable  
Illuminate\Contracts\Support\Htmlable  
Illuminate\Contracts\Support\Jsonable  
Illuminate\Contracts\Support\MessageBag  
Illuminate\Contracts\Support\MessageProvider  
Illuminate\Contracts\Support\Renderable  
Illuminate\Contracts\Support\Responsable  
Illuminate\Contracts\Translation\Loader  
Illuminate\Contracts\Translation\Translator Lang
Illuminate\Contracts\Validation\Factory Validator
Illuminate\Contracts\Validation\ImplicitRule  
Illuminate\Contracts\Validation\Rule  
Illuminate\Contracts\Validation\ValidatesWhenResolved  
Illuminate\Contracts\Validation\Validator Validator::make()
Illuminate\Contracts\View\Engine  
Illuminate\Contracts\View\Factory View
Illuminate\Contracts\View\View View::make()

五、請求生命周期

本節主要概括了框架運行的生命周期。

  1. 所有請求必定首先通過 public/index.php
  2. 在上述這個文件中首先加載 composer 自動加載文件,然后從 bootstrap/app.php 實例化一個服務容器。
  3. 接下來,框架會根據請求類型傳送請求至 app/Http/Kernel.php 或者 app/Console/Kernel.php
  4. app/Http/Kernel.php 擴展了Illuminate\Foundation\Http\Kernel 類,父類強制在處理請求前應該做哪些操作,操作內容都放到了 bootstrappers 數組里面(配置錯誤處理、配置記錄日志、檢測應用環境、注冊和啟動服務提供者等)。子類在數組 middleware 中規定了請求在被處理前必須經過的一些處理(讀寫 session、判斷是否處於維護模式、驗證 csrf 令牌等)。
  5. 處理請求,返回響應內容。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM