本文主要和大家分享Laraval之文件結構、路由、控制器詳解,我們的文章路線是一、 文件結構二、 編寫第一行代碼三、 初始強大的 Artisan四、 路由五、 控制器。
一、文件結構
打開項目代碼之后,我們就可以在 Sublime的左側邊欄里清楚的看到 Laravel源碼的結構:
下面簡單介紹一下 Laravel源碼里每個文件夾都是用來做什么的,了解結構才能更好地進行后續的開發。
文件夾
介紹
app
網站的業務邏輯代碼,例如:控制器/模型/路由等
bootstrap
框架啟動與自動加載設置相關的文件
config
網站的各種配置文件
database
數據庫操作相關的文件
public
網站的對外文件夾,入口文件和靜態資源(CSS,JS,圖片等)
resources
前端視圖文件和原始資源(CSS,JS,圖片等)
storage
編譯后的視圖、基于會話、文件緩存和其它框架生成的文件
tests
自動化測試文件
vendor
Composer 依賴文件
app/Http/Controllers
存放控制器
app/Http/Middleware
存放中間件
resources/views
視圖路徑 blade視圖
除了上述文件夾,根目錄下有些文件也比較常用:
文件
介紹
.env
環境配置文件
.env.example
.env 文件的一個示例
.gitignore
git 的設置文件,制定哪些文件會被 git忽略,不納入文件管理
composer.json
網站所需的 composer擴展包
composer.lock
擴展包列表,確保這個網站的副本使用相同版本的擴展包
gulpfile.js
GULP 配置文件( GULP 后邊會學到)
package.json
網站所需的 npm包
readme.md
網站代碼說明文件
app/Http/routes.php
網站的大多數路由都定義在該文件中,該文件將會被 App\Providers\RouteServiceProvider類加載。
有個簡單的了解就好,在后續開發過程中會通過實踐對 Laravel 的結構進行更深的理解。
二、編寫第一行代碼
下面就讓我們編寫第一行代碼,Hello World!
首先我們需要定位到我們之前看到過的歡迎頁面,這個頁面的位置是:resources/views/welcome.blade.php。
打開這個文件,按 ctrl+f 搜索 Laravel 5 可以定位到代碼具體位置
修改為 Hello world 然后記得 ctrl+s 保存。
.
.
.
<body>
<pclass="container">
<pclass="content">
<pclass="title">My first Demo</p>
</p>
</p>
</body>
.
.
.
現在打開瀏覽器,在地址欄輸入 localhost 可以看到如下效果:
很簡單,我們的第一行代碼就完成了:)
三、初始強大的 Artisan
(一) 什么是Artisan呢?
熟悉 linux 的朋友都知道,我們平時的創建/刪除文件等常用操作都可以在命令行里來完成,Artisan 就相當于 Laravel 為我們獨家定制的一個命令行工具,提供了很多實用的命令,可以用來快速生成 Laravel 開發中常用的一些文件并完成相關的配置。
(二) 常用 Artisan 命令
使用命令行進入我們的代碼根目錄:
cd ~/Code/myweb
然后,執行 php artisan list 可以查看常用 artisan 命令:
php artisanlist
如下圖,可以看到顯示出了很多的 artisan 命令:
下面列出最常用的一些命令,使用方法就像上面的php artisan list一樣,先有個簡單了解就好,我們在后面的開發中會多次使用到這些命令:
命令
說明
php artisan key:generate
生成 App Key
php artisan make:controller
生成控制器
php artisan make:model
生成模型
php artisan make:policy
生成授權策略
php artisan make:seeder
生成 Seeder文件
php artisan migrate
執行遷移
php artisan migrate:rollback
回滾遷移
php artisan migrate:refresh
重置數據庫
php artisan db:seed
填充數據庫
php artisan tinker
進入 tinker環境
php artisan route:list
查看路由列表
在開發過程中,應該盡量使用 artisan 命令,這樣不僅可以提高開發效率,還可以減少bug。
在后續的實驗中,我們也會多次使用 artisan 命令。
四、路由
我們學習 Laravel 基礎功能之一:路由。
(一) 什么是路由呢?
在瀏覽器中輸入http://blog.csdn.net/u014665013我們可以訪問實驗樓網站的首頁,如果我們輸入http://blog.csdn.net/u014665013/article/details/77588281呢?我們會來到博客的文章頁面。
這就是路由了,即路由系統會對用戶輸入的 URL 地址 進行解析,然后分配不同的工作,有點像路由器。
路由不僅可以美化 URL,還可以便于用戶記憶等。
那么 Laravel 是怎么處理 url 的呢?
首先,我們打開項目代碼,找到路由設置文件,文件位置:app/Http/routes.php。
我們可以看到,當前 routes.php 文件中只有如下幾行代碼,這幾行代碼都實現了哪些功能呢?
Route::get('/', function(){
return view('welcome');
});
這幾行代碼表示,當我們輸入的 url為 網址 + ‘/’,也就是localhost/ 時,為我們返回 歡迎頁,也就是之前我們寫 Hello World 的頁面。
注意:在輸入網址的時候,localhost和 localhost/是一樣的。
我們可以嘗試將這段代碼修改一下:
Route::get('welcome', function(){
return view('welcome');
});
然后我們打開瀏覽器,再輸入localhost,我們會發現,報錯了!
這個錯誤的大概意思是,沒有找到處理該 url 的辦法,因為我們沒有定義 '/' 這條路由。
現在我們輸入 localhost/welcome 并刷新頁面,我們看到了熟悉的頁面原來的征程welcome界面
通過上面的嘗試,你是否對路由有了一個簡單的認識?
下面我們來系統的學習一下 Laravel 的路由。
(二) 基本路由
網站的大多數路由都定義在 app/Http/routes.php 文件中,該文件將會被 App\Providers\RouteServiceProvider 類加載。最基本的 Laravel 路由僅接受 URI 和一個閉包,下面我們再定義兩條路由。
app/Http/routes.php
<?php
Route::get('welcome', function(){
return view('welcome');
});
Route::get('/', function(){
return'Index Page';
});
Route::get('/help', function(){
return'Help Page';
});
然后我們分別訪問 localhost 和 localhost/help 可以看到返回了對應的信息:
(三) 路由動作
我們知道,一個url請求可能有多種類型,除了常用的GET,還可能有 POST、PUT、DELETE 等類型的請求。
對應的處理方法如下:
Route::post('/foo', function(){
//該路由將匹配 post方法的 '/foo' url
});
Route::put('/foo', function(){
//該路由將匹配 put方法的 '/foo' url
});
除此之外,還可以用 match 來同時處理多種類型的請求:
Route::match(['get', 'post'],'/foo', function(){
// 該路由將匹配 get 和 post 方法的 'foo' url
});
甚至,還可以使用 any 來同時處理所有類型的請求:
Route::any('/foo', function(){
// 該路由將匹配所有類型的 'foo' url
});
(四) 路由參數
1.基礎的路由參數
有時候你可能需要從 URL 中獲取一些參數,比如姓名、年齡等。
下面打開 routes.php,加入一個帶參路由。
app/Http/routes.php
<?php
Route::get('name/{name}', function($name){
return'I`m '.$name;
});
然后我們如果訪問 localhost/name/Tom 我們可以看到網頁返回了對應的信息:
如果試圖訪問 localhost/name 將會出現錯誤:
我們也可以定義多個參數:
app/Http/routes.php
<?php
Route::get('name/{name}/age/{age}', function($name, $age){
return'I`m '.$name.' ,and I`m '.$age;
});
然后我們如果訪問 localhost/name/Tom/age/28 我們可以看到網頁返回了對應的信息:
2.可選的路由參數
有時你需要指定可選的路由參數,可以通過在參數后面加上 ?來實現。
app/Http/routes.php
<?php
Route::get('hello/{name?}', function($name = null){
return'Hello! '.$name;
});
這時你訪問 localhost/hello 將不會報錯,只是參數是空值。
你可以為該可選參數設定一個默認值,當 url 未傳參時,將顯示默認值。
app/Http/routes.php
<?php
Route::get('hello/{name?}', function($name = 'Tom'){
return'Hello! '.$name;
});
這時訪問 localhost/hello 將返回默認的信息,如下圖:
如果訪問localhost/hello/John 將會顯示參數,如下圖:
(五) 命名路由
所謂命名路由,就是給路由起個名字,這樣我們就可以通過這個名字獲取到該條路由的相關信息,也更利于后期維護。
建議在開發過程中給每個路由命名,使用下面兩種方式都可以為一個路由命名。
Route::get('foo', ['as' => 'foo', function(){
//方法一
}]);
Route::get('foo', function(){
//方法二
})->name('foo');
(六) 路由群組
路由群組允許你共用路由屬性,例如:中間件、命名空間等,你可以利用路由群組統一為多個路由設置共同屬性,而不需在每個路由上都設置一次。共用屬性被指定為數組格式,當作Route::group方法的第一個參數。
下面通過幾個常用樣例來熟悉這些特性。
1.為路由群組添加共用的中間件
至于什么是中間件,在后面的實驗中會專門的學習。
Route::group(['middleware' => 'auth'], function(){
Route::get('/', function() {
// 該路由將使用 Auth 中間件
});
Route::get('name', function(){
// 該路由也將使用 Auth 中間件
});
});
2.為路由群組添加共用的命名空間
什么是命名空間?從廣義上來說,命名空間是一種封裝事物的方法。在很多地方都可以見到這種抽象概念。例如,在操作系統中目錄用來將相關文件分組,對于目錄中的文件來說,它就扮演了命名空間的角色。具體舉個例子,文件 foo.txt 可以同時在目錄/home/greg 和 /home/other 中存在,但在同一個目錄中不能存在兩個 foo.txt 文件。另外,在目錄 /home/greg 外訪問 foo.txt 文件時,我們必須將目錄名以及目錄分隔符放在文件名之前得到 /home/greg/foo.txt。這個原理應用到程序設計領域就是命名空間的概念。
你可以簡單的把命名空間理解為,當前文件所在的位置。
Route::group(['namespace' => 'Admin'], function()
{
// 控制器在「App\Http\Controllers\Admin」命名空間
Route::group(['namespace' => 'User'], function()
{
// 控制器在「App\Http\Controllers\Admin\User」命名空間
});
});
3.為路由群組添加共用的前綴
你可能有一系列路由都具有一個相同的前綴,比如:
Route::get('user/name', function(){
//
});
Route::get('user/age', function(){
//
});
Route::get('user/introduction', function(){
//
});
這時你就可以用路由群組來簡化代碼:
Route::group(['prefix' => 'user'], function(){
Route::get('name', function() {
//
});
Route::get('age', function() {
//
});
Route::get('introduction', function() {
//
});
});
路由群組也可以添加參數:
Route::group(['prefix' => 'user/{id}'], function(){
Route::get('name', function($id) {
// 符合 'user/{id}/name' URL
});
Route::get('age', function($id) {
// 符合 'user/{id}/age' URL
});
});
(七) 查看路由
我們可以使用url('foo')函數來生成完整的 URL,例如,我們這樣修改一下代碼:
app/Http/routes.php
<?php
Route::get('/help', function(){
return url('/help');
});
然后,訪問localhost/help,我們可以看到返回了完整的 URL 信息:
我們還可以使用命名路由函數route('foo')來生成完整的 URL 信息。
app/Http/routes.php
<?php
Route::get('/help', function(){
return route('foo');
});
Route::get('/foo', function(){
//
})->name('foo');
然后,訪問 localhost/help,我們可以看到返回了 foo 路由的完整 URL 信息:
(八) 正則表達式限制路由
你可以使用 where 方法來限制參數的格式。where 方法接受參數的名稱和正則表達式。
app/Http/routes.php
<?php
Route::get('hello/{name?}', function($name = 'Tom'){
return'Hello! '.$name;
})->where('name','[A-Za-z]+');
然后如果訪問 localhost/hello/John 這樣的 url 就會正確顯示。
如果訪問 localhost/hello/55 這樣的 url 將會報錯,如下圖:
同樣,也可對多個參數都設置正則驗證:
app/Http/routes.php
<?php
Route::get('name/{name}/age/{age}', function($name, $age){
return'I`m '.$name.' ,and I`m '.$age;
})->where(['name' => '[A-Za-z]+', 'age' => '[0-9]+']);
如果你想對所有的路由參數都加上某種限制,需要在RouteServiceProvider 的 boot 方法里定義這些限制。
publicfunctionboot(Router $router)
{
$router->pattern('id', '[0-9]+');
parent::boot($router);
}
五、控制器
本次實驗我們學習控制器(Controller)。
(一) 準備工作
首先,我們先創建一個路由,順便再練習一下上次試驗的內容,打開routes.php文件。
app/Http/routes.php
<?php
Route::get('/', function(){
return view('welcome');
});
Route::get('user/name', function(){
return'Name Page';
});
當我們訪問網站地址 localhost/user/name 時,會返回 'NamePage':
但是我們知道,實際的網站功能不可能這么單調,我們需要更多的返回信息和操作,顯然把大量的處理代碼寫在這里是不合適的,這時候就要用到Controller。
現在我們對上面的代碼進行更改:
<?php
Route::get('/', function(){
return view('welcome');
});
Route::get('/user/name', 'UserController@name');
這段代碼的意思就是,當用戶訪問 'localhost/user/name' 這個 URL 的時候,調用 UserController 這個控制器的 name 方法來處理請求。也就是說,將原來的閉包函數放到了一個單獨的文件中。
我們可以將有共同特征的路由處理函數放到一個共同的控制器中,例如下面這種方式:
Route::get('/user/name', 'UserController@name');
Route::get('/user/age', 'UserController@age');
Route::get('/user/introduction', 'UserController@introduction');
三條不同的路由的處理函數放在了同一個控制器(用戶控制器)的三個不同的方法內。
下面我們通過幾個簡單的例子來體會一下 Controller是怎么工作的。
(二) 基礎控制器
控制器一般存放在 app/Http/Controllers 目錄下,下面是一個基礎控制器的例子,先來簡單感受一下控制器文件的結構:
<?php
namespaceApp\Http\Controllers;
useApp\User;
useApp\Http\Controllers\Controller;
classUserControllerextendsController
{
publicfunctionshow($id)
{
return view('user.profile', ['user' => User::findOrFail($id)]);
}
}
所有 Laravel 控制器都應繼承基礎控制器類,它包含在Laravel 的默認安裝中。該基礎類提供了一些便捷的方法,例如 middleware 方法(middleware 是中間件 后邊會講解),該方法可以用來將中間件附加在控制器行為上。
然后你就可以通過一個路由把請求引入到這個控制器文件來,像下面這樣:
Route::get('user/{id}', 'UserController@show');
現在,當請求和此特定路由的 URI 相匹配時,UserController 類的 show 方法就會被運行。當然,路由的參數也會被傳遞至該方法。
現在,讓我們動手實踐來感受一下控制器。
首先用 artisan 命令創建一個新的控制器,打開命令行,進入代碼根目錄:
cd ~/Code/myweb
然后運行 artisan命令生成控制器:
phpartisanmake:controllerUserController
然后轉到 app/Http/Controllers目錄下,可以看到剛剛創建的 UserController.php。打開這個文件:
<?php
namespaceApp\Http\Controllers;
useIlluminate\Http\Request;
useApp\Http\Requests;
useApp\Http\Controllers\Controller;
classUserControllerextendsController
{
publicfunctionindex()
{
//
}
publicfunctioncreate()
{
//
}
publicfunctionstore(Request $request)
{
//
}
publicfunctionshow($id)
{
//
}
publicfunctionedit($id)
{
//
}
publicfunctionupdate(Request $request, $id)
{
//
}
publicfunctiondestroy($id)
{
//
}
}
我們可以看到,Laravel 為我們生成了一些默認的代碼,仔細觀察可以發現是 7 個空方法,分別是
index()、create()、store()、show()、edit、update、destroy
其中index()通常用來顯示引導頁/首頁,其他的六個通常用來對數據的創建/讀取/更新/刪除操作,簡稱 CRUD (Create Retrieve Update Delete)。
現在我們先刪除這些空操作,然后創建一個新方法:
<?php
namespaceApp\Http\Controllers;
useIlluminate\Http\Request;
useApp\Http\Requests;
useApp\Http\Controllers\Controller;
classUserControllerextendsController
{
publicfunctionname(){
return'Name Page';
}
}
對應之前創建過的路由:
Route::get('/user/name', 'UserController@name');
現在我們可以訪問一下localhost/user/name看下效果:
可以看到,實現了跟以前一樣的效果,但是我們應用了 Controller ,一個很簡單的例子。
(三) 控制器的命名空間
可能你會注意到控制器文件中有這么一行代碼:
namespaceApp\Http\Controllers;
這行代碼就是說明了此控制器的命名空間。
這個目錄也是控制器的默認目錄,所以我們在 routes.php 文件中引入的時候可以直接使用:
Route::get('/user/name', 'UserController@name');
有一點非常重要,那就是我們在定義控制器路由時,不需要指定完整的控制器命名空間。我們只需要定義「根」命名空間 App\Http\Controllers 之后的部分類名稱即可。默認 RouteServiceProvider 會使用路由群組,把 routes.php 文件里所有路由規則都配置了根控制器命名空間。
現在假如你在 App\Http\Controller 目錄下新建了一個 User 文件夾來存放 UserControllser.php。
你的 routes.php 文件中就需要這么寫:
Route::get('/user/name', 'User\UserController@name');
相應的,控制器中的命名空間也要改變:
namespaceApp\Http\Controllers\User;
現在讓我們來刪掉剛才的控制器,重新生成一個新的控制器,打開命令行:
rm app/Http/Controllers/UserController.php
然后重新生成一個 UserController ,這次我們單獨創建一個 User 文件夾來存放這個 Controller 。
php artisan make:controller User/UserController
然后打開工程文件,我們可以看到,在 app\http\Controllers 文件夾下新建了一個 User 文件夾,里邊有我們剛剛創建的 UserController.php 文件,打開這個文件:
<?php
namespaceApp\Http\Controllers\User;
useIlluminate\Http\Request;
useApp\Http\Requests;
useApp\Http\Controllers\Controller;
classUserControllerextendsController
{
publicfunctionindex()
{
//
}
.
.
.
}
注意看命名空間,可以看到,默認生成的命名空間就是App\Http\Controller\User 這就是 artisan 命令為我們做的。
修改為我們自己的方法:
<?php
namespaceApp\Http\Controllers\User;
useIlluminate\Http\Request;
useApp\Http\Requests;
useApp\Http\Controllers\Controller;
classUserControllerextendsController
{
publicfunctionname(){
return'Name Page';
}
}
然后對應更改 routes.php 文件:
Route::get('/user/name', 'User\UserController@name');
然后訪問 localhost/user/name 可以看到實現了正確的跳轉!
(四) 控制器的依賴注入
細心的你肯定發現,控制器中還有幾行神奇的代碼:
use Illuminate\Http\Request;
use App\Http\Requests;
use App\Http\Controllers\Controller;
這幾行代碼說明了該控制器的依賴注入,簡單來說,依賴注入就是將該控制器用到的依賴添加進來。
比如,所有的 Controller 都依賴 基礎 Controller.php ,所以需要:
use App\Http\Controllers\Controller;
比如,當我們處理請求的時候,我們引入 Request 類,才可以使用很多 Laravel 提供的方法:
use Illuminate\Http\Request;
在后邊的實驗中你會慢慢體會到依賴注入的強大之處。
相關推薦:
.net轉php laraval框架學習系列,.netlaraval_PHP教程
以上就是Laraval之文件結構、路由、控制器詳解的詳細內容,更多請關注php中文網其它相關文章!