第3章 應(yīng)用Laravel8 框架

3.1 ? ?上手 Laravel8
3.1.1 ? ?介紹
Lavavel 一直 秉承著優(yōu)雅的原則,很好的支持了 composer,實(shí)現(xiàn)了更豐富的擴(kuò)展,社區(qū)文檔活躍,相較于TP,Lavavel 更龐大,安全性也更高 ,更適合開發(fā)大中型項(xiàng)目,被稱為“巨匠型開發(fā)框架”。
優(yōu)點(diǎn):
Laravel 的設(shè)計(jì)思想是很先進(jìn)的,非常適合應(yīng)用各種開發(fā)模式 TDD, DDD 和 BDD。
支持composer包管理工具。
集合了php 比較新的特性,以及各種各樣的設(shè)計(jì)模式, Ioc 容器,依賴注入等。
缺點(diǎn):
基于組件式的框架,所以比較臃腫。
綜合來說:Laravel 框架非常適合大中型的商業(yè)項(xiàng)目。Laravel 是以組件化為主的框架。
3.1.2 ? ?安裝
終端行執(zhí)行以下命令 :
composer create-project --prefer-dist laravel/laravel blog
此處省略 執(zhí)行過程 :
注意:前提是符合框架基本要求,要求如下:
PHP >= 7.2.5
BCMath PHP 拓展
Ctype PHP 拓展
Fileinfo PHP 拓展
JSON PHP 拓展
Mbstring PHP 拓展
OpenSSL PHP 拓展
PDO PHP 拓展
Tokenizer PHP 拓展
XML PHP 拓展
安裝成功,在瀏覽器輸入 Laravel 框架的地址至 ?public
目錄訪問項(xiàng)目 :
3.1.3 ? ?目錄介紹
|--- app --- 應(yīng)用目錄
| |-- Console -- 命令行目錄
| |-- Exceptions -- 異常目錄
| |-- Http -- 網(wǎng)絡(luò)請(qǐng)求目錄
| |-- Providers -- 服務(wù)提供目錄
| |......
|--- bootstrap --- 啟動(dòng)目錄
| |-- cache -- 路由和服務(wù)緩存目錄
| |-- app.php -- 應(yīng)用啟動(dòng)文件
|--- config --- 應(yīng)用配置目錄
| |-- app.php -- 應(yīng)用配置文件
| |-- auth.php -- 認(rèn)證配置文件
| |-- broadcasting.php -- 廣播配置文件
| |-- cache.php -- 緩存配置文件
| |-- database.php -- 數(shù)據(jù)庫配置文件
| |......
|--- database --- 數(shù)據(jù)庫目錄
| |-- factories -- 模型工廠目錄
| |-- migrations -- 數(shù)據(jù)遷移目錄
| |-- seeds -- 種子目錄
| |......
|--- public --- 公共目錄
| |-- css -- 公共css目錄
| |-- js -- 公共js目錄
| |-- index.php -- 入口文件
|--- resources --- 資源目錄
| |-- lang -- 語言包目錄
| |-- sass -- sass目錄
| |-- views -- 模板目錄
|--- routes --- 路由目錄
| |-- api.php -- api路由定義
| |-- console.php -- 控制臺(tái)路由定義
| |-- web.php -- 網(wǎng)頁路由定義
|--- storage --- 存儲(chǔ)目錄
| |-- app -- 存儲(chǔ)應(yīng)用生成的文件
| |-- framework -- 存儲(chǔ)框架生成的文件和緩存
| |-- logs -- 存儲(chǔ)日志
|--- tests --- 單元測(cè)試目錄
|--- vendor --- 第三方類庫目錄
| |-- composer -- composer目錄
| |-- laravel -- laravel框架目錄
| |-- symfony -- symfony組件目錄
| |-- autoload.php -- 自動(dòng)加載入口文件
| |......
|--- .env --- 環(huán)境變量配置文件
|--- artisan --- artisan工具文件
|--- server.php --- 命令行應(yīng)用測(cè)試文件
|.........
核心目錄與文件
.env 文件
這是一個(gè)重要文件,為 Laravel 框架主配置文件。
Artisan.php
該文件為 Laravel 提供了 Artisan 命令,artisan是 laravel 中自帶的命令行工具的名稱。
App 目錄
你的大部分應(yīng)用程序都位于 app
目錄中。默認(rèn)情況下,此目錄的命名空間為 App
, 并通過 Composer 使用 自動(dòng)加載。
Bootstrap 目錄
bootstrap
目錄包含引導(dǎo)框架的 app.php
文件。該目錄還包含了一個(gè) cache
目錄, cache
目錄下存放著框架生成的用來提升性能的文件,比如路由和服務(wù)緩存文件。
Config 目錄
config
目錄,顧名思義,包含應(yīng)用程序所有的配置文件。我們鼓勵(lì)你通讀這些文件,以便幫助你熟悉所有可用的選項(xiàng)。
Public 目錄
public
目錄包含了入口文件 index.php
,它是進(jìn)入應(yīng)用程序的所有請(qǐng)求的入口點(diǎn)。此目錄還包含了一些你的資源文件(如圖片、JavaScript 和 CSS)。
Resources 目錄
resources
目錄包含了視圖和未編譯的資源文件(如 LESS、SASS 或 JavaScript)。此目錄還包含你所有的語言文件。
Routes 目錄
routes
目錄包含了應(yīng)用的所有路由定義,Laravel 默認(rèn)包含了幾個(gè)路由文件:web.php
、api.php
、 console.php
和 channels.php
。
Storage 目錄
storage
目錄包含編譯后的 Blade 模板、session 會(huì)話生成的文件、緩存文件以及框架生成的其他文件。這個(gè)目錄被細(xì)分成 app
、 framework
和 logs
三個(gè)子目錄。app
目錄可以用來存儲(chǔ)應(yīng)用生成的任何文件。 framework
目錄用來存儲(chǔ)框架生成的文件和緩存。最后, logs
目錄包含應(yīng)用的日志文件。
3.2 ? ?Laravel 8 請(qǐng)求與響應(yīng)
3.2.1 ? ?控制器
在路由文件中我們可以寫入很多的處理邏輯,但是當(dāng)邏輯越來越多單純的使用路由文件來編寫就會(huì)使得路由文件越來越大,并且負(fù)責(zé)的職責(zé)也會(huì)越來越多。對(duì)于面向?qū)ο蟮脑O(shè)計(jì)來說是很不合理的,所這里會(huì)給予一個(gè)控制器組織這些行為??刂破髂軐⑾嚓P(guān)的請(qǐng)求處理邏輯組成一個(gè)單獨(dú)的類,控制器被存放在 app/Http/Controllers
目錄。
1. 基礎(chǔ)控制器
控制器都會(huì)放在 app\Http\Controllers 目錄下面,在其中已經(jīng)存在了一個(gè) Controller.php 文件,我們可以在其中創(chuàng)建一個(gè) index 方法,通過路由來執(zhí)行該方法 :
Controller 文件:app\Http\Controllers\Controller.php
<?php
namespace App\Http\Controllers;
# ......
class Controller extends BaseController
{
? ?# ......
? ?public function index()
? ?{
? ? ? ?return '我是控制器';
? ?}
}
路由文件:routes\web.php
<?php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\Controller;
Route::get('index',[Controller::class,'index']);
結(jié)果 :

這個(gè)就是控制器,只是一般我們把這個(gè)控制器作為父類控制器來使用,接下來就要自力更生創(chuàng)建和使用自定義的控制器了。
2. 自定義控制器
首先可以施展我們的 cv 打法來創(chuàng)建自己的控制器。直接復(fù)制 Controller.php 文件到當(dāng)前目錄更名,也可以到子目錄,記得修改子目錄下的控制器的命名空間。例如,復(fù)制 Controller.php 控制器更名為 HelloController.php
HelloController 控制器:app\Http\Controllers\HelloController.php
<?php
namespace App\Http\Controllers;
class HelloController extends Controller
{
? ?public function index()
? ?{
? ? ? ?return '我是 HelloController 控制器';
? ?}
}
路由 :
use App\Http\Controllers\HelloController;
Route::get('hello', ,[HelloController::class,'index']);
結(jié)果 :

這樣我們創(chuàng)建的控制器就能正常使用了,之后我們講另一種方式來創(chuàng)建控制器并說明命名空間。
3. 命令創(chuàng)建控制器
Laravel 框架給我們提供了命令來創(chuàng)建控制器,命令為 :
php artisan make:controller 控制器名稱
創(chuàng)建的控制器默認(rèn)創(chuàng)建在 Controllers 下,如果需要?jiǎng)?chuàng)建子目錄下的控制器呢?我們需要加入子目錄名稱。例如在 Controllers/Admin 目錄下面創(chuàng)建 IndexController 控制器 :
php artisan make:controller Admin/IndexController
注意,目錄和控制器中間要使用 \
分割,其目錄為 :

在其中創(chuàng)建一個(gè) index 方法【內(nèi)容任意,這里就不多寫了】,創(chuàng)建訪問該方法的路由為 :
use app\Http\Controllers\Admin\IndexController;
Route::get('admin', [IndexController::class,'index']);
通過 blog.com/admin 訪問可以成功訪問到 index
方法。
4. 單行為控制器
以上創(chuàng)建的控制器都是最基礎(chǔ)的控制器,加下來我們?cè)賮砜磶讉€(gè)特殊的控制器。首先就是單行為控制器,那么什么是單行為控制器呢?單行為控制器是 一個(gè)只處理單個(gè)行為的控制器,其創(chuàng)建命令為 :
php artisan make:controller 控制名稱 --invokable
根據(jù)命令我們來創(chuàng)建一個(gè)單行為控制器,該控制器為 Admin/SingleBeController.php ,那么他和普通控制器的區(qū)別和特點(diǎn)主要是什么呢?首先來看看生成的控制器 :
SingleBeController控制器:app\Http\Controllers\Admin\SingleBeController.php
<?php
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
class SingleBeController extends Controller
{
? ?# 默認(rèn)生成的方法
? ?public function __invoke(Request $request)
? ?{
? ? ? ?return '單行為控制器';# 編寫其中的唯一存在的方法
? ?}
}
接下來對(duì)該方法編寫一個(gè)路由 :
Route::get('sbc', 'Admin\SingleBeController@__invoke');
訪問的結(jié)果為 :

如果僅僅是這樣的話那么就沒有必要使用單一行為控制器了,這時(shí)候我們可以這樣來創(chuàng)建路由:
Route::get('sbc', 'Admin\SingleBeController');
通過上 URL 來訪問能夠得到同樣的結(jié)果,也就是說 單行為控制器只需要 控制器名稱 即可默然訪問到 __invoke
方法,而這個(gè)控制器也只用來實(shí)現(xiàn)一個(gè)方法。
注意:并不是說單行為控制器中不能創(chuàng)建其他方法或者不能訪問,而是作為單一行為控制器其特點(diǎn)是只實(shí)現(xiàn)一個(gè)功能,體現(xiàn)面向?qū)ο蟮膯我宦氊?zé)。
5. 資源控制器
除了單行為控制器之外還有一個(gè) 資源控制器,其特點(diǎn)是該控制器會(huì)創(chuàng)建一個(gè)符合 restful 規(guī)范的控制器,并且可以典型的「CURD (增刪改查)」路由分配給控制器。說起來會(huì)有點(diǎn)懵,我們結(jié)合代碼來看看其特點(diǎn)。
(1)創(chuàng)建資源控制器
首先我們通過命令創(chuàng)建資源控制器 :
php artisan make:controller Admin\ResourceController --resource
Admin\ResourceController 是控制器名稱,自行定義。
(2)資源路由功能測(cè)試
創(chuàng)建成功后會(huì)出現(xiàn)一個(gè)控制器,其中會(huì)存在一些已經(jīng)存在的方法,例如:index,create,store 等,具體的可以自行創(chuàng)建一個(gè)資源控制器查看,其中方法是一樣的。接下來對(duì)其中的方法進(jìn)行編寫:
ResourceController 控制器:app\Http\Controllers\Admin\ResourceController.php
<?php
namespace App\Http\Controllers\Admin;
class ResourceController extends Controller
{
? ?# 其他代碼省略 測(cè)試使用
? ?public function index()
? ?{
? ? ? ?return '資源控制器的 index 方法';
? ?}
? ?public function store(Request $request)
? ?{
? ? ? ?return '資源控制器的 store 方法';
? ?}
? ?public function show($id)
? ?{
? ? ? ?return '資源控制器的 show 方法';
? ?}
}
(3)路由編寫
既然單行為控制器對(duì)路由有特殊點(diǎn),那么資源控制器自然也有,這里就不賣關(guān)子了,我們直接來看其特點(diǎn):
先創(chuàng)建一個(gè)該控制器的路由,這里需要注意的是調(diào)用的方法不再是 get 等之類的,而需要通過 resource 創(chuàng)建:
use app\Http\Controllers\Admin\ResourceController;
Route::resource('resource', ResourceController::class);
同樣,創(chuàng)建出來的路由地址不需要的接具體的某個(gè)方法,那么我們是如何訪問到具體的方法的呢?繼續(xù)往下看。
(4)測(cè)試
資源控制器:通過不同的方式以及改變?cè)L問時(shí)添加的參數(shù)來進(jìn)行訪問,我們會(huì)發(fā)現(xiàn)訪問到的會(huì)是不同的方法 :

以上是通過 get 方式以及添加參數(shù)訪問的,分別訪問到了 index 方法和 show 方法,其他的方法可以自行測(cè)試,其具體訪問的是什么方法參照下表 :
(5)資源控制器操作處理

單行為控制器主要體現(xiàn)單一職責(zé),一個(gè)類只實(shí)現(xiàn)一個(gè)方法。而資源控制器則是規(guī)范了開發(fā)的方法并且為預(yù)先為我們創(chuàng)建了一系列路由,可以快速訪問,提升開發(fā)效率。
(6)控制器中間件
在路由中我們初步認(rèn)識(shí)并且創(chuàng)建了中間件,而這里雖然有一個(gè)叫做 控制器中間件
的東西存在,但是其本質(zhì)就是中間件,只是使用的地方放到了控制器當(dāng)中。接下來就來看看在控制器中如何使用中間件的【這里就不重復(fù)對(duì)中間件進(jìn)行說明了】。
(7)在路由文件中分配給控制器的路由
上一篇中我們直接通過路由組進(jìn)行中間件的分配,而給控制器使用的中間件也可以直接通過路由來給定到某個(gè)控制器,這里我們需要在路由的后面借助 middleware
方法來實(shí)現(xiàn),例如 :
Route::get('midd', [IndexController::class,'index'])->middleware('first');# 分配 first 中間件給 IndexController 控制器使用
這種方式分配的中間件對(duì)該控制器中的所有方法都會(huì)生效。
(8) 在控制器的構(gòu)造函數(shù)中指定中間件
在控制器的構(gòu)造函數(shù)中指定中間件更為方便。在控制器的構(gòu)造函數(shù)中使用 middleware
方法,可以輕松地將中間件分配給控制器的操作,例如 :
<?php
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
class IndexController extends Controller
{
? ?public function __construct()
? ?{
? ? ? ?$this->middleware('first');# 對(duì)當(dāng)前控制器下所有的方法都使用該中間件, 如果使用多個(gè)中間件可以使用數(shù)組
? ?}
? ?public function index()
? ?{
? ? ? ?return 'IndexController 下的 index';
? ?}
? ?public function hello()
? ?{
? ? ? ?return 'IndexController 下的 hello';
? ?}
}
如果需要限定中間件分配的方法,還可以在 middleware 方法鏈?zhǔn)秸{(diào)用 only
或者 ?except
方法 :
$this->middleware('first')->only('index');# 只對(duì)該方法生效
# 或者
$this->middleware('first')->except('index');# 除了該方法,其他方法都生效
這樣就能限定中間件生效的方法了。
6. 依賴注入
要通過依賴注入獲取當(dāng)前 HTTP 請(qǐng)求實(shí)例,你應(yīng)該在控制器上引入 Illuminate\Http\Request
類。傳入的請(qǐng)求實(shí)例將會(huì)由服務(wù)容器自動(dòng)注入 :
依賴注入:只要不是由內(nèi)部生產(chǎn)(比如初始化、構(gòu)造函數(shù)
__construct
中通過自行手動(dòng) new 的),而是由外部以參數(shù)或其他形式注入的,都屬于 依賴注入(DI)。
# 其他代碼不變 ?這里使用依賴注入方式
public function login(Request $request)
{
? ?$user = $request->input();# 獲取到的是一個(gè)數(shù)組,
? ?dd($user);
}
結(jié)果 :

從結(jié)果我們可以看到,設(shè)置的數(shù)據(jù)通過 request 請(qǐng)求對(duì)象成功獲取到了。那么為什么依賴注入可以實(shí)現(xiàn)數(shù)據(jù)的獲取而自己創(chuàng)建實(shí)例則無法獲取呢?那么就要具體的看看什么是依賴注入了,我們來 擴(kuò)展一點(diǎn)東西 :
<?php
# 車類 - 給人類使用
class Car
{
? ?public $color;
? ?public $type;
}
# 人類 - 調(diào)用車類
class Person
{
? ?# 1.依賴注入方式
? ?public function drive(Car $car)
{
? ?$color = $car->color;
? ?$type = $car->type;
? ?echo "開 $color 的 $type ";
}
# ---------------------------------
# 2.手動(dòng)創(chuàng)建方式
public function drive()
{
? ?$car = new Car();
? ?$color = $car->color;
? ?$type = $car->type;
? ?echo "開 $color 的 $type ";
}
}
# 1.依賴注入
$car = new Car();# 創(chuàng)建車類對(duì)象并對(duì)原有屬性賦值
$car->color = '白色';
$car->type = '小轎車';
(new Person())->drive($car);# 傳遞被修改過的對(duì)象
# 結(jié)果:開 白色 的 小轎車
# 2.手動(dòng)創(chuàng)建
(new Person())->drive();# 在人類中創(chuàng)建車類對(duì)象,不再外部傳遞
# 結(jié)果:開 的
注意:從上面的結(jié)果來看,我們可以看出新創(chuàng)建的對(duì)象無法和其他對(duì)象共有同一屬性值,所以如果我們需要使用之前保存在對(duì)象中的內(nèi)容就需要通過注入的方式傳遞對(duì)象而不能重新創(chuàng)建。
除了通過 依賴注入
以外,我們還可以使用 門面
和 助手函數(shù)
。
7. 門面靜態(tài)調(diào)用
要通過門面調(diào)用請(qǐng)求數(shù)據(jù),你應(yīng)該在控制器上引入 use Illuminate\Support\Facades\Request
類 :
<?php
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Request;# 這里是需要重點(diǎn)注意的地方,和依賴注入所引用的不是同一個(gè)
class IndexController extends Controller
{
? ?public function login()
? ?{
? ? ? ?$user = Request::input();
? ? ? ?dump($user);
? ?}
}
結(jié)果就不再展示,同樣可以獲取到數(shù)據(jù)。
需要注意的是: 通過門面方式調(diào)用時(shí),引入的是
Illuminate\Support\Facades\Request
而通過依賴注入方式引入的則是Illuminate\Http\Request
。
8. 助手函數(shù)
Laravel 框架為我們提供了很多助手函數(shù)方便我們直接使用,request 函數(shù)就是其中之一,它可以幫助我們快速的獲取到 request 對(duì)象。
<?php
namespace App\Http\Controllers\Admin;
class IndexController extends Controller
{
? ?public function login()
? ?{
? ? ? ?$user = \request()->input();
? ? ? ?dump($user);
? ?}
}
通過助手函數(shù)不需要引入什么類,直接通過 request()
函數(shù)調(diào)用即可。
請(qǐng)求方法
既然框架給我們提供了一個(gè)請(qǐng)求對(duì)象,那么在其中也會(huì)給我們提供一系列已經(jīng)準(zhǔn)備好的方法給我們來使用,方便我們操作。首先來看看我們上面已經(jīng)接觸到的輸入數(shù)據(jù)的獲取。
獲取輸入
(1)input
上面已經(jīng)接觸到了 input
方法,從結(jié)果可以看出 其返回值是一個(gè)包含所有數(shù)據(jù)的鍵值對(duì)數(shù)組 - 獲取所有數(shù)據(jù) ,那么能不能傳遞鍵到 input
中直接獲取需要的值呢?來嘗試一下 :
$name = \request()->input('name');
dump($name);
結(jié)果:

可以看出我們是可以直接傳遞 key
從而獲取對(duì)應(yīng)的值的。
(2)all
和 input
方法比較類似的還有一個(gè) all
方法,其作用也是獲取所有數(shù)據(jù),其不同點(diǎn)就在于 獲取單個(gè)數(shù)據(jù)的時(shí)候,其返回的結(jié)果還是數(shù)組 :
$user = \request()->all();
dump($user);
結(jié)果:

(3)only 與 except
有時(shí)候我們可能 不需要的這么多的數(shù)據(jù),只需要其中的幾個(gè)即可 ,Laravel 框架的請(qǐng)求對(duì)象也很貼心的給我們創(chuàng)建了 only 與 except 兩個(gè)方法來實(shí)現(xiàn) :
$name = \request()->only('name');# 只獲取的數(shù)據(jù),多個(gè)數(shù)據(jù)可以通過數(shù)組傳遞
dump($name);
$name = \request()->except('name');# 只獲取的數(shù)據(jù),多個(gè)數(shù)據(jù)可以通過數(shù)組傳遞
dump($name);
結(jié)果分別是 :
array:1 [
?"name" => "jack"
]
array:1 [
?"password" => "123456"
]
另外還有一種 通過屬性直接獲取的方式,我們可以看看 :
$name = \request()->name;
dump($name);
結(jié)果 :

如果需要獲取過來的數(shù)據(jù),我們可以使用上面的幾種方式來獲取。
3.2.2 ? ?路由
1. 了解路由
路由 (route) 是指根據(jù) url, 分配到對(duì)應(yīng)的處理程序的映射。簡(jiǎn)單來說,就是一個(gè)路徑的解析,根據(jù)客戶端提交的路徑,將請(qǐng)求解析到相應(yīng)的 模塊/控制器/方法上。
這里我們先來看一個(gè) Laravel 中已經(jīng)存在的一個(gè)路由 :
Route::get('/', function () {
? ?return view('welcome');
});
設(shè)置一個(gè)域名來訪問該框架,訪問到該路由的 URL 為:blog.coms;上面這個(gè)路由是以 /
為 標(biāo)識(shí),無法很好的體現(xiàn)路由標(biāo)識(shí)的特性,我們可以根據(jù)該路由來編寫一個(gè)自己的路由 :
# 路由方法 ?路由標(biāo)識(shí) ?閉包
Route::get('base', function(){
? ?return '第一個(gè)路由';
});
# 也可以路由到控制器:路由到 app\Http\Controllers\HelloController 控制器的 Hello 方法
Route::get('Hello', 'HelloController@hello');
無論怎么去定義路由,最基礎(chǔ)的就是需要根據(jù)路由標(biāo)識(shí)找到對(duì)應(yīng)的路由地址 ,也就是說路由必須存在 路由標(biāo)識(shí)
以及 路由地址
,也就是所有的路由都符合以下方式 :
Route : : 路由方法 ( 路由標(biāo)識(shí), 路由地址 ) ;
2. 路由方法
路由器允許你注冊(cè)能響應(yīng)任何 HTTP 請(qǐng)求的路由,在 ?Laravel 框架中主要包括以下方法 :
Route::get($uri, $callback);
Route::post($uri, $callback);
Route::put($uri, $callback);
Route::patch($uri, $callback);
Route::delete($uri, $callback);
Route::options($uri, $callback);
3. 重定向路由
如果要定義重定向到另一個(gè) URI 的路由,可以使用 Route::redirect
方法。這個(gè)方法可以快速的實(shí)現(xiàn)重定向,而不再需要去定義完整的路由或者控制器 :
Route::redirect('重定向路由標(biāo)識(shí)','路由標(biāo)識(shí)');// 路由重定向
# 重定向路由
Route::redirect('redirect', 'base');
4. 路由參數(shù)
有時(shí)路由需要一些變量來改變?cè)竟潭ǖ膬?nèi)容,我們可以通過捕獲一些 URL 片段來實(shí)現(xiàn),而這些可以被我們捕獲到的片段就是路由的參數(shù),路由參數(shù)可以在原本的 URL 后面加上即可,那么我們?nèi)绾伪硎疚覀兊穆酚墒切枰獏?shù)的呢 ?
如果要表示某個(gè)路由需要給定參數(shù),我們可以使用 {參數(shù)名稱} 來表示,例如 :
# user 是路由標(biāo)識(shí),{id} 則是該路由需要的參數(shù)
Route::get('user/{id}', function ($id) {
? ?return 'User '.$id;
});
3.2.3 ? ?CSRF
Laravel 提供應(yīng)用程序免受
(CSRF)攻擊。 跨站點(diǎn)請(qǐng)求偽造是一種惡意攻擊,它憑借已通過身份驗(yàn)證的用戶身份來運(yùn)行未經(jīng)過授權(quán)的命令。Laravel 會(huì)自動(dòng)為每個(gè)活躍的用戶的會(huì)話生成一個(gè) CSRF「令牌」。該令牌用于驗(yàn)證經(jīng)過身份驗(yàn)證的用戶是否是向應(yīng)用程序發(fā)出請(qǐng)求的用戶。
在應(yīng)用程序中定義 HTML 表單時(shí),都應(yīng)該在表單中包含一個(gè)隱藏的 CSRF 標(biāo)記字段,以便 CSRF 保護(hù)中間件可以驗(yàn)證該請(qǐng)求,你可以使用 @csrf
Blade 指令來生成令牌字段,如下 :
<form method="POST" action="/profile">
? ?@csrf
? ?...
</form>
CSRF 保護(hù):指向
web
路由文件中定義的POST
、PUT
或DELETE
路由的任何 HTML 表單都應(yīng)該包含一個(gè) CSRF 令牌字段,否則,這個(gè)請(qǐng)求將會(huì)被拒絕。
步驟:打開 app\Http\Kernel.php 文件,注釋掉其中的 VerifyCsrfToken
中間件 :

接下來再切換方式訪問就可以成功訪問到了。

需要注意的是 match 方法只能訪問到被設(shè)定的方式,any 方法能訪問到 larave 設(shè)置的任意一種方式。
路由白名單
除了上述方式能實(shí)現(xiàn)除 非 get 方式 也能被訪問以外,我們還可以給路由添加白名單。
首先還原我們剛剛注釋的內(nèi)容。被注釋的其實(shí)是一個(gè) 中間件
【在執(zhí)行代碼得到結(jié)果之前運(yùn)行的類文件,可以起到過濾作用】,根據(jù)該類的地址我們可以找到位于 app\Http\Middleware 下的 VerifyCsrfToken.php 文件。而注釋掉該中間件則是去掉該中間件的過濾作用,為了安全我們可以只對(duì)我們認(rèn)可的中間件解除過濾,該中間件就提供了一個(gè)白名單的功能來實(shí)現(xiàn)。
添加白名單
添加白名單的步驟很簡(jiǎn)單,在該中間件中我們可以看到其中存在一個(gè) $except
屬性,把我們信任的路由標(biāo)識(shí)寫入其中即可,例如 ,白名單添加 :

通過 post 方式訪問 match 標(biāo)識(shí)的結(jié)果 :

注意:這里是已經(jīng)去掉了
app\Http\Kernel.php
文件中該中間件的注釋,否則不是白名單起到作用,而是該中間件沒有使用 。
3.2.4 ? ?視圖
1. 理解視圖
前面的內(nèi)容中,我們都會(huì)把代碼實(shí)現(xiàn)的內(nèi)容都通過瀏覽器或相關(guān)工具顯示出來,而框架則給我們提供了視圖來對(duì)這些數(shù)據(jù)進(jìn)行渲染顯示。Blade
是 Laravel
提供的一個(gè)簡(jiǎn)單而又強(qiáng)大的 模板引擎
。和其他流行的 PHP 模板引擎不同,Blade 并不限制你在視圖中使用原生 PHP 代碼。所有 Blade 視圖文件都將被編譯成原生的 PHP 代碼并緩存起來,除非它被修改,否則不會(huì)重新編譯。
使用視圖我們還可以得到以下好處 :
可以制定用戶需求的數(shù)據(jù),而不用看一些無用的其他數(shù)據(jù)。
對(duì)其他的數(shù)據(jù)有一定保護(hù)左右,當(dāng)前用戶只能查看到自己需要的數(shù)據(jù),如果沒有權(quán)限則無法查看其他數(shù)據(jù),起到一定保護(hù)作用。
使用戶的操作變得簡(jiǎn)單,復(fù)雜的操作只需要視圖中的一些按鈕或操作就能實(shí)現(xiàn)。
對(duì)復(fù)雜的數(shù)據(jù)進(jìn)行分離渲染顯示,不用再在眾多的數(shù)據(jù)中查找自己需要的部分。
剛安裝的框架給我們準(zhǔn)備好一個(gè)視圖文件,而該文件存放于 resources\views 目錄下。路由中返回的 view('welcome') 則是找到該視圖文件,welcome
則是視圖的名稱。
2. 創(chuàng)建視圖
resources\views 目錄下創(chuàng)建 index.blade.php 的視圖文件,輸入任意內(nèi)容,創(chuàng)建該視圖對(duì)應(yīng)的路由 :
Route::get('view', function () {
? ?return view('index');
});
3. 訪問視圖
從控制器訪問到視圖文件。首先在 View 目錄下創(chuàng)建一個(gè) IndexController 控制器 :
namespace App\Http\Controllers\View;
use App\Http\Controllers\Controller;
class IndexController extends Controller
{
? ?public function index()
? ?{
return view('index');# 與路由中使用效果一樣
? ?}
}
路由 :
Route::get('index', 'View\IndexController@index');
4. view 函數(shù)
從控制器訪問到視圖文件。首先在 View 目錄下創(chuàng)建一個(gè) IndexController 控制器 :
namespace App\Http\Controllers\View;
use App\Http\Controllers\Controller;
class IndexController extends Controller
{
? ?public function index()
? ?{
return view('index');# 與路由中使用效果一樣
? ?}
}
5. 視圖方法
exists:exists
方法的作用是 判斷視圖文件是否存在,可以通過 view 對(duì)象調(diào)用,如果存在,exists
方法會(huì)返回 true
。
return view()->exists('index');
因?yàn)槲覀円呀?jīng)創(chuàng)建了 index
視圖,所以結(jié)果是 true
。
share:share
方法的作用是 與所有視圖共享數(shù)據(jù)。有時(shí)候,你可能需要共享一段數(shù)據(jù)給應(yīng)用程序的所有視圖。 你可以在 app\Providers\AppServiceProvider.php
的 boot
方法中調(diào)用視圖門面(Facade)的 share
方法。例如 :
AppServiceProvider 文件:app\Providers\AppServiceProvider.php
namespace App\Providers;
use Illuminate\Support\Facades\View;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
? ?public function boot()
? ?{
View::share(['color'=>'yellow']);
? ?}
}
3.3 ? ?Laravel 8 數(shù)據(jù)庫操作
數(shù)據(jù)庫的配置文件在 config/database.php
文件中,你可以在這個(gè)文件中定義所有的數(shù)據(jù)庫連接配置,并指定默認(rèn)的數(shù)據(jù)庫連接。這個(gè)文件中提供了大部分 Laravel 能夠支持的數(shù)據(jù)庫配置示例。
基本操作 :
原生語句
#\Illuminate\Support\Facades\DB 下面使用DB
DB::select(原生curd的sql語句);
新增操作
DB::table('表名')->insert(數(shù)據(jù));
例:
DB::table('test')->insert(['name'=>'sixsatr','age'=>5]);
改
DB::table('表名')->where(條件)->update(數(shù)據(jù));
例:
DB::table('tests')->where('id',1)->update($data);
#返回的是影響的條數(shù)。
刪
DB::table('表名')->where(條件)->delete();
例:
DB::table('tests')->where('id',3)->delete();
# 返回的是條數(shù)
查
#獲取所有數(shù)據(jù)
DB::table('tests')->get();
#獲取具體字段
DB::table('tests')->value('name');
#獲取一列
DB::table('tests')->pluck('name');
聚合
$users = DB::table('tests')->count();
$users = DB::table('tests')->avg('age');
$users = DB::table('tests')->max('age');
連接查詢
DB::table('test')
? ?# ? ?關(guān)聯(lián)表名稱 ?本表主鍵 ?比較符 ?關(guān)聯(lián)表外鍵
? ?->join('test1','test.id','=','test1.id')
? ?->where('test.name','sixstar')
? ?->get();
3.4 ? ?laravel8 核心功能
3.4.1 ? ?容器概述
1 . 服務(wù)容器
服務(wù)容器 以字面意思可以分解為兩個(gè)部分來理解,分別是服務(wù)與容器。
2 . 什么是 服務(wù)容器
首先看看什么是 服務(wù),任何一個(gè)功能,任務(wù)都可以叫做服務(wù) service。所以說功能類對(duì)象,就是服務(wù)。
再看 容器,我們有許許多多的東西需要放在一起,而裝這些東西的就是一個(gè)容器。一個(gè)容器能夠裝什么,全部取決于你對(duì)該容器的定義。
當(dāng)我們 容器中存儲(chǔ)的不是其他東西而是服務(wù) 的話,那么這個(gè)容器就稱為 服務(wù)容器 了。從此來看服務(wù)容器就是用來存放 對(duì)象、對(duì)象的描述(類、接口)或者是提供對(duì)象的回調(diào)等功能。而通過服務(wù)容器可以很好的降低代碼間的耦合度。
3 . 服務(wù)綁定
你也可以使用 instance
方法將現(xiàn)有對(duì)象實(shí)例綁定到容器中。給定的實(shí)例會(huì)始終在隨后的調(diào)用中返回到容器中 :
$test = new Test();
$this->app->instance('test', $test);
4 . 綁定接口到實(shí)現(xiàn)
服務(wù)容器有一個(gè)很強(qiáng)大的功能,就是支持綁定接口到給定的實(shí)現(xiàn)。例如,如果我們有個(gè) EventPusher
接口 和一個(gè) RedisEventPusher
實(shí)現(xiàn)。一旦我們寫完了 EventPusher
接口的 RedisEventPusher
實(shí)現(xiàn),我們就可以在服務(wù)容器中注冊(cè)它,像這樣 :
$this->app->bind(
? ?'App\Contracts\Test',
? ?'App\Services\Test'
);
5. 解析實(shí)例
通過上述方式能成功把服務(wù)保存到容器中,但是如何從容器中獲取存入的服務(wù)呢?這時(shí)可以使用以下幾種方式實(shí)現(xiàn)服務(wù)對(duì)象的獲取,可以稱之為解析實(shí)例。
6. make 方法
你可以使用 make
方法從容器中解析出類實(shí)例。 make
方法接收你想要解析的類或接口的名字 :
$api = $this->app->make('test');
7. resolve 方法
如果你的代碼處于無法訪問 $app
變量的位置,則可用全局輔助函數(shù) resolve
來解析 :
$api = resolve('test');
3.4.2 ? ?服務(wù)提供者
服務(wù)容器以及存在并且我們可以存入和取出這些服務(wù),那么這些服務(wù)由誰來管理呢?答案是服務(wù)提供者。
1 . 服務(wù)提供者作用
服務(wù)提供者是所有 Laravel 應(yīng)用程序的引導(dǎo)中心。你的應(yīng)用程序,以及 通過服務(wù)器引導(dǎo)的 Laravel 核心服務(wù)都是通過服務(wù)提供器引導(dǎo)【注冊(cè)】。
但是,「引導(dǎo)」是什么意思呢? 通常,我們可以理解為注冊(cè),比如注冊(cè)服務(wù)容器綁定,事件監(jiān)聽器,中間件,甚至是路由。服務(wù)提供者是配置應(yīng)用程序的中心。
當(dāng)你打開 Laravel 的 config/app.php
文件時(shí),你會(huì)看到 providers
數(shù)組。數(shù)組中的內(nèi)容是應(yīng)用程序要加載的所有服務(wù)提供者的類。當(dāng)然,其中有很多 「延遲」 提供者,他們并不會(huì)在每次請(qǐng)求的時(shí)候都加載,只有他們的服務(wù)實(shí)際被需要時(shí)才會(huì)加載。
2 . 編寫服務(wù)提供者
所有的服務(wù)提供者都會(huì)繼承 Illuminate\Support\ServiceProvider
類。 大多服務(wù)提供者都包含一個(gè) register
和一個(gè) boot
方法。在 register
方法中, 你只需要將服務(wù)綁定到服務(wù)容器。而不要嘗試在 register
方法中注冊(cè)任何監(jiān)聽器,路由,或者其他任何功能。
想要?jiǎng)?chuàng)建一個(gè)服務(wù)提供者可以通過 make:provider
命令可以生成 :
php artisan make:provider RiakServiceProvider
3 . 注冊(cè)方法
在 register
方法中,你只需要將服務(wù)綁定到服務(wù)容器中。讓我們來看一個(gè)基礎(chǔ)的服務(wù)提供者。在任何服務(wù)提供者方法中,你可以通過 $app
屬性來訪問服務(wù)容器 :
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use App\Utils\Test\Test;
class RiakServiceProvider extends ServiceProvider
{
? ?/**
? ? * 注冊(cè)應(yīng)用服務(wù)
? ? *
? ? * @return void
? ? */
? ?public function register()
? ?{
? ? ? ?$this->app->singleton(Connection::class, function ($app) {
? ? ? ? ? ?return new Test();
? ? ? ?});
? ?}
}
bindings
和 singletons
的特性
如果你的服務(wù)提供器注冊(cè)了許多簡(jiǎn)單的綁定,你可能想用 bindings
和 singletons
屬性替代手動(dòng)注冊(cè)每個(gè)容器綁定。當(dāng)服務(wù)提供器被框架加載時(shí),將自動(dòng)檢查這些屬性并注冊(cè)相應(yīng)的綁定 :
<?php
namespace App\Providers;
use App\Contracts\DowntimeNotifier;
use App\Contracts\ServerProvider;
use App\Services\DigitalOceanServerProvider;
use App\Services\PingdomDowntimeNotifier;
use App\Services\ServerToolsProvider;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
? ?/**
? ? * 設(shè)定所有的容器綁定的對(duì)應(yīng)關(guān)系
? ? *
? ? * @var array
? ? */
? ?public $bindings = [
? ? ? ?ServerProvider::class => DigitalOceanServerProvider::class,
? ?];
? ?/**
? ? * 設(shè)定所有的單例模式容器綁定的對(duì)應(yīng)關(guān)系
? ? *
? ? * @var array
? ? */
? ?public $singletons = [
? ? ? ?DowntimeNotifier::class => PingdomDowntimeNotifier::class,
? ? ? ?ServerToolsProvider::class => ServerToolsProvider::class,
? ?];
}
4 . 注冊(cè)服務(wù)提供者
所有服務(wù)提供者都是通過配置文件 config/app.php
進(jìn)行注冊(cè)。該文件包含了一個(gè)列出所有服務(wù)提供者名字的 providers
數(shù)組,默認(rèn)情況下,其中列出了所有核心服務(wù)提供者,這些服務(wù)提供者啟動(dòng) Laravel 核心組件,比如郵件、隊(duì)列、緩存等等。
要注冊(cè)提供器,只需要將其添加到數(shù)組 :
'providers' => [
? ?// 其他服務(wù)提供者
? ?App\Providers\TestServiceProvider::class,
],
延遲提供者
如果你的服務(wù)提供者只在服務(wù)容器中注冊(cè),可以選擇延遲加載該綁定直到注冊(cè)綁定的服務(wù)真的需要時(shí)再加載,延遲加載這樣的一個(gè)提供者將會(huì)提升應(yīng)用的性能,因?yàn)樗粫?huì)在每次請(qǐng)求時(shí)都從文件系統(tǒng)加載。
Laravel 編譯并保存延遲服務(wù)提供者提供的所有服務(wù)的列表,以及其服務(wù)提供者類的名稱。因此,只有當(dāng)你在嘗試解析其中一項(xiàng)服務(wù)時(shí),Laravel 才會(huì)加載服務(wù)提供者。
要延遲加載提供者,需要實(shí)現(xiàn) \Illuminate\Contracts\Support\DeferrableProvider
接口并置一個(gè) provides
方法。這個(gè) provides
方法返回該提供者注冊(cè)的服務(wù)容器綁定 :
<?php
namespace App\Providers;
use Illuminate\Contracts\Support\DeferrableProvider;
use Illuminate\Support\ServiceProvider;
use App\Utils\Test\Test;
class RiakServiceProvider extends ServiceProvider implements DeferrableProvider
{
? ?/**
? ? * 注冊(cè)服務(wù)提供者。
? ? *
? ? * @return void
? ? */
? ?public function register()
? ?{
? ? ? ?$this->app->singleton(Test::class, function () {
? ? ? ? ? ?return new Test();
? ? ? ?});
? ?}
? ?/**
? ? * 獲取由提供者提供的服務(wù)。
? ? *
? ? * @return array
? ? */
? ?public function provides()
? ?{
? ? ? ?return [Test::class];
? ?}
}
3.4.3 ? ?Facade
Facades 為應(yīng)用的 服務(wù)容器 提供了一個(gè)「靜態(tài)」 接口。Laravel 自帶了很多 Facades,可以訪問絕大部分功能。Laravel Facades 實(shí)際是服務(wù)容器中底層類的 「靜態(tài)代理」 ,相對(duì)于傳統(tǒng)靜態(tài)方法,在使用時(shí)能夠提供更加靈活、更加易于測(cè)試、更加優(yōu)雅的語法。
1 . Facades 使用
所有的 Laravel Facades 都定義在 Illuminate\Support\Facades
命名空間下。所以,我們可以輕松的使用 Facade :
use Illuminate\Support\Facades\Cache;
Route::get('/cache', function () {
? ?return Cache::get('key');
});
2 . Facades 工作原理
在 Laravel 應(yīng)用中,F(xiàn)acade 就是一個(gè)可以從容器訪問對(duì)象的類。其中核心的部件就是 Facade
類。不管是 Laravel 自帶的 Facades,還是自定義的 Facades,都繼承自 Illuminate\Support\Facades\Facade
類。
Facade
基類使用了__callStatic()
魔術(shù)方法,直到對(duì)象從容器中被解析出來后,才會(huì)進(jìn)行調(diào)用 :
namespace Illuminate\Support\Facades;
abstract class Facade
{
/**
? ? * Handle dynamic, static calls to the object.
? ? *
? ? * @param ?string ?$method
? ? * @param ?array ?$args
? ? * @return mixed
? ? *
? ? * @throws \RuntimeException
? ? */
? ?public static function __callStatic($method, $args)
? ?{
? ? ? ?$instance = static::getFacadeRoot();
? ? ? ?if (! $instance) {
? ? ? ? ? ?throw new RuntimeException('A facade root has not been set.');
? ? ? ?}
? ? ? ?return $instance->$method(...$args);
? ?}
}
在下面的例子中,調(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。這個(gè) Facade 作為訪問 Illuminate\Contracts\Cache\Factory
接口底層實(shí)現(xiàn)的代理。我們使用 Facade 進(jìn)行的任何調(diào)用都將傳遞給 Laravel 緩存服務(wù)的底層實(shí)例。
如果我們看一下 Illuminate\Support\Facades\Cache
這個(gè)類,你會(huì)發(fā)現(xiàn)類中根本沒有 get
這個(gè)靜態(tài)方法 :
class Cache extends Facade
{
? ?/**
? ? * 獲取組件的注冊(cè)名稱。
? ? *
? ? * @return string
? ? */
? ?protected static function getFacadeAccessor() {
? ? ? ?return 'cache';
? ?}
}
Cache
繼承了 Facade 類,并且定義了 getFacadeAccessor()
方法。這個(gè)方法的作用是返回服務(wù)容器綁定的名稱。當(dāng)用戶調(diào)用 Cache
Facade 中的任何靜態(tài)方法時(shí),Laravel 會(huì)從服務(wù)容器中解析 cache
綁定以及該對(duì)象運(yùn)行所請(qǐng)求的方法(在這個(gè)例子中就是 get
方法)。
3 . 自定義門面
(1)創(chuàng)建門面要代理的類
<?php
namespace App\Units\Test;
class Test
{
? ?public function index()
? ?{
? ? ? ?return 'this is facade';
? ?}
}
(2)創(chuàng)建服務(wù)提供者
php artisan make:provider TestcServiceProvider
因?yàn)殚T面代理是從容器中解析處理對(duì)象,所以在定義門面開始時(shí),就需要通過服務(wù)把需要代理的類注冊(cè)到容器中。
<?php
namespace App\Providers;
use App\Units\Test\Test;
use Illuminate\Support\ServiceProvider;
class TestcServiceProvider extends ServiceProvider
{
? ?public function register()
? ?{
? ? ? ?$this->app->bind('test', function (){
? ? ? ? ? ?return new Test();
?});
? ?}
}
(3)注冊(cè)服務(wù)提供者
在 config\app.php 文件中的 providers 屬性里面注冊(cè)我們剛添加的服務(wù)提供者,即添加 :
'providers' => [
App\Providers\TestcServiceProvider::class,
],
(4)創(chuàng)建門面類
app 目錄下面創(chuàng)建一個(gè)門面類,App\Facade\Index.php 目錄隨意建立,這只要 在注冊(cè)的時(shí)候一致就可以。代碼如下 :
<?php
namespace App\Facade;
use Illuminate\Support\Facades\Facade;
class Test extends Facade
{
? ?protected static function getFacadeAccessor()
? ?{
? ? ? ?return 'test';
? ?}
}
當(dāng)然,如果不想使用服務(wù)提供者,在 getFacadeAccessor
方法中也可以直接返回被代理類的路徑。
3.4.4 ? ?Contracts
契約就是接口,它的使用就是把方法中的參數(shù)類型約束設(shè)置為接口,但實(shí)際傳參的時(shí)候,用的是實(shí)例化接口的類。
1 . 契約使用
Laravel 中的許多類都通過服務(wù)容器解析,包括控制器,事件監(jiān)聽器,中間件,隊(duì)列任務(wù),甚至路由閉包。因此,要獲得契約的接口實(shí)現(xiàn),你可以在要解析的類的構(gòu)造函數(shù)中使用「類型提示」接口。例如 :
<?php
namespace App\Listeners;
use App\Events\OrderWasPlaced;
use Illuminate\Contracts\Redis\Factory;
class CacheOrderInformation
{
? ?protected $redis;
? ?public function __construct(Factory $redis)
? ?{
? ? ? ?$this->redis = $redis;
? ?}
}
解析事件偵聽器后,服務(wù)容器將讀取類的構(gòu)造函數(shù)上的類型提示,并注入適當(dāng)?shù)闹?,?Factory 則是契約下的 Factory 類。
2 . 自定義契約
(1)創(chuàng)建契約
<?php
namespace App\Contracts\Test;
interface TestContract
{
? ?public function contract();
}
(2)創(chuàng)建契約實(shí)現(xiàn)類
<?php
namespace App\Utils\Test;
use App\Contracts\Test\TestContract;
class TestContractUtil implements TestContract
{
? ?public function contract()
? ?{
? ? ? ?dump('跟我 TestContractUtil 簽訂契約吧');
? ?}
}
(3)綁定接口到實(shí)現(xiàn)
<?php
namespace App\Providers;
use App\Contracts\Test\TestContract;
use App\Utils\Test\TestContractUtil;
use Illuminate\Support\ServiceProvider;
class TestServiceProvider extends ServiceProvider
{
? ?public function register()
? ?{
? ? ? ?$this->app->bind(TestContract::class,TestContractUtil::class);
? ?}
}
注意:沒有實(shí)現(xiàn)該契約的實(shí)現(xiàn)類無法使用。
(4)注冊(cè)服務(wù)提供者
'providers' => [
App\Providers\TestServiceProvider::class,
],
3.4.5 ? ?中間件
中間件提供了一種方便的機(jī)制過濾進(jìn)入應(yīng)用程序的 HTTP 請(qǐng)求。要給一組路由中所有的路由分配中間件,可以在 group 之前調(diào)用 middleware
方法,中間件會(huì)依照它們?cè)跀?shù)組中列出的順序來運(yùn)行。這里我們以 First 和 Second 作為中間件名稱為例。
1. 創(chuàng)建中間件
首先通過命令創(chuàng)建兩個(gè)中間件分別為 :
php artisan make:middleware FirstMiddleware
php artisan make:middleware SecondMiddleware
執(zhí)行成功后會(huì)在 app\Http\Middleware 目錄下生成對(duì)應(yīng)文件 :

中間件主要是執(zhí)行其中的 handle 方法 :
FirstMiddleware 文件:app\Http\Middleware\FirstMiddleware.php
<?php
namespace App\Http\Middleware;
use Closure;
class FirstMiddleware
{
? ?public function handle($request, Closure $next)
? ?{
? ? ? ?echo '中間件 First' . '<br/>';
? ? ? ?return $next($request);
? ?}
}
SecondMiddleware 文件:app\Http\Middleware\SecondMiddleware .php
<?php
namespace App\Http\Middleware;
use Closure;
class SecondMiddleware
{
? ?public function handle($request, Closure $next)
? ?{
? ? ? ?echo '中間件 Second' . '<br/>';
? ? ? ?return $next($request);
? ?}
}
3. 注冊(cè)中間件
在 app\Http\Kernel.php
文件把創(chuàng)建的中間件進(jìn)行注冊(cè) :
<?php
namespace App\Http;
use Illuminate\Foundation\Http\Kernel as HttpKernel;
class Kernel extends HttpKernel
{
# 其他代碼省略 ......
? ?protected $routeMiddleware = [
? ? ? ?# 自定義中間件注冊(cè)
? ? ? ?'first' => \App\Http\Middleware\FirstMiddleware::class,
? ? ? ?'second' => \App\Http\Middleware\SecondMiddleware::class,
? ?];
}
4. 中間件使用
# 路由組中的路由都會(huì)使用到組的內(nèi)容,這里不在重復(fù)寫路由
# ?從注冊(cè)的地方可以看出,middleware 方法后面的中間件是給的注冊(cè)時(shí)的別名
Route::middleware(['first', 'second'])->group(function () {
? ?Route::get('midd', function () {
? ? ? ?return '中間件測(cè)試';
? ?});
});
結(jié)果 :

可以看到中間件會(huì)自動(dòng)在執(zhí)行該路由的時(shí)候執(zhí)行。
3.5 ? ?Artisan 命令
Artisan 是 Laravel 中自帶的命令行工具的名稱。它提供了一些對(duì)應(yīng)用開發(fā)有幫助的命令。它是由強(qiáng)大的 Symfony Console 組件驅(qū)動(dòng)的。為了查看所有可用的 Artisan 的命令,可以使用 list 命令來列出它們 :
php artisan list
可以查看所有的命令。
Laravel 框架中也可以去執(zhí)行help命令去查看如: php artisan help migrate
。
1. Artisan 命令使用
(1)利用 Artisan 工具創(chuàng)建控制器
如果手動(dòng)去創(chuàng)建一個(gè)控制器, 需要自己去手寫, 命名空間, 繼承類等 。那么在 Laravel 中, 還可以利用 artisan 工具去執(zhí)行, 如創(chuàng)建一個(gè) AuthController :
php artisan make:controller AuthController
執(zhí)行之后, ?'app\http\Controller' 會(huì)多出一個(gè) AuthController
如果一個(gè)項(xiàng)目中分前臺(tái)和后臺(tái), 相應(yīng)的控制器也需要放置在不同的目錄下, 比如創(chuàng)建一個(gè) Admin/GoodsController
php artisan make:controller Admin/GoodsController
會(huì)自動(dòng)創(chuàng)建 Admin 文件夾, 執(zhí)行之后會(huì)發(fā)現(xiàn), Admin 下多出 GoodsController 的文件, 打開, 發(fā)現(xiàn)命名空間也自動(dòng)整理好。
(2)利用 Artisan 工具查看路由
php artisan route:list
利用這條命令可以查看所有的路由。
(3)利用 Artisan 工具創(chuàng)建中間件
php artisan make:middleware EmailMiddleware
執(zhí)行會(huì)在, middleware 文件夾下找到。
2. 其他 Artisan 命令使用
查看 artisan 命令
php artisan
php artisan list
查看某個(gè)幫助命令
php artisan help make:model
查看 laravel 版
php artisan --version
使用 PHP 內(nèi)置的開發(fā)服務(wù)器啟動(dòng)應(yīng)用
php artisan serve
生成一個(gè)隨機(jī)的 key
php artisan key:generate
開啟Auth用戶功能(開啟后需要執(zhí)行遷移才生效)
php artisan make:auth
開啟維護(hù)模式和關(guān)閉維護(hù)模式(顯示 503)
php artisan down
php artisan up
進(jìn)入tinker工具
php artisan tinker
列出所有的路由
php artisan route:list
生成路由緩存以及移除緩存路由文件
php artisan route:cache
php artisan route:clear
創(chuàng)建控制器
php artisan make:controller StudentController
創(chuàng)建 Rest 風(fēng)格資源控制器(帶有index、create、store、edit、update、destroy、show方法)
php artisan make:controllerPhotoController --resource
創(chuàng)建模型
php artisan make:model Student
創(chuàng)建新建表的遷移和修改表的遷移
php artisan make:migration create_users_table --create=students //創(chuàng)建students表
php artisan make:migration add_votes_to_users_table --table=students //給students表增加votes字段
遷移命令
執(zhí)行遷移
php artisan migrate
創(chuàng)建模型的時(shí)候同時(shí)生成新建表的遷移
php artisan make:model Student -m
回滾上一次的遷移
php artisan migrate:rollback
回滾所有遷移
php artisan migrate:reset
創(chuàng)建中間件(app/Http/Middleware 下)
php artisan make:middlewareActivity
創(chuàng)建隊(duì)列(數(shù)據(jù)庫)的表遷移(需要執(zhí)行遷移才生效)
php artisan queue:table
創(chuàng)建隊(duì)列類(app/jobs下):
php artisan make:jobSendEmail
創(chuàng)建請(qǐng)求類(app/Http/Requests下)
php artisan make:request CreateArticleRequest
數(shù)據(jù)遷移(Migration)
創(chuàng)建遷移
php artisan make:migration create_users_table
指定路徑
php artisan make:migration --path=app\providers create_users_table
數(shù)據(jù)填充(Seeder)
創(chuàng)建要填充的數(shù)據(jù)類
php artisan make:seeder UsersTableSeeder
數(shù)據(jù)填充(全部表)
php artisan db:seed
指定要填充的表