Laravel教程 六:表單 Forms

Laravel教程 六:表單 Forms

此文章爲原創文章,未經贊成,禁止轉載。php

laravel 5.2 以後請使用 laravelcollective/html 替換 illuminate/html. 出現問題先看評論。css

在開始以前,咱們把界面先美化一點點先:html

首先到https://github.com/JellyBool/blog-css-js獲得靜態文件,而後分別修改下面三個文件:laravel

1. app.blade.php 2. articles/index.blade.php 3. articles/show.blade.php 

下面的視圖代碼的修改部分,若是你偷懶,你可使用ctrl+c大法。git

app.blade.php中:將原來@yield('content')的代碼替換成下面的代碼:github

<body>
    <div class="container"> <section class="content"> <div class="pad group"> @yield('content') </div> </section> </div> </body> 

就是在外面多加了個div和一個section。web

再引入這兩個css文件:數據庫

<link rel='stylesheet' href="/css/bootstrap.min.css" type='text/css' media='all'/> <link rel='stylesheet' href="/css/all.css" type='text/css' media='all'/> 

一個是bootstrap,一個是自定義的。bootstrap

articles/index.blade.php文件中,咱們將每一個$article放在<article>標籤中:segmentfault

@foreach($articles as $article)
<article class="format-image group"> <h2 class="post-title pad"> <a href="/articles/{{ $article->id }}"> {{ $article->title }}</a> </h2> <div class="post-inner"> <div class="post-deco"> <div class="hex hex-small"> <div class="hex-inner"><i class="fa"></i></div> <div class="corner-1"></div> <div class="corner-2"></div> </div> </div> <div class="post-content pad"> <div class="entry custome"> {{ $article->intro }} </div> <a class="more-link-custom" href="/articles/{{ $article->id }}"><span><i>更多</i></span></a> </div> </div> </article> @endforeach 

而後最後就是修改articles/show.blade.php視圖文件了:

@section('content')
    <article class="format-image group"> <h2 class="post-title pad"> <a href="/articles/{{ $article->id }}" rel="bookmark"> {{ $article->title }}</a> </h2> <div class="post-inner"> <div class="post-content pad"> <div class="entry custome"> {{ $article->content }} </div> </div> </div> </article> @endsection 

最後看看效果:

替代文字

教程的最後,基本上就能夠完成一個跟本人的blog同樣的小產品。

OK,稍微美化完事後,咱們就能夠進入咱們的主題了:在Laravel中使用Forms表單。

前奏

既然咱們須要建立一篇文章,咱們首先仍是須要將這個建立文章的頁面展現出來吧,就像SF的文章撰寫頁面同樣:http://segmentfault.com/write

因此咱們須要將上一篇的內容走一遍:

註冊路由,在routes.php中增長:

Route::get('article/create','ArticleController@create'); 

咱們指定article/create來加載ArticleControllercreate()方法,而後咱們在ArticleController建立之:

public function create() { return view('articles.create'); } 

這個create()方法直接加載咱們的create.blade.php,因此咱們建立這個視圖文件,來到以前的views/articles/這個文件夾中,新建create.blade.php,寫上這些測試內容:

@extends('app') @section('content') <h1>撰寫新文章</h1> @endsection 

瀏覽器訪問試試http://blog.dev/article/create:

替代文字

一切正確加載以後,咱們就開始着手咱們的Forms使用了,由於建立文章的時候就是須要表單的提交,咱們才能夠將內容接收到,或者說幾乎每個web應用都離不開表單,哪怕是一個註冊,登陸頁面,也都是須要表單的存在,只要你須要收集用戶的信息或者但願有一些UGC,也離不開表單。因此咱們開始使用Laravel的Forms表單吧。

使用illuminate/html

這裏咱們使用一個官方的Package:https://github.com/illuminate/html

咱們經過composer來安裝之:

composer require illuminate/html 

靜待一會,安裝成功以後,咱們們怎麼告訴Laravel,這個Package已經安裝了?或者說咱們怎麼將這個Package跟Laravel的整個體系結合起來呢?

經過提供Service Provider和指定Facade!這樣就能夠很完美地與Laravel結合了。

爲何直接叫Service Provider和Facade?由於我知道怎麼翻譯這兩個才貼切,意會一下

在這裏順便多說一點:在PHP的不少composer的package中,都會有各個框架的不一樣版本,好比說HtmlPurifier這個過濾html和預防xss的package,就有這個Laravel的版本:https://github.com/mewebstudio/Purifier ,或多或少,一些很好的package都會有Laravel的版本。

配置

那麼說回Service Provider和Facade,剛開始可能對Service Provider的概念可能很迷惑,不過你如今徹底沒必要要擔憂,儘管打開config/app.php這個文件看一看:

'providers' => [ Illuminate\Foundation\Providers\ArtisanServiceProvider::class, Illuminate\Auth\AuthServiceProvider::class, Illuminate\Broadcasting\BroadcastServiceProvider::class, //... ] 

你會看到providers這個數組裏面會有一堆Laravel預置的Service Provider,好比咱們常用到得Auth,Controller等,均可以在這裏找到。若是你再往下拉,你還會看到一個這樣的aliases數組:

'aliases' => [ 'App' => Illuminate\Support\Facades\App::class, 'Artisan' => Illuminate\Support\Facades\Artisan::class, 'Auth' => Illuminate\Support\Facades\Auth::class, //... ] 

aliases其實就是快捷方式了,一旦在這裏指定了快捷方式,咱們就能夠在Laravel中全局使用,好比我在代碼中使用Auth,其實背後我就是在用Illuminate\Support\Facades\Auth::class,而後再深刻,咱們實際上是在用providers中的Illuminate\Auth\AuthServiceProvider::class這個。

趁上面寫這些的時候illuminate/html已經下載好了:

替代文字

那麼,按照上面方式,咱們來配置一下咱們的illuminate/html,在config/app.php中的providers添加咱們的Service Provider:

Illuminate\Html\HtmlServiceProvider::class, 

配置完大概長這樣:

替代文字

OK,Service Provider添加好了以後,咱們來添加咱們的Facade,也就是在aliases這個數值後面添加:

'Form' => Illuminate\Html\FormFacade::class, 

配置完以後看看圖片長這樣:

替代文字

使用Forms

這兩個配置好了以後,咱們就能夠在在咱們的create.blade.php這個視圖中使用它了:

@section('content') <h1>撰寫新文章</h1> {!! Form::open() !!} {!! Form::close() !!} @endsection 

咱們加入了兩行{!! Form::open() !!}{!! Form::close() !!},至於{!!相似的符號,請類好比blade的{{,不用太糾結這個。咱們再來訪問http://blog.dev/article/create試試:

咋一看,貌似沒有什麼變化,可是你要查看頁面源碼或者使用開發者工具檢查元素的時候,就能夠發現這個form元素已經建立出來了。

替代文字

不難發現,Laravel的Form還默認爲咱們生成一個hidden的表單(name="_token"),這個是Laravel默認對錶單提交的一點安全支持。在表單提交的時候,Laravel會自動檢查這個_token是否與保存在session中的_token一致,若是不一致,那就直接跳轉回遠頁面,不容許咱們提交數據。

既然Form能夠正常使用了,咱們就能夠建立咱們須要的表單了:

{!! Form::open() !!}
   <div class="form-group"> {!! Form::label('title','標題:') !!} {!! Form::text('title',null,['class'=>'form-control']) !!} </div> <div class="form-group"> {!! Form::label('content','正文:') !!} {!! Form::textarea('content',null,['class'=>'form-control']) !!} </div> <div class="form-group"> {!! Form::submit('發表文章',['class'=>'btn btn-success form-control']) !!} </div> {!! Form::close() !!} 

咱們在{!! Form::open() !!}加入一點東西,先來看看咱們的效果:

替代文字

下面詳細解釋一下:

{!! Form::text('title',null,['class'=>'form-control']) !!} 

拿這個來開刀吧:

  1. Form::text 表示<input type='text' />,還要一堆好比 <input type='password' />等你能夠參照着寫。

  2. 'title' 表示 name='title'

  3. null 表示 value=''

  4. 'class'=>'form-control' 表示class='form-control',這裏能夠指定idplaceholder等一系列你想指定的屬性

然而在Form::open()沒有指定提交路徑的狀況之下,默認是提交到本頁面,這樣對於咱們的清晰分工是不太好的,由於這個頁面就是用來加載視圖的,而對於咱們表單提交的內容,咱們但願用另外的方法來處理,因此咱們來寫一寫吧。

首先在Form::open()指定表單提交的url,直接在加入url:

{!! Form::open(['url'=>'article/store']) !!} 

咱們指定表單post提交到article/store這個地址,而後在routes.php註冊這個路由地址:

Route::post('article/store','ArticleController@store'); 

這裏注意咱們使用了Route::post而不是Route::get,這是用來接收post的路由。而後順利成章,在ArticleController中建立store()方法:

public function store() { $input = Request::all(); return $input; } 

在這個方法中,咱們引入Laravel自帶的Request並使用Request::all(),來獲取全部的用戶提交的過來的內容(這裏指的是:_token,namecontent),若是你想獲取具體某一個表單輸入的內容,可使用Request::get(),好比Request::get('title'),而後直接return來看看用戶到底輸入了什麼內容,咱們來試試:

替代文字

實現建立新文章

OK,成功拿到用戶的提交的內容以後,咱們須要將這些保存到數據庫,怎麼實現呢?在第四篇中,咱們提到的Eloquentcreate()方法如今就能夠派上用場了,因而咱們能夠寫成這樣:

Article::create($input); 

Laravel會自動過濾_token這個提交內容。

可是建立完一篇文章以後,咱們並非想return $input,而是想從新跳轉到某個頁面中,好比咱們的首頁,由於發表完文章,咱們須要看到它是否成功出線在文章列表中,因此咱們最後寫一下:

public function store() { $input = Request::all(); Article::create($input); return redirect('/'); } 

咱們直接使用Laravel的redirect()函數進行跳轉,跳轉到首頁。這個時候,短短的三行代碼就能夠將咱們的邏輯實現了,那麼咱們來試試:

替代文字

貌似成功了?可是咱們以爲這個排序有點問題,最新建立的文章固然是在最上面的了,因此咱們到ArticleControllerindex()方法中稍微修改一下:

public function index() { $articles = Article::latest()->get(); return view('articles.index',compact('articles')); } 

將原來的all()換成了latest()->get(),刷新,

替代文字咱們發現,最新的文章intro居然空白,咱們到數據庫看看: 替代文字

咱們發現,剛剛建立的文章的intro爲空值,而published_at0000-00-00 00:00:00,這不是咱們想要的,爲何會這樣呢?由於咱們在提交過來的時候,並無這兩個數據啊,爲了解決這個問題,首先咱們能夠很暴力得將這兩個數據在使用Article::create($input)以前配置好,好比:

public function store() { $input = Request::all(); //下面增長兩行,順便看看Request::get的使用 $input['intro'] = mb_substr(Request::get('content'),0,64); $input['published_at'] = Carbon::now(); Article::create($input); return redirect('/'); } 

intro字段就直接取content字段的頭64個,而後published_at就默認爲建立的時間。目前開起來代碼有點暴力,可是不失爲一種解決方案,咱們後續會使代碼much cleaner。咱們再來試試:

替代文字

bang,成功了,咱們在看看數據庫:

替代文字

到這裏,咱們建立一篇文章的基本流程就完成了,可是這裏還有一個問題,若是你嘗試在文章建立的頁面什麼都不填,直接提交數據,你看看會發生什麼,若是不肯定,你能夠看看你的數據庫,到底發生了什麼。

##下一節

鑑於最後的問題和牽涉到表單的內容,下一節貌似很瓜熟蒂落就應該說說表單驗證了,在Laravel中就是Request Validation。

最後,

Happy Hacking

相關文章
相關標籤/搜索