Laravel入門(四)

配置資源路由

將當前路由配置中的 Route::get('article', 'ArticleController@index'); 改成 Route::resource('article', 'ArticleController');

其中Route::resource('article', 'ArticleController');是RESTful 資源控制器它約定了一系列對某一種資源進行“增刪改查”操作的路由配置,讓我們不再需要對每一項需要管理的資源都寫 N 行重復形式的路由。我們只要寫下這條路由就可以得到下面7條路由配置

Paste_Image.png

左邊是 HTTP 方法,中間是 URL 路徑,右邊是 控制器中對應的函數,只要某個請求符合這七行中某一行的要求,那么這條請求就會觸發最后一列的方法。

新增 Article

兩個動作

  • 獲取“新增Article”的頁面
  • 提交數據到后端,插入一篇文章到數據庫。

獲取“新增Article”的頁面

第二行路由可以滿足我們的要求

在ArticleController 中寫入:

public function create()  
{
    return view('admin/article/create');
}

新增視圖文件 learnlaravel5/resources/views/admin/article/create.blade.php

@extends('layouts.app')

@section('content')
<div class="container">  
    <div class="row">
        <div class="col-md-10 col-md-offset-1">
            <div class="panel panel-default">
                <div class="panel-heading">新增一篇文章</div>
                <div class="panel-body">

                    @if (count($errors) > 0)
                        <div class="alert alert-danger">
                            <strong>新增失敗</strong> 輸入不符合要求<br><br>
                            {!! implode('<br>', $errors->all()) !!}
                        </div>
                    @endif

                    <form action="{{ url('admin/article') }}" method="POST">
                        {!! csrf_field() !!}
                        <input type="text" name="title" class="form-control" required="required" placeholder="請輸入標題">
                        <br>
                        <textarea name="body" rows="10" class="form-control" required="required" placeholder="請輸入內容"></textarea>
                        <br>
                        <button class="btn btn-lg btn-info">新增文章</button>
                    </form>

                </div>
            </div>
        </div>
    </div>
</div>  
@endsection

?

提交數據到后端

視圖文件中有一個表單:

<form action="{{ url('admin/article') }}" method="POST">  
    {!! csrf_field() !!}
    <input type="text" name="title" class="form-control" required="required" placeholder="請輸入標題">
    <br>
    <textarea name="body" rows="10" class="form-control" required="required" placeholder="請輸入內容"></textarea>
    <br>
    <button class="btn btn-lg btn-info">新增文章</button>
</form>  

其中csrf_field。這是 Laravel 中內置的防止應對 CSRF 攻擊的防范措施,任何 POST PUT PATCH 請求都會被檢測是否提交了 CSRF 字段。

{!! csrf_field() !!}

后端接收數據

新建store方法:

public function store(Request $request) // Laravel 的依賴注入系統會自動初始化我們需要的 Request 類  
{
    // 數據驗證
    $this->validate($request, [
        'title' => 'required|unique:articles|max:255', // 必填、在 articles 表中唯一、最大長度 255
        'body' => 'required', // 必填
    ]);

    // 通過 Article Model 插入一條數據進 articles 表
    $article = new Article; // 初始化 Article 對象
    $article->title = $request->get('title'); // 將 POST 提交過了的 title 字段的值賦給 article 的 title 屬性
    $article->body = $request->get('body'); // 同上
    $article->user_id = $request->user()->id; // 獲取當前 Auth 系統中注冊的用戶,并將其 id 賦給 article 的 user_id 屬性

    // 將數據保存到數據庫,通過判斷保存結果,控制頁面進行不同跳轉
    if ($article->save()) {
        return redirect('admin/article'); // 保存成功,跳轉到 文章管理 頁
    } else {
        // 保存失敗,跳回來路頁面,保留用戶的輸入,并給出提示
        return redirect()->back()->withInput()->withErrors('保存失??!');
    }
}

編輯 Article

使用edit和updata兩個方法
模板復制create的模板 主要修改的地方

<form action="{{ url('admin/article/'.$article->id) }}" method="POST">
                        {{ method_field('PUT') }}
                        {!! csrf_field() !!}

PHP文件修改:

public function update($id,Request $request)
{


$this->validate($request, [
        'title' => 'required|unique:articles|max:255', // 必填、在 articles 表中唯一、最大長度 255
        'body' => 'required', // 必填
    ]);

    $article          = Article::findOrFail($id);
    $article->title   = $request->get('title');
    $article->body    = $request->get('body');
    $article->user_id = $request->user()->id;

    if ($article->save()) {
        return redirect('admin/article');
    } else {
        return redirect()->back()->withInput()->withErrors('保存信息失敗!');
    }
     //dd($request->all());
}

刪除 Article

<form action="{{ url('admin/article/'.$article->id) }}" method="POST" style="display: inline;">  
    {{ method_field('DELETE') }}
    {{ csrf_field() }}
    <button type="submit" class="btn btn-danger">刪除</button>
</form>  

其中{{ method_field('DELETE') }}的意思簡單的來說就是

Laravel 的請求處理系統要求所有非 GET 和 POST 的請求全部通過 POST 請求來執行,再將真正的方法使用 _method 表單字段攜帶給后端代碼。

在控制器中增加刪除文章對應的是 destroy 方法:

public function destroy($id)  
{
    Article::find($id)->delete();
    return redirect()->back()->withInput()->withErrors('刪除成功!');
}

開始構建評論系統

建立 Model 類和數據表

創建名為 Comment 的 Model 類,并順便創建附帶的 migration,在 learnlaravel5 目錄下運行命令:

php artisan make:model Comment -m

這樣一次性建立了 Comment 類和 20160603220325createcommentstable 兩個文件。修改 migration 文件的 up 方法為:

public function up()  
{
    Schema::create('comments', function (Blueprint $table) {
        $table->increments('id');
        $table->string('nickname');
        $table->string('email')->nullable();
        $table->string('website')->nullable();
        $table->text('content')->nullable();
        $table->integer('article_id');
        $table->timestamps();
    });
}

之后運行命令:

php artisan migrate

建立“一對多關系”

在 Article 模型中增加一對多關系的函數:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Article extends Model  
{
    public function hasManyComments()
    {
        return $this->hasMany('App\Comment', 'article_id', 'id');
    }
}

構建前臺 UI

修改前臺的視圖文件,想辦法把評論功能加入進去。
創建前臺的 ArticleController 類
運行命令:

php artisan make:controller ArticleController

增加路由:

Route::get('article/{id}', 'ArticleController@show');

此處的 {id} 指代任意字符串,在我們的規劃中,此字段為文章 ID,為數字,
給 ArticleController 增加 show 函數:

public function show($id) { return view('article/show')->withArticle(Article::with('hasManyComments')->find($id));}

創建前臺文章展示視圖
新建 learnlaravel5/resources/views/article/show.blade.php
文件:

<!DOCTYPE html>  
<html lang="en">  
<head>  
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <title>Learn Laravel 5</title>

    <link  rel="stylesheet">
    <script src="http://cdn.bootcss.com/jquery/1.11.1/jquery.min.js"></script>
    <script src="http://cdn.bootcss.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>
</head>

    <div id="content" style="padding: 50px;">

        <h4>
            <a href="/"><< 返回首頁</a>
        </h4>

        <h1 style="text-align: center; margin-top: 50px;">{{ $article->title }}</h1>
        <hr>
        <div id="date" style="text-align: right;">
            {{ $article->updated_at }}
        </div>
        <div id="content" style="margin: 20px;">
            <p>
                {{ $article->body }}
            </p>
        </div>

        <div id="comments" style="margin-top: 50px;">

            @if (count($errors) > 0)
                <div class="alert alert-danger">
                    <strong>操作失敗</strong> 輸入不符合要求<br><br>
                    {!! implode('<br>', $errors->all()) !!}
                </div>
            @endif

            <div id="new">
                <form action="{{ url('comment') }}" method="POST">
                    {!! csrf_field() !!}
                    <input type="hidden" name="article_id" value="{{ $article->id }}">
                    <div class="form-group">
                        <label>Nickname</label>
                        <input type="text" name="nickname" class="form-control" style="width: 300px;" required="required">
                    </div>
                    <div class="form-group">
                        <label>Email address</label>
                        <input type="email" name="email" class="form-control" style="width: 300px;">
                    </div>
                    <div class="form-group">
                        <label>Home page</label>
                        <input type="text" name="website" class="form-control" style="width: 300px;">
                    </div>
                    <div class="form-group">
                        <label>Content</label>
                        <textarea name="content" id="newFormContent" class="form-control" rows="10" required="required"></textarea>
                    </div>
                    <button type="submit" class="btn btn-lg btn-success col-lg-12">Submit</button>
                </form>
            </div>

            <script>
            function reply(a) {
              var nickname = a.parentNode.parentNode.firstChild.nextSibling.getAttribute('data');
              var textArea = document.getElementById('newFormContent');
              textArea.innerHTML = '@'+nickname+' ';
            }
            </script>

            <div class="conmments" style="margin-top: 100px;">
                @foreach ($article->hasManyComments as $comment)

                    <div class="one" style="border-top: solid 20px #efefef; padding: 5px 20px;">
                        <div class="nickname" data="{{ $comment->nickname }}">
                            @if ($comment->website)
                                <a href="{{ $comment->website }}">
                                    <h3>{{ $comment->nickname }}</h3>
                                </a>
                            @else
                                <h3>{{ $comment->nickname }}</h3>
                            @endif
                            <h6>{{ $comment->created_at }}</h6>
                        </div>
                        <div class="content">
                            <p style="padding: 20px;">
                                {{ $comment->content }}
                            </p>
                        </div>
                        <div class="reply" style="text-align: right; padding: 5px;">
                            <a href="#new" onclick="reply(this);">回復</a>
                        </div>
                    </div>

                @endforeach
            </div>
        </div>

    </div>

</body>  
</html> 

構建評論存儲功能
我們需要創建一個 CommentsController 控制器,并增加一條“存儲評論”的路由。運行命令:

php artisan make:controller CommentController

控制器創建成功,接下來我們增加一條路由:

Route::post('comment', 'CommentController@store');

給這個類增加 store 函數:

public function store(Request $request)  
{
    if (Comment::create($request->all())) {
        return redirect()->back();
    } else {
        return redirect()->back()->withInput()->withErrors('評論發表失??!');
    }
}

批量賦值

采用批量賦值方法來減少存儲評論的代碼
給 Comment 類增加 $fillable 成員變量:

protected $fillable = ['nickname', 'email', 'website', 'content', 'article_id'];

效果如下

Paste_Image.png
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 文章分類 后臺文章分類列表頁模板導的詳細步驟建立數據表blog_category,并添加相應的文章字段使用php ...
    JoyceZhao閱讀 1,771評論 0 14
  • 0.1配置1.模板繼承2.控制器3.git4.支付寶支付的流程5.路由6.中間件7.請求8.laravel 學習筆...
    云龍789閱讀 841評論 0 5
  • 先說幾句廢話,調和氣氛。事情的起由來自客戶需求頻繁變更,偉大的師傅決定橫刀立馬的改革使用新的框架(created ...
    wsdadan閱讀 3,091評論 0 12
  • [城東老母] 佛陀時代的城東老母是釋迦牟尼佛之鄰居,佛祖雖是無緣大慈,同體大悲,但卻從未與老母說法。一次弟子怪而問...
    一彎港灣閱讀 259評論 0 0
  • 雨是憋了大半天 終于在晚上傾盆而出 約是臨時起意 興致而來的秋水望穿 你是一面之緣 似曾相識的故人 而聽場內琴聲轉...
    五人王閱讀 224評論 2 1