laravel 5.5入门系列——6

向laravel 5进军6

    • Blade模板引擎必备使用技能

    • 完成用户注册功能

    • 使用if

    • 使用foreach

    • 使用for循环

    • 使用switch

    • yield extend section stop

    • 输出变量

    • 流程控制语句

    • 使用unless

    • 身份快捷认证

    • 表单方法伪造

    • 路由重定向

    • Request request实例

    • validate的用法

    • 表单构建之前

    • 构建表单

    • 提交错误处理

    • 多语言支持

    • 向laravel 5进军6

Blade模板引擎必备使用技能

1. @yield @extend @section @stop

在构建静态页面时已经介绍了@yield和@extend的用法,在此再整理一下 
路径layouts下的default.blade.php的内容:

<!DOCTYPE html><html><head>
    <title>@yield('title','NewProject')——入门教程</title></head><body>@yield('content')</body></html>123456789

而在home.blade.php的内容如果是:

@extends('layouts.default')@section('title','Help')@section('content')
    <h1>帮助页</h1>@stop12345

可以看到,用@extend引用父类视图,用@yield等待补充内容,@section到@stop之间的内容就会填充到@yield中.

@yield的第二种用法是带两个参数,第二个参数是默认参数,此情况下只用@section不需要用@stop.详见.laravel 5入门系列——3


2. 输出变量

在Blade模板中{{ \$title }} 会被解析为类似 这样的输出 <?php echo $title; ?> 因此就有:

  • 原样输出 {{ $variable }}

  • 如果将$tiltle写成

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

那就应该渲染后输出{{!! $title !!}}


3. 流程控制语句

使用@if

某控制器中的函数为

public function test(){
    $judge='yes';    return view('default',compact('judge'));
}1234

其中default.blade.php文件内容如下:

@if($judge == 'yes')
<h1>{{ $judge }}</h1>
@else<h1>no</h1>
@endif12345

感觉都不用解释,用laravel的blade模板跟写英语差不多了.


使用@foreach

foreach的用法和php的foreach一样,只不过是加了一个@符号而已: 
控制器写成

public function test(){
    $arr=['test1','test2'];    return return view('default',compact('arr'));
}1234

视图文件如下:

@foreach($arr as $element)
<h1>{{ $element }}</h1>
@endforeach123

使用@for循环

直接贴用法啦:

@for ($i = 0; $i < 10; $i++)
    <p>目前的值为 {{ $i }}</p>
@endfor1234

使用@switch
@switch($i)
    @case(1)
        First case...
        @break
    @case(2)
        Second case...
        @break
    @default
        Default case...
@endswitch123456789101112

使用@unless

unless 相当于 if(! something)

@unless (Auth::check())
    你尚未登录。@endunless123

身份快捷认证

先码在这里,以后权限认证是用的到的,很方便

@auth
    // 用户已经通过身份认证...@endauth
@guest
    // 用户没有通过身份认证...@endguest1234567

Blade模板还有更高端的功能,详情参看文档Blade模板

完成用户注册功能

回顾一下,已经通过resource添加了符合RESTful框架的路由规则.等效生成的路由有

Route::get('/users', 'UsersController@index')->name('users.index');Route::get('/users/{user}', 'UsersController@show')->name('users.show');Route::get('/users/create', 'UsersController@create')->name('users.create');Route::post('/users', 'UsersController@store')->name('users.store');Route::get('/users/{user}/edit', 'UsersController@edit')->name('users.edit');Route::patch('/users/{user}', 'UsersController@update')->name('users.update');Route::delete('/users/{user}', 'UsersController@destroy')->name('users.destroy');1234567

那么创建一个新用户存入数据库,就得用到store方法.下面来写UsersController的store方法: 
文件路径为:App/Http/Controller/UsersController.php

namespace App\Http\Controllers;use Illuminate\Http\Request;use App\Http\Requests;use App\Models\User;class UsersController extends Controller{
   ...
   ...
   ...    public function store(Request $request)
    {
        $this->validate($request, [            'name' => 'required|max:50',            'email' => 'required|email|unique:users|max:255',            'password' => 'required|confirmed|min:6'
        ]);         $user = User::create([            'name' => $request->name,            'email' => $request->email,            'password' => bcrypt($request->password),
        ]);        return redirect()->route('users.show', compact('user'));//重定向到show视图文件
    }
}1234567891011121314151617181920212223242526272829

首先store会接受一个Request类的实例$request,而validate方法接受两个参数,第一个是\$request,第二个是一个关联数组,指定验证格式。这里用到了validate方法,理由很简单,对于注册的账号,姓名,邮箱,密码都是有要求的。如果验证成功,那么利用User模型的create方法,把数据记录到数据库中,再重定向页面即可。


validate的用法

validate第二个参数填的关联数组即可实现验证.关联数组的key对应数据库中的字段,关联数组的value对应验证方法.其中用到的验证方法一一解释一下:

  • required表示不能为空

  • email表示验证这是个邮箱,这是laravel的功能,不用自己写正则来判断

  • unique:users表示对于users数据表该字段必须是唯一的

  • confirmed表示两次填入的信息要一致

  • max:16 | min: 3 指的是对输入长度的要求

  • 如果有多个验证要求,用 | 符号隔开即可


表单构建之前

跨站请求伪造(CSRF)是一种通过伪装授权用户的请求来攻击授信网站的恶意漏洞。 
Laravel 通过自带的 CSRF 保护中间件让避免应用遭到跨站请求伪造攻击变得简单:Laravel 会自动为每一个被应用管理的有效用户会话生成一个 CSRF “令牌”,然后将该令牌存放在 Session 中,该令牌用于验证授权用户和发起请求者是否是同一个人。

我们使用 POST 方法提交表单时,Laravel 为了安全考虑,会让我们提供一个 token(令牌)来防止我们的应用受到 CSRF(跨站请求伪造)的攻击。因此如果使用POST方法,在表单下应添加一行{{ csrf_field() }}.这行命令会被解析成<input type="hidden" name="_token" value="cxqT67dMoWsAHGGPJOAWJn8x5R5ctSwZrAq">即一个隐藏域. 
详细内容参看手册.CSRF


表单方法伪造

HTML 表单不支持 PUT、PATCH 或者 DELETE 请求方法,因此,在 HTML 表单中调用 PUT、PATCH 或 DELETE 路由时,需要添加一个隐藏的 _method 字段,其值被用作该表单的 HTTP 请求方法:

<form action="/foo/bar" method="POST">
    <input type="hidden" name="_method" value="PUT">
    <input type="hidden" name="_token" value="{{ csrf_token() }}"></form>1234

还可以直接使用辅助函数 method_field 来实现这一功能:

{{ method_field('PUT') }}1

路由重定向

如果你需要定义一个重定向到其他 URI 的路由,可以使用 Route::redirect 方法,该方法非常方便,以至于你不需要再定义额外的路由或控制器来执行简单的重定向逻辑:

Route::redirect('/here', '/there', 301);1

Request $request实例

laravel应用程序中index.php是所有请求的入口。当用户提交一个form或者访问一个网页时,首先由kernel捕捉到该session PHP运行环境下的用户数据,生成一个request对象,该对象再传入routing系统寻址到对应的controller,最终由controller形成response返回给浏览器,完成整个网页请求的生命周期。

总的来说,就是HTTP请求中的信息,通过http协议传输过来之后,在后端的代码里这些信息就被封装在了request里面.因此有直接引用$request->name,$request->email这些操作.详细的技术问题以后再追究吧.

现在只需知道,通过表单提交过来的数据,命名字段后,可以直接在Controller中注入Request的实例$request获得前端提供的信息.其实$request还有很多操作,比如$request->url()等等,进阶的时候详细研究一下.


构建表单

表单区域的样式代码大概写成这样

<div class="panel-body">
      <form method="POST" action="{{ route('users.store') }}">
          {{ csrf_field() }}
          <div class="form-group">
            <label for="name">名称:</label>
            <input type="text" name="name" class="form-control" value="{{ old('name') }}">
          </div>
          <div class="form-group">
            <label for="email">邮箱:</label>
            <input type="text" name="email" class="form-control" value="{{ old('email') }}">
          </div>
          <div class="form-group">
            <label for="password">密码:</label>
            <input type="password" name="password" class="form-control" value="{{ old('password') }}">
          </div>
          <div class="form-group">
            <label for="password_confirmation">确认密码:</label>
            <input type="password" name="password_confirmation" class="form-control" value="{{ old('password_confirmation') }}">
          </div>
          <button type="submit" class="btn btn-primary">注册</button>
      </form>
    </div>123456789101112131415161718192021222324252627

可以看到 <form method="POST" action="{{ route('users.store') }}">中表单提交的对象即为命名路由users.store再贴一下命名路由张啥样: 
Route::post('/users', 'UsersController@store')->name('users.store'); 
而UserController的store方法已经写好了包含了validate验证和create新实例到数据库中,顺利注册后还会重定向到显示页面,此时已经完成了store方法,但是表单功能还不完善,因为还没有确定如果出现输入不符合标准的错误情况,网站应该做出什么反应。下面来完善它


提交错误处理

Laravel 默认会将所有的验证错误信息进行闪存。当检测到错误存在时,Laravel 会自动将这些错误消息绑定到视图上,因此我们可以在所有的视图上使用 errors 变量来显示错误信息。需要注意的是,在我们对 errors 进行使用时,要先使用 count($errors) 检查其值是否为空。

错误提示是laravel自带的,因此这段代码有通用性,为了符合Don’t repeate yourself的准则,咱们把这段代码弄出来,以后要用就直接调用就行。$error变量是验证错误后,validate方法返回到视图中的,因此可以直接调用.

@if(count($errors) > 0)     <div class="alert alert-danger">
      <ul>
          @foreach($errors->all() as $error)          <li>{{ $error }}</li>
          @endforeach      </ul>
  </div>@endif123456789

多语言支持

此时做好的表单错误信息返回的是英文,不过laravel非常友好的有多语言包,不用太操心这个事情.给一个链接按照步骤安装多语言包Laravel-language