首页 » Web技术 » Laravel » 正文

[Laravel 5 教程学习笔记] 十、Forms 表单

前面介绍了如何显示列表与单个文章,这一节介绍添加发布文章。首先需要有一个表单,然后需要获取表单的数据并插入到数据库,最后跳转到列表页。

一、注册路由

Route::get('articles/create', 'ArticlesController@create');

二、修改控制器

添加 create() 方法:

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

三、创建视图

可以通过普通的 form 标签创建表单,但是这里使用 illuminate/html 库来创建。当然还可以使用 laravelcollective/html 库,其操作可以参考 文档

3.1 引入HTML库依赖

命令行运行:

composer require illuminate/html

安装过程需要一段时间,可以使用《Windows下安装Laravel 5》中介绍的修改 Composer 源的方法加快安装速度。

安装完成之后,修改 config/app.php 文件,把库注册到 Laravel 中。在 providers 字段中添加 HtmlServiceProvider

// 添加到 'Illuminate\View\ViewServiceProvider', 后面
'Illuminate\Html\HtmlServiceProvider',

接着通过 aliases 字段为刚才注册的 Provider 设置别名:

// 添加到 'View'      => 'Illuminate\Support\Facades\View', 之后
'Form'      => 'Illuminate\Html\FormFacade',
'Html'      => 'Illuminate\Html\HtmlFacade',

设置别名后,在控制器中调用的时候就不需要输入 Facade 的完整名称,只需要使用别名即可。

3.2 创建视图文件

接着创建视图文件 resources/views/articles/create.blade.php

@extends('main')

@section('content')
    <h1>Wirte a New Article</h1>

    <hr/>

    {!! Form::open() !!}

    {!! Form::close() !!}
@stop

3.3 调整路由顺序

然后在浏览器访问 http://laravel.dev/articles/create ,发现提示错误:

ModelNotFoundException in Builder.php line 125:
No query results for model [App\Article].

我们已经创建了 create() 方法,而且也创建了视图文件,为什么会出现这个错误呢?查看 route.php 文件:

Route::get('articles', 'ArticlesController@index');
Route::get('articles/{id}', 'ArticlesController@show');
Route::get('articles/create', 'ArticlesController@create');

注意 {id} 是一个通配符,它会匹配 /articles/ 后面所有的内容,所以当我们访问 /articles/create 的时候,它会匹配到 create ,然后进入 ArticlesController@show ,而非 ArticlesController@create 。解决方法很简单,就是调整下这两个路由的顺序:

Route::get('articles', 'ArticlesController@index');
Route::get('articles/create', 'ArticlesController@create');
Route::get('articles/{id}', 'ArticlesController@show');

注:以后设置路由都要注意此问题,顺序从特殊到普通。

再次访问 http://laravel.dev/articles/create,一切正常了。查看页面源文件:

laravel-form

可以看到,模版中那一段代码已经为我们生成了一个 form 表单,method 默认为 POSTaction 为当前RUL,并且生成了一个隐藏域 _token ,它可以让表单提交更加安全。

3.4 修改视图

下面修改视图文件:

@extends('main')

@section('content')
    <h1>Wirte a New Article</h1>

    <hr/>

    {!! Form::open() !!}
        <div class="form-group">
            {!! Form::label('title', 'Title:') !!}
            {!! Form::text('title', null, ['class' => 'form-control']) !!}
        </div>

        <div class="form-group">
            {!! Form::label('body', 'Body:') !!}
            {!! Form::textarea('body', null, ['class' => 'form-control']) !!}
        </div>

        <div class="form-group">
            {!! Form::submit('Add Article', ['class' => 'btn btn-primary form-control']) !!}
        </div>
    {!! Form::close() !!}
@stop

上面的表单会默认提交到 /articles/create ,而我们希望把它提交到 /articles ,所以需要定义一个新的路由:

Route::post('articles', 'ArticlesController@store');

这个路由中,我们需要接受 POST 提交的数据,存入数据库,然后重定向页面。

接着修改视图文件:

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

上面的 url() 也可以用 action() 方法,也可以直接写 /articles

3.5 修改控制器文件

//文件顶部删除改行 use Illuminate\Http\Request;
//添加下面的 Facade
use Request;

//Controller中添加 store() 方法
    public function store(){
        $input = Request::all();

        return $input;
    }

在表单中添加数据,然后提交,可以到底页面以JSON形式返回了刚才输入的数据。可以使用 Request::get('title');Request::get('body'); 来获取单个字段的值。

现在可以使用 Eloquent ORM 中介绍的方法来向数据库中添加数据了。这里我们不担心 SQL注入 等问题,因为Eloquent模型已经帮我们处理好了。并且我们前面已经在 Article 模型中定义了 $fillable 字段,模型只接受该字段中定义了的字段属性,其他的字段都会被过滤掉。

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

        Article::create($input);

        return redirect('articles');
    }

这时再重新提交表单,可以看得成功添加了一条记录。但是我们前面定义的 published_at 还需要处理一下:

// 使用Carbon
use Carbon\Carbon;

//修改store()方法
    public function store(){
        $input = Request::all();
        $input['published_at'] = Carbon::now();

        Article::create($input);

        return redirect('articles');
    }

再次添加数据提交表单,可以看到生成的数据已经完整了。但是还有个小的问题,就是列表页显示的文章顺序是从旧到新的,而我们想要的的从新到旧,所以需要修改 index() 方法:

    public function index(){
        //方法一
        $articles = Article::latest('published_at')->get();
        //方法二
        //$articles = Article::orderBy('published_at', 'desc')->get();

        return view('articles.index', compact('articles'));
        //或者也可以使用这种方式
        //return view('articles.index')->with('articles', $articles);
    }

再次刷新列表页,发现顺序已经变成了从新到旧。

这时,我们再到文章添加页,不填写任何内容,直接提交表单,发现数据库也会多出一条数据,这是因为我们对输入的数据没有做任何的验证,这显然是不行的,下一节将介绍表单验证。

本文共 30 个回复

  • 诗意的边缘 2016/05/25 16:37

    很喜欢你的博文,希望多多更新,另外可以交换友链吗?alan51.com

  • iTuring 2016/12/16 20:06

    谢谢 你的文章帮我解决了一个问题

  • Rikuo 2017/01/11 15:16

    Article::create($input);写入数据库时就报错了MassAssignmentException in Model.php line 421:_token

    • Rikuo 2017/01/11 15:35

      @ Rikuo 我找到原因了,model 没加protected $fillable = ['var1', 'var2', ....];

  • Aaron 2017/01/18 22:53

    楼主你好,你这博客 是你自己开发的还是下载的程序呢?

  • tonbo 2017/04/13 02:33

    mothod 是不是打錯了

12

发表评论