laravel5.5+
laravel
是目前最流行的php
框架,發展勢頭迅猛,應用非常廣泛,有豐富的擴充套件包可以應付你能想到的各種應用場景,laravel
框架思想前衛,跟隨時代潮流,提倡優雅程式碼,自稱為“web
工匠”,其中的route
、blade
模板引擎、console
、容器以及compose
r擴充套件包為業務的開發提供了極大的便利。
國內目前已經有眾多的laravel
社群,比如
當然還有更多可供開發者學習和交流的網站,可以自行google
或者百度。
不過如果看文件的話,建議檢視英文網站官網(如果英語允許的話),官網也有一個對應的社群,供開發者問答,不過貌似沒有那麼活躍,提問題的話也需要有一定的英文基礎,至少可以看懂stackoverflow
上的問答。
言歸正傳,這裡會介紹一下laravel5.5
的簡易上手教程,如果你需要理解laravel
框架整體的設計和實現原理的話,MVC
、設計模式(尤其是工廠模式)、路由、管道、容器、控制反轉、依賴注入等都是必須要理解的,這裡並不深入探討,否則本作者寶寶就要吐血寫個系列了,想想都覺著累(經常加班啊沒時間啦!)。
本教程可以讓你在短時間內按照123步驟完成一個網站的應用,貫穿laravel
各個層級,對於一個剛接觸該框架的開發者來說,先應用,後深入,這也是登堂入室的學習方式,何樂而不為呢?
Ok, Here we go!!!
前期準備
- 安裝
php7
(最好加入環境變數)。可以上官網或者軟體包管理工具安裝,例如:brew install php7
- 安裝
composer
- 安裝
mysql
建立laravel
專案
1. 終端執行命令
composer create-project laravel/laravel blog
2. 進入blog
資料夾,執行
php -S localhost:80 -t public
3. 瀏覽器訪問 http://localhost
4. 執行命令 php artisan
如果3、4步驟執行成功,則一切無礙,可以進行下一步。
5. 利用你的編輯工具,以sublime
為例,開啟blog
專案,Ctrl+P
找到web.php
,寫入如下程式碼,進行路由註冊:
Route::get(`/test`, function () {
return "<h1>Hi Sunday.</h1>";
});
這裡簡單解釋一下,路由在
routes
目錄之下,有三個檔案:web.php
、console.php
、channel.php
其中,web.php
是負責網站路由,也就是當php
是以http
請求的方式執行時才會用到,console.php
是在命令列執行模式下執行artisan
命令的,這個後續會講到,channel.php
是廣播訊息時會用到,這個本篇略過,需要看的可以檢視文件get
是http
請求方式,路由註冊時也可以用post/put/delete/patch
等,laravel-router
還提供了便利的restful
風格的路由註冊resource
方法,可以對後續業務處理增刪改查等。
上述例子為一個匿名函式,其實一般情況下會有路由分組,字首,中介軟體(後面會講到),別名,匹配等的鏈式呼叫:Route::prefix(`prefix_example`)->middleware([`m_exaple_1`,`m_example_2`])->group(Route_Closure)
;
下面給一個完整的示例:
Route::prefix(`hi`)->middleware([`hi_m`])->namespace(`sd`)->group(function () {
Route::post(`sunday`, `SundayController@sunday`)->name(`hi.sunday.post`);
Route::put(`sunday`, `SundayController@sunday`)->name(`hi.sunday.put`);
})
怎麼樣?
laravel
路由的註冊風格是不是非常友好,非常靈活多變?其中Route
也可以使用app(`router`)
訪問,app()
是一個輔助方法,這個輔助方法在vendorlaravelframeworksrcIlluminateFoundationhelpers.php
中,其中也有很多其他好用的輔助方法。app()
涉及到容器的思想和facade
門面註冊,這裡不詳述。
6. 訪問以下剛剛註冊的路由,http://localhost/test
7. 手動在app/Http/Controllers
下新建或命令列生成一個控制器:php artisan make:controller sd/SundayController
,這時你會看到app/Http/sd
下面有一個SundayController.php
,將下面的程式碼寫入:
public function sunday()
{
return "Hi sunday";
}
8. web.php
註冊路由,併成功訪問:
Route::prefix(`hi`)->namespace(`sd`)->group(function () {
Route::get(`sunday`, `SundayController@sunday`)->name(`hi.sunday.get`);
})
9. 中介軟體,執行命令php artisan make:middleware MyMiddleware
,會生成一個標準中介軟體,開啟MyMiddleware.php
可以看到裡面有兩個方法handle
和terminate
public function handle($request, $next)
{
// 上面兩個入參,你不用管,這個是laravel路由分發時自動注入的引數,$request是laravel封裝的請求物件,IlluminateHttpRequest,你可以獲取到所有超級變數的資料,也可以獲得對應的一些請求處理方法如session(),getClientIp().
// 這個方法是在進入Controller之前執行的,目的是對本次請求進行預處理或者校驗等。
app(`log`)->info(`記錄一個日誌`);
}
public function terminate($request, $response)
{
// 這個方法是在請求即將關閉時執行的,可以處理一些響應相關的邏輯。
app(`log`)->info(`再記錄一下日誌`);
}
10. 中介軟體註冊,開啟app/Http/Kernel.php
,在$middleware
中加入
appHttpMiddlewareMyMiddleware::class
11. 檢視 storage/logs/laravel.log
(如果你config/app.php
配置了日誌channel
為daily
,那麼應該看到的是日期格式的檔案),裡面應該有上一步中記錄的日誌資訊,以及對應的日誌級別,laravel
的日誌使用monolog
,可以使用多種驅動去記錄日誌,也可以配置上報策略,實現了loggerinterface
介面,符合psr3
的規範。
12. 檢視層,在剛剛的方法 SundayController@sunday
中,將返回值改為:
return view(`test.test`, [`name` => `sunday`, `testArray` => [1,2,3]]);
在前端模板所在目錄 resources/views
下建一個目錄test
,建一個blade
模板test.blade.php
,程式碼如:
@if ($name )
<h1>{{$name}},你好</h1>
@else
<h1>無名氏,你好</h1>
@endif
@foreach ($testArray as $testNumber)
<li>{{$testNumber}}</li>
@endforeach
在控制器返回檢視時,第一個引數是以
.
號表示resources/views
下的目錄層級的,上面的test.test
則表示檢視檔案是在test/test.blade.php
,第二個引數是一個傳遞給檢視層的陣列,裡面應當是key => value
關聯陣列,因為在blade
模板引擎中,會直接將對應的key
轉化成一個可使用的變數,在返回給檢視之前,如果你定義了檢視繫結,如在ComposerServiceProvider
中的boot
方法中註冊了對應的檢視繫結的話,那麼會先處理這一步,然後再將資料傳給目的檔案。
在這個例子中,test.blade.php
得到了引數之後,會通過blade
引擎分析模板檔案,解析語法,轉化成正常的html
文字。{{$name}}
或{!!$name!!}
語法相當於<?=$name>
,前者為防止xss會過濾掉一些specialchar
,後者則會直接輸出文字,不安全。@if ... @endif
則是條件判斷語句,行後面可以跟一個簡短的php
邏輯判斷@foreach ... @endforeach
輪詢陣列
其他語法請參考 官方文件。
以上的步驟,僅僅是完成了從路由到檢視的簡單處理,下面看一下資料模型,Model
層
13. 配置資料庫
database.php
// config/database.php
`mysql` => [
`driver` => `mysql`,
`host` => env(`DB_HOST`, `127.0.0.1`), // 主機
`port` => env(`DB_PORT`, `3306`), // 埠
`database` => env(`DB_DATABASE`, `forge`), // 這裡需要配置你的資料庫
`username` => env(`DB_USERNAME`, `forge`), // 配置你的使用者名稱
`password` => env(`DB_PASSWORD`, ``), // 密碼
`unix_socket` => env(`DB_SOCKET`, ``),
`charset` => `utf8mb4`,
`collation` => `utf8mb4_unicode_ci`,
`prefix` => ``,
`strict` => true,
`engine` => null,
],
.env
// .env檔案
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=test #這裡需要你手動在資料庫建立一下資料庫
DB_USERNAME=root #你自己的使用者名稱
DB_PASSWORD=pwd #你自己的密碼
14. 執行artisan
命令 php artisan make:auth
15. 執行artisan
命令 php artisan make:migration
建立user表和密碼錶,進入你的資料庫中檢視是否建立成功
16. 這時,開啟網站首頁,你會看到有一個登入標誌,當你註冊成功之後,你會看到user表中多了一條資料,表示資料庫連線是成功的。
model
可以通過php artisan make:model TestModel
來建立,如果你沒有特殊要求的話,它會出現在app
目錄下。
進入該Model
你會看到它繼承了一個EloquentModel
,這個ORM model
可以為你提供多種多樣的CURD
方法,具體可見文件,在Model裡面需要自定義一些屬性,例如table、fillable、guards
等,支援軟刪除use SoftDeletes
,但對應表中必須要有deleted_at
欄位。
你也可以用DB匿名類或者app(`db`)來得到一個比EloquentModel更加原始的模型物件,這會讓你對資料庫的操作更加原生,詳見 文件
以上就是對應的MVC
使用的簡單介紹
下面,讓我們看看console
的使用
- 終端進入專案目錄,執行
php artisan
可以檢視所有可執行命令 - 執行
php artisan route:list
可以檢視已成功註冊的路由列表 -
php artisan make:command NewCommand
建立一個新的命令 - 開啟
app/Console/Commands/NewCommand.php
,在$signature
後定義一個命令的名稱如:test:test {--O|op= : 這是我的測試引數}
,在handle()
方法中寫入你的邏輯。如:
$this->info(`我第一個命令`); // 會在終端上輸出該文字
$this->error(`我的命令錯了`); // 會在終端上輸出該文字
$this->confirm(`確認我的命令?`); // 選擇yes/no
$this->choice(`我還有其他選擇:`, ["A", "B"]); // 選擇一個
$this->output->progress(); //進度條
echo $this->option(`op`); // 獲取所定義引數值
之後,在app/Console/Kernel.php
$commands
註冊命令AppConsoleCommandsTestCommand::class
,執行php artisan test:test --op=1
,成功輸出1,這條命令算是完工了。
如果你想要加入定時任務,可以將命令加在
schedule()
中,$schedule->cron("0 0 0 0 0")
這裡填寫crontab
的格式。
你可以執行php artisan schedule:run
來執行定時任務laravel
會在你專案維護或迭代時自動完成定時任務的重啟
composer
擴充套件包
如果你有心,當你建立一個laravel
專案的時候,就會注意到,composer
會在專案中建立一個vendor
目錄,這個目錄下儲存著各式各樣的擴充套件包,如:laravel/framework、symphony/console、monolog/monolog
等,這些擴充套件包是laravel
的寶庫,為你的開發提供了極大便利。
所有的擴充套件包都需要符合psr4
載入規範,通過spl_autoload_register()
方法自動加在,composer
會生成一個autoload_classmap.php
你可以找到所有載入到的類和檔案。
如何開發一個composer
擴充套件包呢?
1.新建目錄test
,進入執行 composer init
這裡
type
一般選擇project/library
,license
一般選擇MIT
協議(一種開源授權協議)
2.開啟composer.json,加入psr4
規則:
"autoload": {
"psr-4": {
"Name1\Name2\": "name/src/Name" // 這裡表示按照psr4規範,對於name/src/Name目錄下的所有檔案,載入名稱空間以Name1\Name2\為字首的類。
}
}
3.建立name/src/Name
目錄,在Name
目錄下建立檔案NameServiceProvider.php
,程式碼如下:
<?php
namespace Name1Name2;
use IlluminateSupportServiceProvider;
class NameServiceProvider extends ServiceProvider
{
public function boot()
{
require __DIR__ . `/helpers.php`;
log_info(`我進來了`);
}
}
由於log_info()
這個方法我們沒有定義過,所以可以在helpers.php
中進行定義:
<?php
if (!function_exist(`log_info`)) {
function log_info($message) {
echo $message . PHP_EOL;
}
}
我們也可以建立一個更深層次的目錄,如Handlers
,在其下建立一個TestYou.php
:
namespace Name1Name2Handlers;
class TestYou
{
public function test()
{
log_info("test");
}
}
建立一個匿名類Facades/Test.php
:
namespace Name1Name2Facades;
use IlluminateSupportFacadesFacade;
class Test extends Facade
{
protected static function getFacadeAccessor()
{
return "test";
}
}
材料已準備完畢,下面開始切菜:
// NameServiceProvider
public function register ()
{
$this->app->bind(`test`, Name1Name2HandlersTestYou::class);
}
為什麼一定要定義匿名類呢?因為
laravel
框架本身要求就是少去關注工具類的實現,多關注業務本身,所以所有的sdk或者擴充套件包都在接入時儘量提供便利,其中$this->app->bind()
也體現了一個依賴注入控制反轉的思想,使得定義了匿名類的,可以在config/app.php
中註冊相應匿名類Test
及NameServiceProvider
之後可以以極為便利的方式使用,如:Test::test()
,或者app(`test`)->test()
,不需要管他們的名稱空間。
上述的擴充套件包功能已經基本成形,你需要將它放到相應的程式碼託管倉庫中,如github
或https://packagist.org
(推薦),你可以嘗試在laravel
中使用命令composer require {你的package名字}
進行安裝。
後語
本文由於初次編寫,必然有諸多不合理之處,希望讀者們多多給出優化意見,以後在文章中會考慮到,大家共同成長,一起發財。