PHP安裝php
https://www.php.net/downloads...nginx
安裝方式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
環境要求數據庫
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
。
vendor
:composer
依賴目錄。
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
註冊了全部的事件廣播頻道。
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]
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.php
和app/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
類,其中該類包含一個register
和boot
方法,其中register
方法中,只須要將服務綁定到服務容器中
經過artisan
命令行工具make:provider
生成一個新的提供者
php artisan make:provider RiakServiceProvider
服務提供者主要由兩個方法:register
和 boot
。register
只負責綁定一些東西到容器。boot
可使用類型提示解析等來完成任意你想作的事情,這些都歸功於容器調用全部服務提供者的register
方法以後纔去調用boot
方法。
在config/app.php
的providers
數組中註冊服務提供者。
若是你的服務提供者只在服務容器中註冊,能夠選着延遲加載該綁定直到註冊綁定的服務真的須要時在加載,延遲加載這樣的提供者提高應用的性能,由於它不是每次都在請求的時候進入加載
要延遲加載提供者,須要實現 \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]; } }
在 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'); });
# 原生用法 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 都可以用來構建健壯的、充分測試過的 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; });