欢迎各位兄弟 发布技术文章

这里的技术是共享的

You are here

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

shiping1 的头像

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

 

一、注册路由


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

二、修改控制器

添加 create() 方法:


  1. public function create(){

  2. return view('articles.create');

  3. }

三、创建视图

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

3.1 引入HTML库依赖  安装建议  见  /node/6895  最后部分

命令行运行:


  1. composer require illuminate/html

(还有一种安装方法 是 在 composer.json 里面 添加  

"require": {
   "laravel/framework": "5.0.*",
   "illuminate/html": "^5.0"
},

然后 composer update (不过这个不推荐)


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

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


  1. // 添加到 'Illuminate\View\ViewServiceProvider', 后面

  2. 'Illuminate\Html\HtmlServiceProvider',

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


  1. // 添加到 'View' => 'Illuminate\Support\Facades\View', 之后

  2. 'Form' => 'Illuminate\Html\FormFacade',

  3. 'Html' => 'Illuminate\Html\HtmlFacade',

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

3.2 创建视图文件

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


  1. @extends('main')

  2.  

  3. @section('content')

  4. <h1>Wirte a New Article</h1>

  5.  

  6. <hr/>

  7.  

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

  9.  

  10. {!! Form::close() !!}

  11. @stop

3.3 调整路由顺序

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


  1. ModelNotFoundException in Builder.php line 125:

  2. No query results for model [App\Article].

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


  1. Route::get('articles', 'ArticlesController@index');

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

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

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


  1. Route::get('articles', 'ArticlesController@index');

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

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

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

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

laravel-form

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

3.4 修改视图

下面修改视图文件:


  1. @extends('main')

  2.  

  3. @section('content')

  4. <h1>Wirte a New Article</h1>

  5.  

  6. <hr/>

  7.  

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

  9. <div class="form-group">

  10. {!! Form::label('title', 'Title:') !!}

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

  12. </div>

  13.  

  14. <div class="form-group">

  15. {!! Form::label('body', 'Body:') !!}

  16. {!! Form::textarea('body', null, ['class' => 'form-control']) !!}

  17. </div>

  18.  

  19. <div class="form-group">

  20. {!! Form::submit('Add Article', ['class' => 'btn btn-primary form-control']) !!}

  21. </div>

  22. {!! Form::close() !!}

  23. @stop

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


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

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

接着修改视图文件:


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

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

3.5 修改控制器文件


  1. //文件顶部删除改行 use Illuminate\Http\Request;

  2. //添加下面的 Facade

  3. use Request;

  4.  

  5. //Controller中添加 store() 方法

  6. public function store(){

  7. $input = Request::all();

  8.  

  9. return $input;

  10. }

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

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


  1. public function store(){

  2. $input = Request::all();

  3.  

  4. Article::create($input);

  5.  

  6. return redirect('articles');

  7. }

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


  1. // 使用Carbon

  2. use Carbon\Carbon;

  3.  

  4. //修改store()方法

  5. public function store(){

  6. $input = Request::all();

  7. $input['published_at'] = Carbon::now();

  8.  

  9. Article::create($input);

  10.  

  11. return redirect('articles');

  12. }

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


  1. public function index(){

  2. //方法一

  3. $articles = Article::latest('published_at')->get();

  4. //方法二

  5. //$articles = Article::orderBy('published_at', 'desc')->get();

  6.  

  7. return view('articles.index', compact('articles'));

  8. //或者也可以使用这种方式

  9. //return view('articles.index')->with('articles', $articles);

  10. }

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

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


 
转载请注明来源:[Laravel 5 教程学习笔记] 十、Forms 表单 - Specs' Blog-就爱PHP

本文共 20 个回复


    •  

      dodo 2015/11/10 17:52

      dodo 看了后面第12章,验证那块,就明白了嘿嘿 :grin:

    •  

      Specs  2015/07/29 11:43

      我想去打猎 你好像没看完我写的那个,看看3.3和3.4就知道了

    •  

      Specs  2015/07/29 11:31

      我想去打猎 提交变成 404 说明你提交的 action 不对吧,或者没有加那个隐藏域

    •  

      Specs  2015/07/29 10:55

      我想去打猎 按正常那种写就行,只不过这个用了Bootstrap的样式,把 action 写对,然后加上那个隐藏域

    •  

      Specs  2015/07/29 11:00

      我想去打猎 用这个HTML库的话,你可以看下这个文件 github.com/illuminate/html/blob/master/FormBuilder.php

    •  

      Specs  2015/05/25 10:31

      yida 我是按一个英文的视频教程写的

    •  

      王晓东 2016/04/18 17:43

      yida 你要调用Use::Carbon;

    •  

      yida 2015/05/24 23:50

      請問為什麼沒辦法使用Carbon::now();FatalErrorException in ArticlesController.php line 25:Class 'App\Http\Controllers\Carbon' not found

    •  

      yida 2015/05/24 23:57

      我看到了!! use Carbon\Carbon;抱歉, 问了一个蠢问题博主的教学很详细,我是php新手也能看懂,感谢!!

    •  

      wenber 2015/07/07 18:40

      楼主,//文件顶部删除改行 use Illuminate\Http\Request;//添加下面的 Facadeuse Request;能说一下,这是为什么吗?是用刚引入的html库将laravel本身的request替代了吗?

    •  

      我想去打猎 2015/07/29 10:48

      请问不引用html 库依赖怎么做form表单 {!! Form::label('title', 'Title:') !!} {!! Form::text('title', null, ['class' => 'form-control']) !!} 几乎看不懂。。。。。

    •  

      我想去打猎 2015/07/29 11:17

      @extends('main') @section('content') Wirte a New Article Title: Body: 提交 @stop我把表单改成这样,其它都是按照文章里做的 只是没用使用html库 ,提交数据的时候就404了。。。路由顺序都调了,不知哪里出错了。。。 :cry: 初学者

    •  

      我想去打猎 2015/07/29 11:19

      额 我在评论里提交源代码 就变成别的了 看不到源代码

    •  

      我想去打猎 2015/07/29 11:35

      :grin: 终于找到原因了 是我action 路径一直没搞对 用form表单的话 action默认 会把路径放到article/create 所以必须要写成create的相对路径 上级目录 action=“../articles”

    •  

      dodo 2015/11/10 13:52

      感谢楼主的guide,很喜欢并且实用只是自己有个地方不太明白。为什么需要用Request?--------------//文件顶部删除改行 use Illuminate\Http\Request;//添加下面的 Facadeuse Request;--------------- Illuminate\Http\Request; 和 Request类有什么区别??

    •  

      shea 2015/11/12 16:58

      博主,又有一个蛋疼的问题,貌似composer require illuminate/html 一直都没成功,我update了好几次也没用,一直出现 Class 'Collective\Html\HtmlServiceProvider' not found的错误

    •  

      zeroone 2016/04/07 17:44

      laravel 5.2 illuminate/html 已经不用官方应该是 laravelcollective/html laravelcollective.com/docs/5.2/html


    普通分类: