Laravel身爲最優雅的PHP框架,不少學習PHP的小夥伴造就對Laravel垂涎欲滴。今天就來實現你的願望,讓咱們一塊兒從零開始,利用Laravel實現Web應用最多見的註冊和登陸功能!全部的課程源碼已放在Github上:laravel-start. Race Start !php
首先咱們來明確一下咱們這個課程須要的東西:css
Laravel
就是咱們關心的核心部分,Bootstrap
用來快速設置一些前端的CSS樣式。html
簡單說明以後咱們來進入下一步,安裝Laravel,在這咱們是經過Composer來安裝,打開命令行終端,執行:前端
cd Sites
Sites
就是web應用的根目錄,你能夠根據須要換成你本身的根目錄,而後再執行:mysql
composer create-project laravel/laravel laravel
laravel
就是你的應用目錄名,你能夠取一個你喜歡的名字。執行上面的命令以後,等一段時間(畢竟在國內,網速是個大坑),安裝完之後你會獲得這一堆目錄:laravel
咱們主要操做models
和 controllers
和 views
這三個目錄:這就是MVC的構成啊!git
而後再命令行執行:github
cd laravel/public/packages
這裏的laravel
與上面的應用目錄對應,若是你在安裝的時候用了其餘的名字,請對應換上。來到packages
這個目錄後安裝Bootstrap
,直接在命令行執行:web
bower install bootstrap
這個比較快,而後等這個下載完以後你就會獲得最新的穩定版Bootstrap。在目錄packages
目錄下的 bower_components/bootstrap/dist/
這裏就包含了Bootstrap的css,js,fonts這三個咱們在開發過程當中常常用到的樣式文件,js和字體文件。成功後你將看到這個:sql
注:這裏使用的bower這個工具,它負責管理一些前端的包。
到這裏,咱們的前期工做已經準備好了。不過在進入下一步以前,咱們得先確保咱們的laravel/app/storage
目錄有相應的寫入權限,因此回到laravel
目錄,若是你在安裝完bower以後沒動過命令行,能夠直接經過:
cd ../../
回到laravel
目錄,而後在執行:
chmod -R 755 app/storage
這一步搞定以後咱們就能夠進入真正的開發階段了。
在開始配置以前,咱們要爲咱們的laravel應用建立一個數據庫,我將它命名爲laravel-start
,
而後在編輯器中打開app/config/database.php
文件,對相應的數據庫配置項填入,如:
'default' => 'mysql', // 數據庫鏈接 'connections' => array( 'mysql' => array( 'driver' => 'mysql', 'host' => '127.0.0.1', 'database' => 'laravel-start', 'username' => 'root', 'password' => '', 'charset' => 'utf8', 'collation' => 'utf8_unicode_ci', 'prefix' => '', ),
鏈接完數據庫以後,還得建立一個Users表,你能夠直接在數據庫中建立Users表,也能夠利用Laravel的artisan來建立,這裏咱們使用Laravel的artisan來建表,順道瞭解一點點關於Laravel migrate的知識。執行下面語句:
php artisan migrate:make create-users-table
以上命令會建立一個migrate文件(文件位於app/database/migrations
目錄下),這個文件的名字就是create-users-table
,而後咱們能夠經過編輯剛剛生成的migrate文件來建立Users表。
public function up() { Schema::create('users', function($table){ $table->increments('id'); $table->string('username', 20); $table->string('email', 100)->unique(); $table->string('password', 64); $table->string('remember_token',62)->default('default'); $table->timestamps(); }); }
上面的方法使用了laravel的Schema Builder類,上面這段代碼使用up()
方法的建立一個users表,這個表裏有5個字段:id
自增 ,username
長度20之內 ,email
長度100之內而且是惟一的 ,password
長度64之內 ,remember_token
是爲了在登陸的時候更方便實用,Laravel會自動將token值填充進來,但在最開始你必須設一個默認值,timestamp
當前的時間戳。在這咱們須要注意的一點是:最好在down()
加上下面的代碼,以防某天咱們須要刪除Users這個表。
public function down() { Schema::drop('users'); }
上面的都作好之後,執行一下下面這一句神奇的命令:
php artisan migrate
有圖有真相:
終於,咱們的前奏搞完了,能夠正式來魯Laravel了。
直接在laravel
目錄執行:
php artisan serve
打開瀏覽器,輸入localhost:8000
,回車,Bingo!
OK,先給本身三十秒的掌聲時間,若是你順利地走到了這一步的話。恭喜你,你已經進入Laravel的大門,更多驚喜咱們再一一道來.....
好了,咱們如今開始了,首先在app/views/
文件夾下建立一個layouts
文件夾,再再這個文件夾下新建一個php文件,命名爲main.blade.php
,在這個文件裏寫上下面這些代碼:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>發現Laravel 4之美</title> </head> <body> </body> </html>
PS:
layouts
文件夾一般用來存放視圖文件的功用部分,好比一些網頁的頭部<header>
和尾部<footer>
,這裏就是存放了頭部<header>
部分
感受main.blade.php
的名字很奇怪?不用擔憂,Laravel的視圖文件命名遵循filename.blade.php
的規則,由於Laravel是用Blade這個模板引擎解析的,你不用深究,就照着上面的名字規則來命名視圖文件就OK
爲視圖文件添加CSS樣式:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>發現Laravel 4之美</title> {{HTML::style('packages/bower_components/bootstrap/dist/css/bootstrap.min.css') }} {{ HTML::style('css/main.css')}} </head> <body> </body> </html>
沒錯,就是在原來的main.blade.php
的基礎上添加兩行代碼;而後咱們來建立咱們的main.css
,這個主要是用來放咱們本身定義的樣式。在public
文件夾下建立css
文件夾,在css
文件夾建立main.css
文件,大功告成。
添加導航欄。在main.blade.php
文件的<body>
標籤中加上如下代碼:
<body> <div class="navbar navbar-inverse navbar-fixed-top"> <div class="container"> <div class="navbar-header"> <a class="navbar-brand hidden-sm" href="/">Laravel新手上路</a> </div> <ul class="nav navbar-nav navbar-right hidden-sm"> <li>{{ HTML::link('users/register', '註冊') }}</li> <li>{{ HTML::link('users/login', '登錄') }}</li> </ul> </div> </div> </body>
上面只是引用了一些簡單的Bootstrap的class,也沒什麼難的,不用傷心。
到這裏基本的功用部分就結束了,可是咱們的追求從不會這麼low,因此爲了更好地與用戶交互,咱們但願在用戶進行某個操做以後給出一些反饋,好比註冊成功的時候說:少年,你已成功註冊本站,恭喜恭喜。等,因而乎,咱們再爲main.blade.php
添加一點點代碼:
<div class="container"> @if(Session::has('message')) <p class="alert">{{ Session::get('message') }}</p> @endif </div>
爲了現實這些反饋信息給用戶,咱們得使用Session::get('message')
方法,固然,咱們得首先從邏輯上判斷一下這個message
是否存在,因此這裏用了一個簡單的if
判斷。
在blade引擎的視圖中
if
的使用格式是
@if(conditions) #code... @endif
到這裏就結束了麼?NO,若是到這裏就結束的話,其餘的視圖文件是怎麼插入main.blade.php
的<body></body>
之間的呢?因此,不要忘了還有一個重要的事:{{ $content }}
,因而乎,上面的代碼就變成了這樣:
<div class="container"> @if(Session::has('message')) <p class="alert">{{ Session::get('message') }}</p> @endif {{ $content }} </div>
{{ $content }}
在這裏就是表示其餘的視圖文件內容,你能夠在理解上將其餘的視圖看成一個字符串來理解,只不過這個字符串很長,並且剛好包含了HTML標籤而已。下面你將體會到這種想法。
建立完咱們的公用視圖main.blade.php
後,咱們先來爲main.css
添加咱們的CSS樣式:
body { padding-top: 60px; } .form-signup, .form-signin { margin: 0 auto; }
由於咱們在main.blade.php
文件中使用了<div class="navbar navbar-inverse navbar-fixed-top">
,Bootstrap的navbar
高爲40px
,因此我將body
樣式設爲padding-top: 60px;
避免下面的註冊表單被navbar
覆蓋。
終於要進入正題
我擦,前面搞這麼久才進入正題?對的,我說的是從這裏開始咱們就開始進入Laravel的Controller世界了,別高潮那麼快,更好的事情還在後頭。
來到app/controllers
文件夾,並在這裏建立UsersController.php
文件並加入下面的代碼:
<?php class UsersController extends BaseController { } ?>
而後告訴咱們的UsersController
咱們要使用main.blade.php
做爲咱們的layouts,因此:
<?php class UsersController extends BaseController { protected $layout = "layouts.main"; } ?>
這裏使用了路徑別名,你不用layouts/main.blade.php
,你只須要layouts.main
,Laravel會自動幫你找到layouts
下相應的文件。
接着爲咱們的UsersController
添加用戶註冊時訪問到的方法:
public function getRegister() { $this->layout->content = View::make('users.register'); }
這裏咱們將content
制定爲users/register.blade.php
文件(咱們等下會建立這個文件),若是你夠細心的話,你可能就注意到了:這裏的content
就是上面咱們在main.blade.php
寫的{{ $content }}
,也就是說等下渲染視圖的時候,咱們的users/register.blade.php
文件會替換掉main.blade.php
的{{ $content }}
進行顯示。如今,清晰了沒?還不清晰?隨時聯繫我....若是你不嫌我長得醜的話。
天然而然的,咱們如今要作的就是建立users/register.blade.php
這個文件了,來到views
文件夾 ,建立一個新的文件夾users/
,再在裏面新建register.blade.php
,寫上下面這些內容:
{{ Form::open(array('url'=>'users/create', 'class'=>'form-signup')) }} <div class="container"> <div class="row"> <div class="col-md-4 col-md-offset-4"> <div class="panel panel-default"> <div class="panel-heading"> <h3 class="panel-title">歡迎註冊</h3> </div> <div class="panel-body"> {{ Form::open(array('url'=>'users/create', 'class'=>'form-signup')) }} <ul> @foreach($errors->all() as $error) <li>{{ $error }}</li> @endforeach </ul> <fieldset> <div class="form-group"> {{ Form::text('username', null, array('class'=>'form-control', 'placeholder'=>'用戶名')) }} </div> <div class="form-group"> {{ Form::text('email', null, array('class'=>'form-control', 'placeholder'=>'郵箱')) }} </div> <div class="form-group"> {{ Form::text('password', null,array('class'=>'form-control', 'placeholder'=>'密碼')) }} </div> <div class="form-group"> {{ Form::text('password_confirmation', null,array('class'=>'form-control', 'placeholder'=>'確認密碼')) }} </div> {{ Form::submit('立刻註冊',array('class'=>'btn btn-large btn-success btn-block')) }} </fieldset> {{ Form::close() }} </div> </div> </div> </div> </div>
這裏咱們使用了Laravel的Form類來建立咱們的註冊表單,首先調用open()方法,表示建立表單的開始,而且咱們也爲其經過數組的形式傳人一些參數,url表示表到提交的地址,class就是表示CSS樣式的類。接下來咱們使用了:
@foreach($errors->all() as $error) <li>{{ $error }}</li> @endforeach
@foreach循環將每一個表單的錯誤信息輸出。由於咱們在讓用戶註冊的時候老是要驗證一下用戶輸入的數據是否知足咱們設定的規則,好比郵箱這一欄咱們規定它必須爲正確的郵箱形式,而若是用戶沒有輸入正確的郵箱格式,咱們就會返回錯誤信息給用戶看。That's it.
再下來須要說明的就是幾個Form輸入框的建立方式了:
{{ Form::text() }} //建立type=text 輸入框 {{ Form::password() }}//建立type=password 輸入框 {{ Form::submit() }}//建立type=submit 輸入框
各個輸入框的值咱們都設爲null,由於咱們用placeholder來更好的替代了,第三個參數是你能夠經過一個數組來傳人相應的HTML選項來實現咱們的佈局,好比上面的array('class'=>'form-control', 'placeholder'=>'確認密碼')
等。
最後別忘咱們要用{{ Form::close() }}
來結束表單。
到這裏咱們就把註冊頁面搞定了,緊接下來就是正確地設置好咱們的路由以使咱們能正確訪問到咱們的getRegister()
方法。因而,帶着神聖的使命感,咱們打開app/routes.php
這個文件,首先能夠將裏面的:
Route::get('/', function() { return View::make('hello'); });
這幾行代碼幹掉(你能夠注視掉或者直接刪了,建議是註釋),而後再添上下面這一行代碼;
Route::controller('users', 'UsersController');
注意到第一個參數users
沒,這個告訴就是說咱們在訪問UsersController
的方法的時候咱們遵循下面這個格式:
/users/actionName
好比咱們想訪問UsersController
的getRegister()
,咱們能夠在瀏覽器地址欄輸入的格式是:
/users/register
因而,打開你的瀏覽器,在地址欄輸入:
http://localhost:8000/users/register
見證奇蹟吧。是否是很爽!哈哈哈。
若是如今你在這個註冊表單添上相應的註冊信息,而後點擊註冊的話,你會獲得一個意外的錯誤:NotFoundHttpException
!那是由於咱們尚未爲註冊表單寫提交地址:users/create
。因此咱們天然要來到UsersController
中,爲其添上postCreate()
:
public function postCreate() { }
這樣咱們就把地址users/create
正確地搞定了,只是咱們尚未爲其添加相應的條件判斷語句,由於咱們首先要在這裏說明一點就是:getRegister()
和postCreate()
的不一樣,沒錯前面的get
或post
就是表明http的提交方式,咱們在註冊表單中使用的是post
方法,因此這裏要使用postCreate()
。
說明上面的細節以後,咱們還要作一件很是重要的事:表單驗證。便是先在用戶提交表單的時候驗證其輸入數據的合法性,以便於咱們在數據庫中能存儲正確的數據,這裏就聯繫到前面的:
@foreach($errors->all() as $error) <li>{{ $error }}</li> @endforeach
這裏的$error
就是咱們在用戶輸入數據不合法的時候返回給用戶的錯誤提示信息。因此,咱們如今app/models/User.php
中添加咱們的表單驗證規則(我通常將驗證規則放在模型modal中):
public static $rules = array( 'username'=>'required|alpha|min:2', 'email'=>'required|email|unique:users', 'password'=>'required|alpha_num|between:6,12|confirmed', 'password_confirmation'=>'required|alpha_num|between:6,12' );
說明一下上面的一些規則表示什麼意思:
required:必填的,不能爲空 alpha:字母 email:郵件格式 unique:users:惟一,參考users表的設置 alpha_num:字母或數字 between:長度位於哪兩個數字之間 confirmed:須要確認的
在咱們有了驗證規則,咱們再來完善咱們的postCreate()
,即爲其添加一些條件判斷使用戶在註冊時能夠保存用戶的註冊信息和進一步引導用戶到登錄頁面:
咱們來一步一步地理清思路:首先判斷用戶提交的數據是否經過了驗證
public function postCreate() { $validator = Validator::make(Input::all(), User::$rules); if ($validator->passes()) { // 驗證經過就存儲用戶數據 } else { // 驗證沒經過就顯示錯誤提示信息 } } }
上面咱們經過Input::all()
來獲取表單傳過來的值,又調用User::$rules
來得到驗證規則,最後經過把這兩個以參數的形式傳入Validator::make()
實現驗證,下面的判斷語句就很清晰了,驗證經過後幹嗎,沒經過又該幹嗎。思路清晰就OK。
接着咱們再來完善咱們的postCreate()
代碼:
if ($validator->passes()) { $user = new User;//實例化User對象 $user->username = Input::get('username'); $user->email = Input::get('email'); $user->password = Hash::make(Input::get('password')); $user->save(); return Redirect::to('users/login')->with('message', '歡迎註冊,好好玩耍!'); } else { // 驗證沒經過就顯示錯誤提示信息 }
上面的咱們經過Input::get('fieldName')
來得到相應的表單輸入框的值,這裏須要注意的是咱們對密碼進行了加密,由於咱們都是棒棒的工程師,不會像以前的CSDN同樣保存明文密碼的,因此在密碼這一欄咱們使用Hash::make()
來加密傳入的密碼。而後咱們經過$user->save()
來將咱們的數據保存到數據庫中。數據保存以後,咱們用Redirect::to()
將頁面跳轉到users/login
,並經過width將註冊成功的信息返回給用戶。
Redirect::to()
的參數規則是:controller/action
。前面是控制起,後面就是具體的方法名。
上面是驗證經過的狀況,如今咱們看看驗證沒有經過的狀況:
if ($validator->passes()) { $user = new User;//實例化User對象 $user->username = Input::get('username'); $user->email = Input::get('email'); $user->password = Hash::make(Input::get('password')); $user->save(); return Redirect::to('users/login')->with('message', '歡迎註冊,好好玩耍!'); } else { return Redirect::to('users/register')->with('message', '請您正確填寫下列數據')->withErrors($validator)->withInput(); }
這裏若是用戶沒有經過驗證,我讓其重定向到註冊頁,並經過withErrors($validator)
將錯誤信息傳到註冊頁面,經過withInput()
將沒有輸錯的數據也傳給註冊頁面(正確來講是傳給register方法,不過你能夠根據上面那樣理解,我的以爲也還OK),這樣一來,咱們就有了錯誤信息和一些正確的表單信息(不用用戶屢次輸入),以提升整個過程的用戶體驗。
再進一步,咱們在開發的時候永遠不要忘記一件很重要的事:安全。那麼在這裏咱們須要POST提交表單,咱們就要保證它不會被CSRF攻擊,解決這個問題咱們須要在UsersController
裏添加下面的代碼:
public function __construct() { $this->beforeFilter('csrf', array('on'=>'post')); }
構造方法請放在其餘方法前面。
接下來的一步就是建立login的視圖文件了,咱們依舊來到咱們最熟悉的views/users/
下,新建文件名爲login.blade.php
的文件,在裏面放上如下的代碼:
<div class="container"> <div class="row"> <div class="col-md-4 col-md-offset-4"> <div class="panel panel-default"> <div class="panel-heading"> <h3 class="panel-title">歡迎登陸</h3> </div> <div class="panel-body"> {{ Form::open(array('url'=>'users/signin', 'class'=>'form-signin')) }} <fieldset> <div class="form-group"> {{ Form::text('email', null, array('class'=>'form-control', 'placeholder'=>'郵箱')) }} </div> <div class="form-group"> {{ Form::password('password', array('class'=>'form-control', 'placeholder'=>'密碼')) }} </div> {{ Form::submit('立刻登陸',array('class'=>'btn btn-large btn-success btn-block')) }} </fieldset> {{ Form::close() }} <hr/> </div> </div> </div> </div> </div>
這裏的一些要點跟register.blade.php
同樣,你不明白的話能夠看看前面的。而後咱們須要在UsersController
裏面定義getLogin()
方法:
public function getLogin() { $this->layout->content = View::make('users.login'); }
這裏也是指定了content
的模版爲users/login.blade.php
,道理跟前面同樣。
這時候咱們就能夠註冊新用戶了,若是你的瀏覽器還保留在http://localhost:8000/users/register
你能夠試着輸入你的用戶名,郵箱,密碼來註冊一個,固然你也能夠故意輸錯,看看會有什麼信息返回給你。enjoy!
正常狀況下,你註冊完以後就吼跳到登陸界面(已經寫好了),可是咱們在登陸的時候也須要驗證,若是你仔細看上面的login.blade.php
的話,你會發現咱們在這裏將用戶的登陸表單提交地址設置爲'url'=>'users/signin'
,因此接下來的一步就是爲UsersController
補充postSignin()
方法:
public function postSignin() { if (Auth::attempt(array('email'=>Input::get('email'), 'password'=>Input::get('password')))) { return Redirect::to('users/dashboard')->with('message', '歡迎登陸'); } else { return Redirect::to('users/login')->with('message', '用戶名或密碼錯誤')->withInput(); } }
這裏咱們使用Auth
類來驗證用戶輸入的信息是否和數據庫的信息一致,若是驗證經過,那麼咱們就將用戶重定向到users/dashboard
,若是沒經過,就從新跳回登陸頁,狀況跟註冊時候幾乎如出一轍,我相信你看得懂。
既然是重定向到users/dashboard
那麼咱們就來寫寫getDashboard()
方法,到這裏可能不用我說你都知道應該在UsersController
添加下面的代碼:
public function getDashboard() { $this->layout->content = View::make('users.dashboard'); }
這裏再多說一句,這個Dashboard的頁面通常是在登陸後才能看到的,爲了限制一些沒登陸的人處處亂逛,咱們只須要在UsersController
中的構造函數加一行代碼,變成這樣的:
public function __construct() { $this->beforeFilter('csrf', array('on'=>'post')); $this->beforeFilter('auth', array('only'=>array('getDashboard'))); }
如今邏輯是否是很清晰,咱們接下來的一步天然是建立dashboard.blade.php
文件了,這個從getDashboard()
看出咱們依然是將這個視圖文件存在views/users/
目錄下,咱們就簡單地在dashboard.blade.php
寫上幾行入門級的HTML:
<div class="welcome"> <center> <a href="http://www.jellybool.com" target="_blank"> <img src="https://wt-prj.oss.aliyuncs.com/766e22da1e8c467a8af35d90c9185409/7680dd9d-c0e4-42ea-86b8-ddd63d07faa6.png" > </a> </center> <center><h1>歡迎來到管理面板!</h1></center> </div>
寫到這裏咱們還不能登陸,由於在Laravel中auth
過濾(filter)會默認將沒登陸的用戶重定向到/login
,但咱們須要的是重定向到users/login
,因此咱們須要自定義咱們的filter
規則,打開app/filter.php
,在代碼的開始加上下面的代碼:
Route::filter('auth', function() { if (Auth::guest()) return Redirect::guest('users/login'); });
到這裏就大功告成了,若是你以前註冊了一個用戶,請用你的郵箱和密碼到
http://localhost:8000/users/login
嘗試登陸一下,你會發現:Bingo!!!登陸進去了!
可是細心的你發現了沒,咱們還有一個須要完善的地方.....沒錯!就是咱們的導航,咱們已經登陸進去了,它仍是顯示登陸
和註冊
,不科學啊!因此回到最初咱們的main.blade.php
在連接部分咱們將它改成:
<ul class="nav navbar-nav navbar-right hidden-sm"> @if(!Auth::check()) <li>{{ HTML::link('users/register', '註冊') }}</li> <li>{{ HTML::link('users/login', '登錄') }}</li> @else <li>{{ HTML::link('users/logout', '退出') }}</li> @endif </ul>
沒錯,咱們爲導航這裏加入了條件判斷語句,若是用戶沒有經過Auth::check()
,也就是沒有登陸的話,咱們顯示登陸
和註冊
,若是登陸了就顯示退出
,
既然有了users/logout
這個連接,那麼咱們就會想到在UsersController
寫這個getLogout()
方法,並且這個方法是負責清理用戶的登陸信息的,因此:
public function getLogout() { if(Auth::check()) { Auth::logout(); } return Redirect::to('users/login')->with('message','你如今已經退出登陸了!'); }
這裏咱們Auth::logout()
將用戶的登陸信息(主要就是session信息)清除掉,而後再將用戶重定向到登陸界面。
這個小教程寫到這裏就基本結束了,但願各位玩的愉快。最後多說一句:編程是咱們最容易學習的超能力,永遠要相信本身能夠改變世界!
Thank You all.