Home >Backend Development >PHP Tutorial >Laravel 5 系列教程三:视图变量传递和Blade

Laravel 5 系列教程三:视图变量传递和Blade

WBOY
WBOYOriginal
2016-06-23 13:28:261279browse

原文来自: https://jellybool.com/post/programming-with-laravel-5-blade-views-with-var

系列文章: http://segmentfault.com/blog/jellybool

上一篇我们简单地说了Router,Views和Controllers的工作流程,这一次我就按照上一篇的计划,来说说下面几个内容:

  • 向视图中传递变量

  • Blade模板的用法

  • Laravel的数据库配置和Migration的用法

  • 向视图中传递变量

    我们在开发web应用当中,通常都不是为了写静态页面而生的,我们需要跟数据打交道,那么这个时候,问题就来了,在一个MVC的框架中,怎么将数据传给视图呢?比如我们要在 ArticleController 的 index 方法的视图输出一个 $title 的变量,在Laravel中,有下面几种常见的方法:

    使用with()方法

     public function index()    {        $title = '文章标题1';        return view('articles.lists')->with('title',$title);    }

    这样的 with('title',$title) 中,第一个 'title' 就是key,第二个 $title 就是值,这样我们就可以在我们的 articles/lists.blade.php 中输出这个变量了:

    <body><h1><?php echo $title; ?></h1></body>

    刷新我们的 blog.dev ,就可以看到类似这样的页面了:

    而在blade引擎中,我们可以这样输出变量:

    <body><h1>{{ $title }}</h1></body>

    其实在blade引擎中, {{ $title }} 会被解析为类似 这样的输出 ,不过这里的 {{ }} 符号会将数据原样输出,比如你将 $title 写成这样:

     public function index()    {        $title = '<span style="color: red">文章</span>标题1';        return view('articles.lists')->with('title',$title);    }

    这个时候你用 {{ $title }} 输出,会看到类似下面这样:

    如果你想将 $title 作为页面元素渲染输出,你需要这样写:

    <h1>{!! $title !!}</h1>

    这里的 {{ }} 和 {!! !!} 是blade的最基础的用法,这两个我们会用得特别多,后面我会详细说说blade的用法。

    直接给view()传参数

    使用这个方法的时候,你可以这样写:

    public function index()    {        $title = '<span style="color: red">文章</span>标题1';        return view('articles.lists',['title'=>$title]);    }

    刷新页面,你依然会看到一样的输出。这里需要说明一下,如果你传多个变量,比如:

     public function index()    {        $title = '<span style="color: red">文章</span>标题1';        $intro = '文章一的简介';        return view('articles.lists',[                                        'title'=>$title,                                        'introduction'=>$intro                                        ]);    }

    在传递的数组中:

    ['title'=>$title,'introduction'=>$intro]

    每一个key会在视图中作为变量,而 value 就作为变量的值。所以在视图中我们需要这样输出:

    <h1>{!! $title !!}</h1>

    {{ $introduction }}

    这里应写成 {{ $introduction }} ,而不是 {{ $intro }} 。

    使用compact

    使用compact是这样写的:

     public function index()    {        $title = '<span style="color: red">文章</span>标题1';        $intro = '文章一的简介';        return view('articles.lists',compact('title','intro'));    }

    compact() 的字符串可以就是变量的名字,多个变量名用逗号隔开。这个时候注意更改视图的变量输出。

    以上就是Laravel中常用的几种向视图传递变量的方法,选择一种你喜欢的方式并坚持这一种写法就可以了,我是使用第三种。

    Blade的基本用法

    上面的内容介绍了一点点blade的语法,这里我们再统一介绍blade,说说下面几个比较常用的:

    @yield()@extends()@if() and @unless()@foreach()

    @yield() 和 @extends() 通常会结合者使用,实现我们通常所说的layouts布局:就是在web开发的过程中,我们将一些公用的部分如 header , footer 等直接放在一个视图文件中,然后在使用的使用直接继承 (使用@extends) 就可以了,比如我们在 resources/views/ 文件夹之下创建一个 app.blade.php :

    <!DOCTYPE html><html class="no-js" lang="zh-CN"><head>    <meta charset="UTF-8">    <meta http-equiv="X-UA-Compatible" content="IE=edge">    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">    <title>Laravel 5 教程</title>    <link rel='stylesheet' href="/css/all.css" type='text/css' media='all'/>    <script type='text/javascript' src="/js/all.js"></script></head><body><div id="wrapper">    @yield('content')    <nav class="nav-container group" id="nav-footer">        <div class="nav-wrap">            <ul class="nav container group">                <li class="menu-item">                    <a href="/" rel="nofollow" target="_blank">Laravel 5 Blog</a>                </li>            </ul>        </div>    </nav></div></body></html>

    写上这么一些内容,其中css这个 href="/css/all.css" ,需要我们手动在 public/ 文件夹之下创建css/文件夹,并创建all.css这个文件,对于js的src="/js/all.js"也是同理,这两个文件是为了后面的页面美化而做的提前准备。

    注意到@yield('content')这个语法,这里就是说,这里有一个content的内容区域,如果某个页面继承了这个app.blade.php,然后那个页面就可以动态改变@yield('content')的内容了。比如我们在articles/lists.blade.php中,我们继承一下app.blade.php:

    @extends('app')@section('content')<h1>{!! $title !!}</h1>

    {{ $intro }}

    @endsection

    这里的第一行@extends('app')就是声明这个页面继承于app.blade.php,也就是我们的articles/lists.blade.php可以使用到all.css和all.js文件,然后@section('content')就是对于app.blade.php的@yield('content'),表明就是:在渲染加载articles/lists.blade.php的时候,@yield('content')这部分内容会被替换为下面的内容:

    <h1>{!! $title !!}</h1>

    {{ $intro }}

    @if()通常是用于在视图中根据某些条件来判断是否该显示某些内容,比如我们可以很“无聊”地试试这样:

    public function index()    {        $first = 'jelly';        $last = 'bool';        return view('articles.lists',compact('first','last'));    }

    在views文件中,我们使用一下@if():

    @extends('app')@section('content') @if($first == 'jellybool') <h1>{{ $first }}</h1> @else <h1>{{ $last  }}</h1>@endif@endsection

    刷新一下就可以看到页面的输出,为$last的值。

    上面的@if(),还有一个可以使用的标签就是@unless(),@unless()就可以理解为 if( ! ),就是if not 这样理解就OK。

    @foreach()用于循环输出变量,比如:

    public function index()    {        $first = ['jelly','bool'];        return view('articles.lists',compact('first'));    }

    我们传一个数组给视图,然后,我们就可以使用@foreach()循环输出了:

    @extends('app')@section('content')@foreach( $first as $name)    <h1> {{ $name }}</h1>@endforeach@endsection

    刷新一下页面,就可以看到循环的结果了:

    blade的更多知识,可以参考文档:

    http://laravel.com/docs/5.1/blade

    Laravel的数据库配置

    本部分内容为下节做准备

    Laravel的配置文件都是在项目目录的config/文件夹之下,这里也就是在blog/config文件夹之下,你可以打开这个文件夹看看,你面有很多配置文件:如mail.php(配置邮件发送服务的)和database.php(配置数据库的),我们这里就是来看看这个database.php配置文件:

     'connections' => [        'mysql' => [            'driver'    => 'mysql',            'host'      => env('DB_HOST', 'localhost'),            'database'  => env('DB_DATABASE', 'forge'),            'username'  => env('DB_USERNAME', 'forge'),            'password'  => env('DB_PASSWORD', ''),            'charset'   => 'utf8',            'collation' => 'utf8_unicode_ci',            'prefix'    => '',            'strict'    => false,        ]        //...        ]

    打开文件,你可以看到里面只是返回简单地php数组而已,我们目前只是关心connections这个数组。上面的代码并没给出所有的数据库配置,你可以自己看,由于博主使用的是mysql,所以这里会给出mysql的配置,其他数据库你可以参照着来,后续的教材博主也会依旧使用mysql。

    那这里说到的配置,基本上就是对下面四个变量的配置:

    'host'      => env('DB_HOST', 'localhost'),//如果.env文件没有DB_HOST配置,则取localhost,后面的一样'database'  => env('DB_DATABASE', 'forge'),'username'  => env('DB_USERNAME', 'forge'),'password'  => env('DB_PASSWORD', ''),

    这里的env()方法是读取到.env (位于blog/.env) 这个文件里面的配置项

    打开这个文件,你可以看到一些常用的配置,包括debug模式和开发环境,你也可以看到我们下面这几个需要操作的选项:

    DB_HOST=localhostDB_DATABASE=homesteadDB_USERNAME=homesteadDB_PASSWORD=secret

    由于这里我使用的是Homestead的开发环境,所以才有了上面的配置(Homestead的默认用户名和密码为homestead和secret),如果你是直接使用php artisan serve这种方式开启服务来开发的话,相应地修改你的配置。

    Laravel为什么要采取这样的配置呢?很大的一个原因可能就是考虑到文件的安全性和便捷性,这样我们在需要将代码推送到coding或者Github的时候,我们可以直接ignore这个.env文件,不必担心我们的核心信息呗泄露。在部署应用的时候,我们可以直接在服务器创建一个.env文件,写上对应的配置项就OK了。

    就这样,只要我们正确配置信息,我们就连接上数据库了,当然,你得首先创建一个homestead数据库。

    使用Migration

    连接好数据库之后,我们就需要创建相对应的数据表了,在没有使用Laravel之前,你可能都是直接手动创建数据表的,比如我们这个blog项目,你会到数据库中手动创建一个articles数据表,但是在Laravel的项目中,我极力推荐你使用Migration,这样有什么好处呢?其实你可以将Migration看做一个数据库的版本管理工具,就如git对于我们的项目文件的版本管理,你可以rollback,你可以reset等,它给予你一种代码实现和命令行结合的方式来管理你的数据库,如果你在blog/目录下,命令行执行 php artisan ,你可以看到很多命令行,下面这几个就是我们这里谈到的rollback和reset等:

    红色框框这几个基本就是比较常用的,如果这里我还没有说服使用migration,那么我们来将这个过程走一遍:

    首先,我们创建一个migration文件,也就是定义一张表的schema,命令行执行:

    php artisan make:migration create_articles_table --create='articles'

    顺利执行之后,我们会得到一个migration文件,这个文件位于database/migrations/下面,打开这个文件夹,你可以看到Laravel本来就有两个migration文件,users表和password-reset表,我们在这个项目中目前还不用这两个文件。所以可以直接删掉,然后打开我们刚刚生成的migration文件:create_articles_table这个文件

     public function up()    {        Schema::create('articles', function (Blueprint $table) {            $table->increments('id');            $table->timestamps();        });    }    /**     * Reverse the migrations.     *     * @return void     */    public function down()    {        Schema::drop('articles');    }

    这里有两个方法:up()和down()。up()方法是执行php artisan migrate的时候调用的,这个方法会创建一个articles数据表,而down()方法则是在php artisan migrate:rollback的使用执行的,这里会直接删除articles这个数据表。

    但是,这里先不要急着执行php artisan migrate,我们还需要为articles的增加几个字段:

    public function up()    {        Schema::create('articles', function (Blueprint $table) {            $table->increments('id');// 主键 自增            $table->string('title');            $table->text('intro');            $table->text('content');            $table->timestamp('published_at');            $table->timestamps(); // 自动创建的两个字段:created_at 和 updated_at        });    }

    这里我们的intro字段是文章的简介,published_at字段是文章的发表日期,这样做对我们写博客有很大的好处,你可以将博客的发表日期控制起来,因为有一些我写好的但是还没有到发表日期的,还不想让用户看到的文章我就可以用published_at来控制了。这样之后,我们来执行一下php artisan migrate:

    然后,articles这个表就创建成功了。

    这个时候你可能还没有体会到migration的好处,想象下面两个场景:

    1. 在进行团队开发的时候,团队成员将我们的代码pull下来之后,怎么可以拿到一样的数据库表设计呢?难道要我们将表 export 出来,给每一个成员import一次?这显然不够明智,如果使用的migration,就一行命令,直接`php artisan migrate`,就可以拿到一样的数据库表了。2. 如果这个时候我们发现articles这个表的有一个字段写错了,比如我们的intro字段写错,它应该命名为introduction的,这个时候,我们怎么办?直接手动改数据库的表?那么回到第一个场景,你的团队成员也需要手动改?这显然也不是我们喜欢的方式,这个时候,migration的优势就来了

    比如我们这里演示一下怎么解决第二个场景:

    我们只需要命令行执行:

    php artisan migrate:rollback

    然后修改up()方法的intro字段:

    $table->text('introduction');

    然后再执行php artisan migrate:

    大工告成,更多特性请看文档:

    http://laravel.com/docs/5.1/migrations

    下一节

    貌似上面配置数据库链接之后还没有用到,不用着急,我接下来的一篇会具体说说Eloquent的用法,这个在Laravel中是很有代表性的部分,希望你可以学到一点东西。

    Happy Hacking

    Statement:
    The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn