laravel學習筆記

PHP安裝php

https://www.php.net/downloads...nginx

composer安裝

安裝方式laravel

https://getcomposer.org/downl...web

配置composer鏡像下載地址redis

//全局配置
composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/
//全局取消配置
composer config -g --unset repos.packagist
//當前項目
composer config repo.packagist composer https://mirrors.aliyun.com/composer/
//當前項目取消配置
composer config --unset repos.packagist

laravel安裝

環境要求數據庫

PHP> = 7.2.0
BCMath PHP擴展
Ctype PHP擴展
JSON PHP擴展
Mbstring PHP擴展
OpenSSL PHP擴展
PDO PHP擴展
Tokenizer PHP擴展
XML PHP擴展

經過laravel安裝程序apache

composer global require laravel/installer
laravel new blog

經過composer建立項目bootstrap

composer create-project --prefer-dist laravel/laravel blog

啓動本地服務器api

php artisan serve

目錄結構

根目錄下的各個目錄

app:應用程序核心目錄,幾乎項目全部的類都在這裏。數組

bootstrap:包含框架啓動文件 app.php,和啓動時爲了優化性能而生成的文件。

config:包含全部配置文件。最好是讀一遍這些文件,瞭解你能夠輕鬆配置哪些內容。

database:包含數據庫填充、遷移、模型工廠文件。能夠用做 SQLite 數據庫存放目錄。

public:靜態資源目錄,幷包含了首頁文件 index.php

resource:包含了未編譯的源文件(模板、語言、資源)。

routes:包含了全部的路由定義。

storage:包含了編譯好的模板文件,session 文件,緩存文件,日誌等文件。

tests:包含了自動測試文件。運行測試命令 php vendor/bin/phpunit

vendorcomposer 依賴目錄。

app目錄下的各個目錄

app 目錄下的不少目錄是命令生成的。由 Composer 使用 PSR-4 自動加載標準自動加載。

查看生成命令:php artisan make:list

Broadcasting:包含全部 broadcast channel 類。

Console:包含自定義的命令和用來註冊命令、定義計劃任務的內核文件。

Events:事件目錄。

Exceptions:異常和異常處理目錄。

Http:包含了控制器、中間件和表單請求。幾乎全部請求的處理邏輯都被放在這裏。

Jobs:儲存隊列任務。

Listeners:存儲事件的監聽。

Mail:存儲郵件類目錄。

Notifications:存放通知類。laravel 內置了不少驅動: email, Slack, SMS, database。

Policies:受權策略類目錄。

Providers:包含了全部服務提供者。服務提供者經過在服務容器上綁定服務、註冊事件或者執行其餘任務來啓動你的應用。

Rules:儲存自定義驗證規則對象。

routes目錄下的各個目錄

web.php內的路由將應用 web 中間件組(功能:session 狀態,CSRF 保護,cookie 加密等)。

api.php內的路由將應用 api 中間件組(功能:訪問速率控制等)。全部的請求將經過 token 認證,無 session 狀態。

consoles.php定義了全部基於控制檯命令的閉包。

channels.php註冊了全部的事件廣播頻道。

WEB服務器配置

apache

Options +FollowSymLinks -Indexes
RewriteEngine On

RewriteCond %{HTTP:Authorization} .
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]

RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]

nginx

location / {
    try_files $uri $uri/ /index.php?$query_string;
}

配置

配置目錄 config

環境配置

.env 文件內的變量會被系統級別或服務器級別的變量覆蓋。

有空格的值請用雙引號包含起來 APP_NAME="My Application"

.env 文件內的變量經過env()函數獲取,config目錄下的變量經過config()函數獲取

在運行PHPUnit測試時或執行以--env=testing爲選項Artisan命令時,.env.testing會覆蓋 .env 文件中的值。

$environment = App::environment();

if (App::environment('local')) {
    // 環境是 local
}

if (App::environment(['local', 'staging'])) {
    // 環境是 local 或 staging...
}

隱藏 debug 頁面中的環境變量

# config/app.php
return [
    // ...
    'debug_blacklist' => [
        '_ENV' => [
            'APP_KEY',
            'DB_PASSWORD',
        ],

        '_SERVER' => [
            'APP_KEY',
            'DB_PASSWORD',
        ],

        '_POST' => [
            'password',
        ],
    ],
];

設置獲取

$value = config('app.timezone');                           // 獲取
config(['app.timezone' => 'America/Chicago']);             // 設置

維護模式

優先加載:resources/views/errors/503.blade.php

php artisan down 
php artisan down --message="Upgrading Database" --retry=60 
php artisan down --allow=127.0.0.1 --allow=192.168.0.0/16`
//退出應用程序的維護模式 
php artisan up

請求生命週期

全部請求一定首先經過 public/index.php

首先加載composer自動加載文件,而後在bootstrap/app.php實例化一個基礎服務容器

框架會將全部的請求傳送到HTTP / Console 內核app/Http/Kernel.phpapp/Console/Kernel.php

app/Http/Kernel.php繼承Illuminate\Foundation\Http\Kernel,在請求被執行以前執行,主要是配置錯誤處理,日誌,檢查環境,已經其餘請求被處理前需執行的任務,好比:HTTP中間件,會話管理,CSRF令牌等

Illuminate\Foundation\Http\Kernel獲取一個 Request ,返回一個 Response

應用程序全部服務提供程序都在config/app.php配置文件的 providers 數組中配置。

首先將在全部的提供程序上調用register方法,而後一旦全部提供程序都已經註冊號,將調用boot方法。一旦應用程序被引導,Request 將被傳遞給 router 以進行分派。 router 會將請求分派給路由或控制器,以及運行任何路由特定的中間件。

服務容器

服務容器中的綁定,解析,解析事件

綁定

基礎綁定

$this->app->bind('redis.connection', function ($app) {
    return $app['redis']->connection();
});

單例綁定

$this->app->singleton('redis', function ($app) { $config = $app->make('config')->get('database.redis', []);
    return new RedisManager($app, Arr::pull($config, 'client', 'predis'), $config);
});

實例綁定

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

給實例初始值

$this->app->when('App\Http\Controllers\UserController')
          ->needs('$variableName')
          ->give($value);

接口綁定

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

根據上下文提供不一樣的綁定

use Illuminate\Support\Facades\Storage;
use App\Http\Controllers\PhotoController;
use App\Http\Controllers\VideoController;
use Illuminate\Contracts\Filesystem\Filesystem;

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

經過 tagged 方法輕鬆地解析它們

$this->app->bind('ReportAggregator', function ($app) {
    return new ReportAggregator($app->tagged('reports'));
});

擴展綁定

extend 方法能夠修改已解析的服務。

$this->app->extend(Service::class, function ($service) {
    return new DecoratedService($service);
});

解析實例

基礎解析

$api = $this->app->make('HelpSpot\API');

//沒法訪問$app時,調用resolve函數
$api = resolve('HelpSpot\API');

//解析時候經過關聯數組注入依賴
$api = $this->app->makeWith('HelpSpot\API', ['id' => 1]);

容器事件

服務容器每次解析對象會觸發一個事件,你可使用 resolving 方法監聽這個事件 :

//容器解析任何對象時調用
$this->app->resolving(function ($object, $app) {
    // Called when container resolves object of any type...
});
//容器解析HelpSpot\API時調用
$this->app->resolving(HelpSpot\API::class, function ($api, $app) {
    // Called when container resolves objects of type "HelpSpot\API"...
});

服務提供者

加載服務提供者是框架啓動的關鍵步驟之一,它主要負責啓動不一樣的組件(數據庫、隊列、驗證、路由等),服務提供者被配置在config/app.php中的providers數組中

全部的服務器都繼承Illuminate\Support\ServiceProvider類,其中該類包含一個registerboot方法,其中register方法中,只須要將服務綁定到服務容器中

製做一個服務提供者

經過artisan命令行工具make:provider生成一個新的提供者

php artisan make:provider RiakServiceProvider

服務提供者主要由兩個方法:registerbootregister 只負責綁定一些東西到容器。boot 可使用類型提示解析等來完成任意你想作的事情,這些都歸功於容器調用全部服務提供者的register方法以後纔去調用boot方法。

config/app.phpproviders數組中註冊服務提供者。

製做一個延遲服務提供者

若是你的服務提供者只在服務容器中註冊,能夠選着延遲加載該綁定直到註冊綁定的服務真的須要時在加載,延遲加載這樣的提供者提高應用的性能,由於它不是每次都在請求的時候進入加載

要延遲加載提供者,須要實現 \Illuminate\Contracts\Support\DeferrableProvider接口並置一個 provides 方法。這個 provides 方法返回該提供者註冊的服務容器綁定:

<?php

namespace App\Providers;

use Riak\Connection;
use Illuminate\Support\ServiceProvider;
use Illuminate\Contracts\Support\DeferrableProvider;

class RiakServiceProvider extends ServiceProvider implements DeferrableProvider
{
    /**
     * 註冊服務提供者。
     *
     * @return void
     */
    public function register()
    {
        $this->app->singleton(Connection::class, function ($app) {
            return new Connection($app['config']['riak']);
        });
    }

    /**
     * 獲取由提供者提供的服務。
     *
     * @return array
     */
    public function provides()
    {
        return [Connection::class];
    }
}

Facades

Facades原理

在 Laravel 應用中,Facade 就是一個能夠從容器訪問對象的類。其中核心的部件就是 Facade 類。無論是 Laravel 自帶的 Facades,仍是自定義的 Facades,都繼承自 Illuminate\Support\Facades\Facade 類。Facade 基類使用了__callStatic() 魔術方法,直到對象從容器中被解析出來後,纔會進行調用。

use Illuminate\Support\Facades\Cache;

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

原生用法 vs 實時用法

# 原生用法
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 列表

Facade Class Service Container Binding
App IlluminateFoundationApplication app
Artisan IlluminateContractsConsoleKernel artisan
Auth IlluminateAuthAuthManager auth
Auth (Instance) IlluminateContractsAuthGuard auth.driver
Blade IlluminateViewCompilersBladeCompiler blade.compiler
Broadcast IlluminateContractsBroadcastingFactory  
Broadcast (Instance) IlluminateContractsBroadcastingBroadcaster  
Bus IlluminateContractsBusDispatcher  
Cache IlluminateCacheCacheManager cache
Cache (Instance) IlluminateCacheRepository cache.store
Config IlluminateConfigRepository config
Cookie IlluminateCookieCookieJar cookie
Crypt IlluminateEncryptionEncrypter encrypter
DB IlluminateDatabaseDatabaseManager db
DB (Instance) IlluminateDatabaseConnection db.connection
Event IlluminateEventsDispatcher events
File IlluminateFilesystemFilesystem files
Gate IlluminateContractsAuthAccessGate  
Hash IlluminateContractsHashingHasher hash
Lang IlluminateTranslationTranslator translator
Log IlluminateLogLogManager log
Mail IlluminateMailMailer mailer
Notification IlluminateNotificationsChannelManager  
Password IlluminateAuthPasswordsPasswordBrokerManager auth.password
Password (Instance) IlluminateAuthPasswordsPasswordBroker auth.password.broker
Queue IlluminateQueueQueueManager queue
Queue (Instance) IlluminateContractsQueueQueue queue.connection
Queue (Base Class) IlluminateQueueQueue  
Redirect IlluminateRoutingRedirector redirect
Redis IlluminateRedisRedisManager redis
Redis (Instance) IlluminateRedisConnectionsConnection redis.connection
Request IlluminateHttpRequest request
Response IlluminateContractsRoutingResponseFactory  
Response (Instance) IlluminateHttpResponse  
Route IlluminateRoutingRouter router
Schema IlluminateDatabaseSchemaBuilder  
Session IlluminateSessionSessionManager session
Session (Instance) IlluminateSessionStore session.store
Storage IlluminateFilesystemFilesystemManager filesystem
Storage (Instance) IlluminateContractsFilesystemFilesystem filesystem.disk
URL IlluminateRoutingUrlGenerator url
Validator IlluminateValidationFactory validator
Validator (Instance) IlluminateValidationValidator  
View IlluminateViewFactory view
View (Instance) IlluminateViewView

契約

契約和 Facades 都可以用來構建健壯的、充分測試過的 Laravel 應用。

緩存實現的高耦合代碼

<?php

namespace App\Orders;

class Repository
{
   /**
     * 緩存實例
     */
    protected $cache;

    /**
     * 建立一個新的倉庫實例
     *
     * @param  \SomePackage\Cache\Memcached  $cache
     * @return void
     */
    public function __construct(\SomePackage\Cache\Memcached $cache)
    {
        $this->cache = $cache;
    }
    
    /**
     * 根據 ID 獲取訂單
     *
     * @param  int  $id
     * @return Order
     */
    public function find($id)
    {
        if ($this->cache->has($id)) {
            //
        }
    }
}

路由

默認路由文件

全部的路由文件都在routers目錄下,

routes/web.php文件定位web界面的路由,被分配給 web 中間件組提供了會話狀態和 CSRF 保護等功能

routes/api.php 中的路由都是無狀態的,而且被分配了 api 中間件組

路由經過 RouteServiceProvider 被嵌套到一個路由組裏面。

路由定義

基本路由

Route::get('/', function () {
    return view('welcome');
});

路由文件

Route::get('/user', 'UserController@index');

可用路由方法

Route::get($uri, $callback);
Route::post($uri, $callback);
Route::put($uri, $callback);
Route::delete($uri, $callback);
Route::options($uri, $callback);

Route::any($uri, $callback);
Route::patch($methods, $uri, $callback);

重定向

Route::redirect('/here', '/there');
Route::redirect('/here', '/there', 301);
Route::permanentRedirect('/here', '/there');

視圖路由

Route::view('/welcome', 'welcome');
Route::view('/welcome', 'welcome', ['name' => 'Taylor']);

參數路由

Route::get('user/{id}', function ($id) {
    return 'User '.$id;
});

Route::get('posts/{post}/comments/{comment}', function ($postId, $commentId) {
    //
});

可選參數路由/默認值路由

Route::get('user/{name?}', function ($name = null) {
    return $name;
});

Route::get('user/{name?}', function ($name = 'John') {
    return $name;
});

正則匹配參數路由

Route::get('user/{name}', function ($name) {
    //
})->where('name', '[A-Za-z]+');

Route::get('user/{id}/{name}', function ($id, $name) {
    //
})->where(['id' => '[0-9]+', 'name' => '[a-z]+']);

全局正則匹配配置方式

\app\Providers\RouteServiceProvider.php文件boot方法中添加

public function boot()
{
    Route::pattern('id', '[0-9]+');

    parent::boot();
}

路由別名

Route::get('user/profile', function () {
    //
})->name('profile');

//生成完整的url
$url = route('profile');

//別名路由重定向
return redirect()->route('profile');

中間件路由組

Route::middleware('auth:api')->get('/user', function (Request $request) {
    return $request->user();
});

命名空間路由組

Route::namespace('Admin')->group(function () {
    // 在 「App\Http\Controllers\Admin」 命名空間下的控制器
});

子域名路由組

Route::domain('{account}.zqw.xyz')->group(function () {
    Route::get('user/{id}', function ($account, $id) {
        //
    });
});

路由前綴

Route::prefix('admin')->group(function () {
    Route::get('users', function () {
        // 匹配包含 「/admin/users」 的 URL
    });
});

路由名稱前綴

Route::name('admin.')->group(function () {
    Route::get('users', function () {
        // 指定路由名爲 「admin.users」...
    })->name('users');
});

模型隱式綁定

Route::get('api/users/{user}', function (App\User $user) {
    return $user->email;
});
相關文章
相關標籤/搜索