Laravel教程 五:MVC的基本流程

此文章为原创文章,未经同意,禁止转载。

期间受到很多私事影响,终于还是要好好写写laravel的教程了。

上一篇我们说了数据库和Eloquent的基本用法,如计划一样,这一篇文章我们说说Laravel中Model,Controller,Views的工作流程,也就是下面这个顺序:

1.注册路由 ---> 2.创建控制器 ---> 3. 控制器中获取数据库数据 ---> 4.在视图中展示数据

英文的表达可能会更加贴切一点:

1.register routes ---> 2.make a controller ---> 3.fetch data from database ---> 4. load a view to display data

在laravel中,最常见的流程就是这个样子的,我们在实现某个功能的时候,通常就是走上面的这个流程。比如我们这个blog项目中,我们需要实现下面的功能:

1. 展示所有的文章  // blog首页
2. 展示一篇文章   //文章详情页
3. 创建一篇文章   // 文章发布页面
4. 修改一篇文章  // 文章修改页面
5. 删除一篇文章  // 后台管理

在这一篇文章中,我们集中精力解决一下第一个功能,所以我们按照上面的流程来走一遍:

PS : 上次我们使用artisan tinker这个工具在命令行中对数据库的数据进行了CRUD,现在就要将这些应用到MVC当中了。

注册路由

我们这里会从头开始,也就是会先删除app/Http/Controllers/ArticleController.php这个文件

在系列文章的第二篇当中,我们在app/Http/routes.php中注册了我们首页的路由:

Route::get('/','ArticleController@index');

可以直接使用这个路由,所以我们可以进入下一步。

创建控制器

这里需要注意的是,如果你使用了Homestead,请先ssh登录到你的虚拟机中执行命令;还有就是,请先删除之前课程遗留的ArticleController,如果你想偷懒,可以跳过这一步

创建控制器的时候你可以手动创建,不过还是推荐使用artisan这个命令行工具,在项目目录之下,命令行执行:

php artisan make:controller ArticleController --plain

这里需要说明的是--plain这个参数表明只要一个简单的controller,里面不需要生成一堆如show(),create()等方法。

控制器中获取数据库数据

打开这个重新创建的ArticleController.php:

class ArticleController extends Controller
{

    public function index()
    {
        $articles = Article::all();

        return $articles;
    }
}

我们创建一个index()方法,这是因为我们在routes.php当中注册的路由指定要加载ArticleControllerindex()方法,我们在index()方法中使用Article::all()将数据库中articles这张表中的所有的记录查找出来,直接返回。

我们用浏览器来访问试试,会看到类似下面这个情况:

对,如你看到的一样,如果你直接返回查找到得数据,Laravel会默认将这些数据转换成json格式,因为laravel可能是出于这样的考虑:一般这种情况下地返回,通常都是在创建api功能,比如你为你的一个手机App写的api一样,json数据无疑是很好的选择。

顺便安利一下大家使用百度团队的这个FeHelper这个chrome插件:

https://github.com/zxlie/FeHelper

但是在这里我们并不是想直接返回json,取而代之的是,我们的目的是加载视图,将数据展示出来。所以这就是我们下一步的工作了

在视图中展示数据

这里我们首先需要修改的是ArticleController中的index()方法:

public function index()
{
    $articles = Article::all();

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

我们只是修改了return这一行的代码,使用view()方法加载视图,这个视图就是位于resources/views/articles/中的index.blade.php(我们还没有创建),最后使用compact('articles')将数据传给视图文件:关于这个视图传递变量的问题,你可以参考教程的第三篇

然后,我们需要创建我们的视图文件,在resources/views/articles/下创建index.blade.php文件:

@extends('app')
@section('content')
 <h1>这是index.blade.php</h1>
@endsection

写上上面的内容,关于视图文件的blade模板,可以参考教程的第三篇,然后浏览器访问一下看看:

视图文件正确之后,我们需要将传递给视图的$articles变量的内容展示出来:

@extends('app')
@section('content')
    @foreach($articles as $article)
        <h1>{{ $article->title }}</h1>
        <p>{{ $article->intro }}</p>
        <hr>
    @endforeach
@endsection

我们使用@foreach来将所有的文章循环出来,浏览器访问看看:

这里我们的首页展示也就基本完成了,然而在我们的实际blog中,我们会在每个标题出给出我们的文章链接,也就是为每个文章添加一个详情展示的页面,用户点击文章的链接之后,我们展示相应的文章详情。我们来实现这个功能

显示文章详情

通过文章展示来快速体验上面的流程:

1.注册路由

来到app/Http/routes.php中,我们增加一个路由:

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

上面的路由articles/{id}指定我们需要加载ArticleController中的show()方法。这里需要注意的是{id}这个表达:这是表示id是一个路由变量,也就是当我们访问类似下面这两个路由的时候:

http://blog.dev/articles/1 //id 为1
http://blog.dev/articles/foo // id为foo

先不急着访问,因为我们还没有创建show()方法,这里只是作为说明。

在laravel中,路由变量写在{}括号中,这个id对应我们等下写的show()方法的参数。

2.编写show()

在ArticleController增加show()方法:

public function show($id)
{
    return $id;
}

我们在show($id)方法中,首先接受参数id,然后直接返回。现在我们可以访问上面的两个url了,看到的类似下面这个效果:

3.获取数据

然而在show()方法中,我们也是需要从数据库中加载获取数据,所以我们先修改show()方法:

public function show($id)
{
    $article = Article::find($id);
    return $article;
}

我们通过find()方法从数据库中查找一条记录,然后直接返回,我们来看看效果:

4.加载视图

获取数据之后,我们需要加载相应地视图来展示数据,还是修改show()方法:

public function show($id)
{
    $article = Article::find($id);
    return view('articles.show',compact('article'));
}

类似地,我们使用view()加载show.blade.php,然后compact()将变量传递过去。所以我们去创建show.blade.php视图文件吧:

@extends('app')
@section('content')
        <h1>{{ $article->title }}</h1>
        <hr>
        <p>{{ $article->content }}</p>
@endsection

这里跟index.blade.php视图文件差不多,我们只是去掉了@foreach,在来访问一下看看:

到这里,我们的文章展示页面也可以说是完成了,然而当我们访问这个下面这个链接的时候:

http://blog.dev/articles/3

报错了!

这是因为我们在show()方法中使用$article = Article::find($id);来查找一篇文章,但是我们的数据库中的articles表并没有id3的记录,也就是id3的时候,$article变量已经是null了,这个时候我们如果还是希望在视图中使用{{ $article->title }},所以才会出现错误:

Trying to get property of non-object....

PS: 如果你想调试,看看$article到底是什么,你可以在laravel中使用dd($article)来调试

那这个要怎么解决呢?有两种方法:

第一,自己写个if条件判断:

public function show($id)
   {
       $article = Article::find($id);
       if(is_null($article)){
           abort(404);
       }
       return view('articles.show',compact('article'));
   }

如果$article为空,直接abort()一个404页面。再来访问一下:

这里貌似还是会看到一堆错误,为什么呢?那是因为在.env中我们设置了APP_DEBUG=true,所以还会有下面的一堆错误,我们在实际的线上部署环境中,APP_DEBUG=false才是我们的设置。我们来体验一把将APP_DEBUG=false,见证一下我们的404页面:

这个404页面,你可以自定义:就是在resources/views/errors/文件夹下创建一个404.blade.php

实际例子就是这样的(彩蛋):

https://jellybool.com/show404page

你也可以在我的blog地址栏随便输入一堆东西,看看找不到文章的时候是什么样的404 page 。

第二,使用findOrFail()

上面的条件判断其实很不错了,但是这里我还是推荐使用findOrFail()这个方法:

public function show($id)
    {
        $article = Article::findOrFail($id);

        return view('articles.show',compact('article'));
    }

findOrFail()表示首先尝试find,如果找不到就fail,抛出一个Eloquent Exception,所以我们再来访问尝试一下:

我们应该会得到一样的结果.

然后我们回到我们的index.blade.php中为每篇文章添加链接:

  @foreach($articles as $article)
      <h1><a href="/articles/{{ $article->id }}">{{ $article->title }}</a></h1>
      <p>{{ $article->intro }}</p>
      <hr>
  @endforeach

访问来看看:

注意我们这里直接使用了href="/articles/{{ $article->id }}"进行链接,你也可以使用action()这个方法:

 @foreach($articles as $article)
        <h1><a href="{{ action('ArticleController@show',[$article->id]) }}">{{ $article->title }}</a></h1>
        <p>{{ $article->intro }}</p>
        <hr>
    @endforeach

action()这个方法第一个参数表明要加载ArticleControllershow()方法,跟routes一样,第二个参数用数组传入相应地参数[$article->id]

你还有第三种选择,使用url()方法:

@foreach($articles as $article)
      <h1><a href="{{ url('articles/',$article->id) }}">{{ $article->title }}</a></h1>
      <p>{{ $article->intro }}</p>
      <hr>
  @endforeach

url()方法第一个参数传入url路径,第二个参数直接传入变量。

上面的三种方法,选择一种自己喜欢的就可以了。

下一节

就写到这里吧,这一节大概也就是这样的内容了,不知道这样介绍,大家对Laravel的Model Controller Views的工作流程清晰了没,不清晰的话可以评论问我。。。

下一节,我即将说说怎么实现创建一篇文章,就会顺带介绍Laravel的Forms表单。

最后,

Happy Hacking

Laravel教程 五:MVC的基本流程的更多相关文章

  1. Laravel 5系列教程五:MVC的基本流程

    免费视频教程地址https://laravist.com/series/laravel-5-basic 期间受到很多私事影响,终于还是要好好写写laravel的教程了. 上一篇我们说了数据库和Eloq ...

  2. Laravel教程 二:路由,视图,控制器工作流程

    Laravel教程 二:路由,视图,控制器工作流程 此文章为原创文章,未经同意,禁止转载. View Controller 上一篇教程我们走了那么长的路,终于把Laravel安装好了,这一篇教程我们就 ...

  3. Laravel教程 三:视图变量传递和Blade

    Laravel教程 三:视图变量传递和Blade 此文章为原创文章,未经同意,禁止转载. Blade 上一篇我们简单地说了Router,Views和Controllers的工作流程,这一次我就按照上一 ...

  4. Laravel教程 七:表单验证 Validation

    Laravel教程 七:表单验证 Validation 此文章为原创文章,未经同意,禁止转载. Laravel Form 终于要更新这个Laravel系列教程的第七篇了,期间去写了一点其他的东西. 就 ...

  5. 2016 版 Laravel 系列入门教程(三)【最适合中国人的 Laravel 教程】

    本教程示例代码见: https://github.com/johnlui/Learn-Laravel-5 在任何地方卡住,最快的办法就是去看示例代码. 在本篇文章中,我们将尝试构建一个带后台的简单博客 ...

  6. Laravel教程 六:表单 Forms

    Laravel教程 六:表单 Forms 此文章为原创文章,未经同意,禁止转载. Form laravel 5.2 之后请使用 laravelcollective/html 替换 illuminate ...

  7. Laravel教程 四:数据库和Eloquent

    Laravel教程 四:数据库和Eloquent 此文章为原创文章,未经同意,禁止转载. Eloquent Database 上一篇写了一些Laravel Blade的基本用法和给视图传递变量的几种方 ...

  8. Laravel 5 系列入门教程(一)【最适合中国人的 Laravel 教程】

    Laravel 5 系列入门教程(一)[最适合中国人的 Laravel 教程] 分享⋅ johnlui⋅ 于 2年前 ⋅ 最后回复由 skys215于 11个月前 ⋅ 17543 阅读   原文发表在 ...

  9. Laravel 系列入门教程(三)【最适合中国人的 Laravel 教程】

    在本篇文章中,我们将尝试构建一个带后台的简单博客系统.我们将会使用到 路由.MVC.Eloquent ORM 和 blade 视图系统. 简单博客系统规划 我们在教程一中已经新建了一个继承自 Eloq ...

随机推荐

  1. Codeforces Round #335 (Div. 2) C. Sorting Railway Cars 连续LIS

    C. Sorting Railway Cars   An infinitely long railway has a train consisting of n cars, numbered from ...

  2. .NET4.5中WCF中默认生成的basicHttpsBinding的研究

    起因: 使用.net4.5建立了一个空白的WCF服务.默认使用的绑定配置是basicHttpsBinding. 问题发现: 1.用客户端进行服务引用,生成了默认的配置文件,其中绑定配置是basicHt ...

  3. JavaScript学习总结一(String对象的用法)

    javascript String对象的常用API 1:indexOf indexOf() 方法可返回某个指定的字符串值在字符串中首次出现的位置.如果没有找到匹配的字符串则返回 -1.注意: inde ...

  4. 使用OLEDB读取不同版本Excel数据的连接字符串设置

    摘要: 用OLEDB通过设置连接字符串可以像读取sqlserver一样将excel中的数据读取出来,但是excel2003和excel2007/2010的连接字符串是不同的/// summary // ...

  5. hibernate对象关系映射( 一对一,一对多,多对一,多对多的单向,双向映射 ——)

    对象之间的关系: 关系映射之间的关系只的是对象之间的关系,并不指数据库表的关系(外键关系)这儿解决的问题是当对象之间的关系之一时,数据库表该如何映射,编程上如何对待. 一对一(主键关联,和单向的外键关 ...

  6. 【windows开发实现记事本程序&mdash;&mdash;界面篇】

    前言 从毕业开始学习windows UI编程,工作中总是和一些API打交道,但是从没有做过一个完整的界面程序.因此打算自己利用空余时间做一个小的项目来总结自己所学的东西.在网上看到许多人建议自己动手写 ...

  7. php 带cookie登陆

    <?php /** * @version $id */ define('SCRIPT_ROOT',dirname(__FILE__).'/'); $act = trim($_REQUEST['a ...

  8. SDWebImage实现原理详解

    1)当需要获取网络图片的时候,我们首先需要的便是URL,如果没有URL什么都没有,获得URL后,SDWebImage实现的并不是直接去请求网路,而是检查图片缓存中有没有和URL相关的图片,如果有则直接 ...

  9. Python读取excel中的图片

    作为Java程序员,Java自然是最主要的编程语言.但是Java适合完成大型项目,对于平时工作中小的工作任务,需要快速完成,易于修改和调试,使用Java显得很繁琐,需要进行类的设计,打成jar包,出现 ...

  10. C++(3):./Encryptor: undefined symbol:Z11startserviceLAKJDFLJALDKJFLLLLL

    在Linux下编译得Encryptor文件,但是执行./Encryptor时 报了如上错误:undefined symbol:Z11startserviceLAKJDFLJALDKJFLLLLL 原因 ...