创建你的第一个 Laravel 应用(2021 版)

Laravel

自2011年首次发布以来,Laravel 经历了指数级增长。在2015年,它成为 GitHub 上最受关注的PHP框架,并成为全世界人民的首选框架。

Laravel 首先关注最终用户:这意味着它关注的是简单、清晰和完成工作。人们和公司都在用它来建造各种各样的东西,从简单的爱好项目一直到财富500强公司。

我的这个 Laravel 教程的目的是为那些刚刚学习 Laravel 的人提供指南。本指南将带你从构想的最开始就进入一个真正的可部署应用程序。如果你更喜欢把它作为电子书来阅读,你可以加入我们的每周 Laravel Newsletter 并免费获得它。

对Laravel的介绍不会详尽无遗,但是如果你想要更详尽的介绍,我建议你阅读 *Laravel: 启动与运行* 一书。本教程确实需要一些先决条件,这是您需要遵循的前提条件:

  • 本地 PHP 环境 (ValetHomestead,Vagrant,MAMP, 等)。
  • 数据库 (我将使用MySQL)
  • 安装 PHPUnit。
  • 安装 Node JS。

注意:对于本地 PHP 开发,我推荐 Mac OSX 和 Valet,因为它会自动设置所有内容。如果你使用的是 Windows,请考虑使用 Homestead 或某种虚拟机。另一种选择是由社区提供的 Windows Valet 端口.

我试图像在现实环境中一样,经历创建新应用程序的过程。实际上,代码和想法来自我构建的项目。

计划

每个项目都必须从某个地方开始;工作中的项目任务,或者只是脑子中的一个想法。无论它起源于何处,在开始编码之前都要彻底规划所有功能对于完成一个项目至关重要。

你如何计划取决于您的思维方式。作为一个有视觉见识的人,我喜欢在纸上计划,画出我看待屏幕外观的方式,然后向后研究如何编码。其他人则喜欢在文本文件,Wiki 或某些思维导图工具中编写项目计划。无论你如何计划,只要你照做就可以了。

对于本指南,我们将构建一个链接目录。以下是此链接应用程序的基本目标列表:

  1. 显示一个简单的链接列表。
  2. 创建一个表单,人们可以在其中提交新链接。
  3. 表单验证。
  4. 将数据插入数据库。

让我们开始吧!

第一步

概述了简单的攻击计划,是时候启动并运行一个全新的空项目。我喜欢将所有项目都放在 〜/ Sites 目录中,这些说明将使用该位置。我已经将该目录 「寄存」在了 Valet 中,因此所有文件夹都将自动映射到浏览器中的 「foldername.test」。

打开终端应用程序,然后切换到该目录。

mkdir ~/Sites
cd ~/Sites

Laravel 提供了一个方便的安装程序。如果你打算编写 Laravel 应用,请遵循 安装文档 以获取有关设置安装程序的详细信息。

无论是设置安装程序还是要使用 composer,请运行以下操作之一为 links 应用程序创建新的 Laravel项目:

# 通过安装程序
laravel new links

# 通过 composer
composer create-project --prefer-dist laravel/laravel links "7.*"

这将在处创建一个新目录 ~/Sites/links 并安装一个新的 Laravel 项目。

现在在浏览器中访问会 links.test, 显示 Laravel 的默认欢迎页面:

数据库设置

创建新的 Laravel 项目时,安装过程会自动创建一个 .env 文件 (从 .env.example 文件中复制) 以用于配置和凭证。根据你的设置,你需要修改以下设置块匹配你的数据库配置:

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel
DB_USERNAME=root
DB_PASSWORD=

你可能要为此项目创建一个新的数据库:

# 通过 mysql CLI 连接
mysql -u root -p
mysql> create database links_development;
mysql> exit

# 或者使用 -e 标志运行 create 命令
mysql -u root -e'create database links_development'

然后需要在 .env 中调整数据库配置:

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=links_development
DB_USERNAME=root
DB_PASSWORD=

测试数据库连接的最佳方法是运行 migrate artisan 命令:

php artisan migrate

如果一切都按计划进行,那么在运行 migration 命令后,你应该会看到类似以下的内容:

认证脚手架

Laravel 有一个单独的第一方软件包,用于生成通用的脚手架,使设置身份验证变得轻而易举。要使用它,我们需要安装 composer UI 包:

composer install laravel/ui

UI 软件包提供了一些命令来设置诸如 React,Vue 和 Bootstrap 之类的工具的脚手架。我们将为此项目创建简单的身份验证支架,但是请随时关注 frontend setup 文档。

运行以下命令来生成路由,控制器,视图和其他对 auth 必需的文件:

php artisan ui bootstrap --auth

最后,我们需要使用以下代码编译 CSS UI:

npm install

# 构建开发环境
npm run dev

# 或者使用监视程序自动更新更改
npm run watch

watch 命令将监听对JS和CSS文件的更改,并自动更新它们。 您可能希望在开发时在单独的选项卡中运行 npm run watch

即使本教程不会通过运行此命令深入探讨身份验证,它也会修改我们的视图和路由。 因此,尽早进行此操作,我们不必担心它会与我们的任何代码混为一谈。

设置好基础知识并开始工作之后,就该开始进行一些编码了。

建立链接列表

如果您开始考虑已完成的项目,很容易不知所措。 解决此问题的最佳方法是将项目分解为小任务。 因此,让我们从显示链接列表开始。

尽管展示一个链接列表听起来好像是个小任务,但是,它仍然需要一个数据库、表、表里的数据、一个数据库查询和一个视图文件

第一步先创建一个数据库的迁移文件(migration),Laravel的Artisan命令可以帮助我们来创建它。

php artisan make:migration create_links_table --create=links

现在打开命令创建生成的migration文件,它的位置在database/migrations/{{datetime}}_create_links_table.php
你可以看到在这个文件夹中,框架已经我们提供了一部分数据库迁移文件。
up() 方法中,添加如下的代码:

Schema::create('links', function (Blueprint $table) {
      $table->increments('id');
      $table->string('title');
      $table->string('url')->unique();
      $table->text('description');
      $table->timestamps();
});

保存文件并执行迁移命令:

php artisan migrate

如果你想清除之前的数据,可以使用下面的命令:

php artisan migrate:fresh

接下来,我们需要一些数据和模型来使用我们的数据库表。 Laravel 提供了两个功能来解决这个问题,第一个是database seeder,它使用数据填充数据库,第二个是model factory,该文件允许我们生成伪造的模型数据,可用于填充开发数据库和测试:

php artisan make:model --factory Link

执行 make:model 命令会创建一个app/Link.php模型文件。 Laravel 模型提供了一个称为 Eloquent 的功能强大的数据库API,您可以在 Eloquent 文档 查看其更多的使用方法。

这个 --factory 命令将会在 database/factories 这个路径下生成一个新的工厂文件用来生成当前应用数据. 在这个示例中, 一个新的 LinkFactory 文件将会为我们的 Link 模型包括一个空的工厂限定。

打开 LinkFactory.php 文件并且填充如下:

<?php

/** @var \Illuminate\Database\Eloquent\Factory $factory */

use App\Link;
use Faker\Generator as Faker;

$factory->define(Link::class, function (Faker $faker) {
    return [
        'title' => substr($faker->sentence(2), 0, -1),
        'url' => $faker->url,
        'description' => $faker->paragraph,
    ];
});

我们使用 $faker->sentence() 方法去生成标题, 并且用 substr 移除以句子结尾的句号.

然后, 创建有关表的命令, 以便我们轻松的添加演示数据到表中:

php artisan make:seeder LinksTableSeeder

make:seeder命令会生成一个数据库类来填充我们的links表。
打开database/seeds/LinksTableSeeder.php文件添加如下代码:

public function run()
{
    factory(App\Link::class, 5)->create();
}

为了启动LinksTableSeeder,我们还需要在主数据库填类文件database/seeds/DatabaseSeeder.php中添加如下代码:

public function run()
{
    $this->call(LinksTableSeeder::class);
}

现在你可以使用migrations和seeds去自动的填充数据库表数据了。使用migrate:fresh命令,我们可以获取到一个干净的schema,然后重新填充数据库。

$ php artisan migrate:fresh --seed
Dropped all tables successfully.
Migration table created successfully.
Migrating: 2014_10_12_000000_create_users_table
Migrated:  2014_10_12_000000_create_users_table
Migrating: 2014_10_12_100000_create_password_resets_table
Migrated:  2014_10_12_100000_create_password_resets_table
Migrating: 2017_11_03_023418_create_links_table
Migrated:  2017_11_03_023418_create_links_table
Seeding: LinksTableSeeder

使用 tinker shell ,您可以开始使用模型进行交互:

$ php artisan tinker
>>> \App\Link::first();
=> App\Link {#3060
     id: 1,
     title: "Rerum doloremque",
     url: "http://russel.info/suscipit-et-iste-debitis-beatae-repudiandae-eveniet.html",
     description: "Dolorem voluptas voluptatum voluptatem consequuntur amet dolore odit. Asperiores ullam alias vel soluta ut in. Facere quia et sit laudantium culpa ea possimus.",
     created_at: "2020-04-05 00:44:33",
     updated_at: "2020-04-05 00:44:33",
   }
>>>

我们已经有了数据和模型! 为了将新链接加入到应用中,我们可以开始创建 UI 视图。

路由和视图

为了构建一个显示链接列表的视图,我们需要更新系统的路由,并创建一个新路由,该路由将显示我们提交的表单。我们可以在routes / web.php文件中向我们的应用程序添加新路由。

在web路由文件中,你会看到如下的默认路由:

Route::get('/', function () {
    return view('welcome');
});

我们可以通过一个闭包或者专用的controller类来创建一个新的路由。在本手册中,我们用闭包来创建我们的提交和索引路由。

首先,我们来更新主页路由,路由中获取一个links的集合然后传递给视图文件:

Route::get('/', function () {
    $links = \App\Link::all();

    return view('welcome', ['links' => $links]);
});

第二个参数可以是一个关联的数据数组,数组的键就是模板文件中的变量名。

如果你喜欢的话,你还可以使用一个fluent API去定义变量:

// with()
return view('welcome')->with('links', $links);

// dynamic method to name the variable
return view('welcome')->withLinks($links);

然后,编辑welcome.blade.php文件添加一个简单的foreach去显示链接:

@foreach ($links as $link)
    <a href="{{ $link->url }}">{{ $link->title }}</a>
@endforeach

这是welcome.blade.php的代码:

<body>
    <div class="flex-center position-ref full-height">
        @if (Route::has('login'))
            <div class="top-right links">
                @auth
                    <a href="{{ url('/home') }}">Home</a>
                @else
                    <a href="{{ route('login') }}">Login</a>
                    <a href="{{ route('register') }}">Register</a>
                @endauth
            </div>
        @endif

        <div class="content">
            <div class="title m-b-md">
                Laravel
            </div>

            <div class="links">
                @foreach ($links as $link)
                    <a href="{{ $link->url }}">{{ $link->title }}</a>
                @endforeach
            </div>
        </div>
    </div>
</body>

刷新浏览器,你就会看到所有添加的链接。接下来,我们来提交链接:

展示链接提交表单

我们就快要完成我们创建的第一个Laravel应用了!

我们完成的这个laravel教程将使人们能够向应用提交链接,提交链接的时候需要提交三个字段:title,URLdescription

我是一个比较注重视觉的人,所以在开始规划HTML的细节之前,我喜欢先画图来构建我的想法。下面就是我画的关于表单的简单草图:

鉴于我们已经添加了所有的核心结构,模型工厂,数据迁移和数据模型,
我们可以通过重复之前的步骤来简化这个部分的工作。

首先,在routes/web.php文件中创建一个新的路由:

Route::get('/submit', function () {
    return view('submit');
});

下一步, 我们将会生成 submit.blade.php 模板在 resources/views/submit.blade.php 这里跟随有如下Bootsrap模板代码:

@extends('layouts.app')
@section('content')
    <div class="container">
        <div class="row">
            <h1>Submit a link</h1>
        </div>
        <div class="row">
            <form action="/submit" method="post">
                @csrf
                @if ($errors->any())
                    <div class="alert alert-danger" role="alert">
                        Please fix the following errors
                    </div>
                @endif
                <div class="form-group">
                    <label for="title">Title</label>
                    <input type="text" class="form-control @error('title') is-invalid @enderror" id="title" name="title" placeholder="Title" value="{{ old('title') }}">
                    @error('title')
                        <div class="invalid-feedback">{{ $message }}</div>
                    @enderror
                </div>
                <div class="form-group">
                    <label for="url">Url</label>
                    <input type="text" class="form-control @error('url') is-invalid @enderror" id="url" name="url" placeholder="URL" value="{{ old('url') }}">
                    @error('url')
                        <div class="invalid-feedback">{{ $message }}</div>
                    @enderror
                </div>
                <div class="form-group">
                    <label for="description">Description</label>
                    <textarea class="form-control @error('description') is-invalid @enderror" id="description" name="description" placeholder="description">{{ old('description') }}</textarea>
                    @error('description')
                        <div class="invalid-feedback">{{ $message }}</div>
                    @enderror
                </div>
                <button type="submit" class="btn btn-primary">Submit</button>
            </form>
        </div>
    </div>
@endsection

在这个表单中我们还有事情要做,所以我们可以看下当你生成一个新的 Laravel 的时候会有一个主要的困惑点。

在表单的头部,我们会有一个 blade 条件去检查如果发现有任何错误的话. 当存在错误的时候, Bootstrap 模板上将会出现一个警告的消息, 提示用户修复无效的表单字段:

@if ($errors->any())
    <div class="alert alert-danger" role="alert">
        Please fix the following errors
    </div>
@endif

每个单独的表单字段将会检查验证错误并显示错误信息然后输出到 has-error 这个类中:

<div class="form-group">
    <label for="title">Title</label>
    <input type="text" class="form-control @error('title') is-invalid @enderror" id="title" name="title" placeholder="Title" value="{{ old('title') }}">
    @error('title')
        <div class="invalid-feedback">{{ $message }}</div>
    @enderror
</div>

如果用户提交了无效数据,则路由会将验证存储在会话中,并将用户重定向回表单。{{old('title')}}函数将填充原始提交的数据。如果用户忘记提交其中一个字段,则在验证失败并显示错误后,将填充具有数据的其他字段。

如果字段中有错误,则@error指令将提供一个错误消息变量,你可以在指令块中使用该变量:

@error('title')
    <div class="invalid-feedback">{{ $message }}</div>
@enderror

检查和消除错误的另一种方法涉及在验证失败并重定向后提供给视图的$ error变量:

@if($errors->has('title'))
    <div class="invalid-feedback">{{ $errors->first('title') }}</div>
@endif

@error指令在后台使用相同的变量,可以随意使用你喜欢的任何一种方法。

提交表单

有了表单后,我们就可以在服务器上处理发送和验证表单数据了。返回routes/web.php文件,为POST请求创建另一个路由:

use Illuminate\Http\Request;

Route::post('/submit', function (Request $request) {
    $data = $request->validate([
        'title' => 'required|max:255',
        'url' => 'required|url|max:255',
        'description' => 'required|max:255',
    ]);

    $link = tap(new App\Link($data))->save();

    return redirect('/');
});

注意:确保在 web.php 顶部添加使用 Illuminate\Http\Request

这条路由比其他路由稍微复杂一些。

首先,我们注入 Illuminate\Http\Request 对象,该对象保存POST数据和有关请求的其他数据。

接下来,我们使用请求的validate()方法来验证表单数据。 validate方法是在Laravel 5.5中引入的,它是用于验证的其他方法的捷径。另外,验证后的字段将返回到 $data 变量,我们可以使用它们填充模型。

我们需要这三个字段,使用管道字符可以定义多个规则。所有三个规则最多可以有255个字符,url 字段需要一个有效的url。

如果验证失败,则会引发异常,并且路由会向用户返回原始输入数据和验证错误。

接下来,我们使用 tap() 辅助函数来创建一个新的 Link 模型实例,然后将其保存。使用 tap 允许我们调用 save() 并在保存后仍返回模型实例。

通常,你必须在不使用 tap 的情况下执行以下操作,它只是添加了一点语法:

$link = new \App\Link($data);
$link->save();

return $link;

如果要用数据填充新模型,则需要允许通过批量分配「填充」字段。 fillable 属性旨在防止大量分配字段,除了你在数组中定义的项目之外。

请考虑一下:我们从请求中获取用户输入,并在数据库模型上大量分配值。请注意用户提交数据的危险性,并注意防范你不希望用户通过表单直接操作的数据。

在我们的示例中,我们正在验证每个字段,因此允许对其进行大规模分配是安全的。要允许我们的模型为这些字段赋值,请打开 app/Link.php 文件并将其更新为如下所示:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Link extends Model
{
    protected $fillable = [
        'title',
        'url',
        'description'
    ];
}

如果我们想避免大量分配,这就是我们的代码看起来的样子:

$data = $request->validate([
    'title' => 'required|max:255',
    'url' => 'required|url|max:255',
    'description' => 'required|max:255',
]);

$link = new \App\Link;
$link->title = $data['title'];
$link->url = $data['url'];
$link->description = $data['description'];

// 保存模型
$link->save();

我们在POST路由中所做的最后一件事是在成功保存链接后将用户重定向回主页。

此时,我们的表单应防止提交带有无效字段的链接:

如果表单通过验证,则数据应保存在数据库中,并且用户重定向回主页。

##测试表单提交

我们有一个基本的工作表单,但是,我们应该通过编写测试来确保它继续工作。

Laravel 使 HTTP 测试变得轻而易举,从而可以对路由和 middleware 进行集成测试,因此,让我们编写一些功能测试来验证我们的代码是否按预期工作。

在开始之前,我们需要在我们的 phpunit.xml 文件中进行一些调整,以便可以使用内存中的 SQLit e数据库。你需要确保已安装正确的PHP模块。

从 Laravel7 开始,在项目的 phpunit.xml 文件配置内存中的 SQLite 数据库。如果你使用的是较旧的 Laravel 版本,请通过添加以下内容来更改数据库连接:

<php>
        <!-- ... -->
    <env name="DB_CONNECTION" value="sqlite"/>
    <env name="DB_DATABASE" value=":memory:"/>
        <!-- ... -->
</php>

接下来,删除 Laravel 附带的占位符测试:

rm tests/Feature/ExampleTest.php

我们准备开始通过 HTTP 请求测试 /submit 表单,以确保路由验证,保存和重定向按预期工作。

首先,让我们创建一个新的功能测试,以针对我们的路由进行测试:

php artisan make:test SubmitLinksTest

该命令将创建一个具有适当依赖关系的新测试文件,其中包括一个 RefreshDatabase 特征,我们将使用它来验证我们的链接是否在有效时保存到数据库中。

打开新的 tests/Feature/SubmitLinksTest.php 文件,让我们在要充实的类的主体中定义几个骨架测试:

/** @test */
function guest_can_submit_a_new_link() {}

/** @test */
function link_is_not_created_if_validation_fails() {}

/** @test */
function link_is_not_created_with_an_invalid_url() {}

/** @test */
function max_length_fails_when_too_long() {}

/** @test */
function max_length_succeeds_when_under_max() {}

这些测试应该为你提供我们将要测试的内容的高级概述:

  1. 验证有效链接已保存在数据库中
  2. 验证失败时,链接不在数据库中
  3. 不允许使用无效的URL
  4. 当字段长于 max255 验证规则时,验证应失败
  5. 当字段根据 max255 足够长时,验证应成功。

我们可能遗漏了一些东西,但对于你的第一个 Laravel 应用程序,这是一个不错的列表,它应该说明Laravel 中的一些基本 HTTP 测试技术。

保存有效链接

我们将编写的第一个测试是验证有效数据是否存储在数据库中的测试:

<?php

namespace Tests\Feature;

use Illuminate\Validation\ValidationException;
use Tests\TestCase;
use Illuminate\Foundation\Testing\RefreshDatabase;

class SubmitLinksTest extends TestCase
{
    use RefreshDatabase;

    /** @test */
    function guest_can_submit_a_new_link()
    {
        $response = $this->post('/submit', [
            'title' => 'Example Title',
            'url' => 'http://example.com',
            'description' => 'Example description.',
        ]);

        $this->assertDatabaseHas('links', [
            'title' => 'Example Title'
        ]);

        $response
            ->assertStatus(302)
            ->assertHeader('Location', url('/'));

        $this
            ->get('/')
            ->assertSee('Example Title');
    }
}

记下 RefreshDatabase 特性,该特性可确保每个测试都有一个新数据库,从而为每个测试提供一个包含所有迁移的原始数据库环境。

我们的第一个测试会提交有效的发布数据,该数据会返回一个响应对象,我们可以使用该对象断言我们的路线是否按预期响应。我们验证数据库是否包含具有刚刚创建的标题的记录。

接下来,我们验证响应是否为 302 状态代码,并带有指向首页的 Location 标头。

最后,我们请求主页并验证链接标题在主页上可见。

让我们进行第一个测试,以确保一切顺利。 Laravel 7 添加了一个新的 artisan test 命令,或者您可以使用 phpunit

php artisan test

# 或直接运行 phpunit
vendor/bin/phpunit

你应该看到测试套件通过了:

测试验证失败

通常当用户提交错误数据时,我们希望验证会触发异常,我们可以用它来确保验证层正常工作:

/** @test */
function link_is_not_created_if_validation_fails()
{
    $response = $this->post('/submit');

    $response->assertSessionHasErrors(['title', 'url', 'description']);
}

我们使用 Laravel 的 assertSessionHasErrors() 来确保会话对每个必需字段都有验证错误。由于我们向路由提交了空数据,因此我们希望 required 规则将为每个字段触发。

让我们运行测试套件以验证到目前为止的工作:

$ php artisan test tests/Feature/SubmitLinksTest

   PASS  Tests\Feature\SubmitLinksTest
  ✓ guest can submit a new link
  ✓ link is not created if validation fails

  Tests:  2 passed
  Time:   0.32s

###测试 URL 验证

我们期望只有有效的 URLs 通过验证,因此我们的应用不会去显示无效的数据。

/** @test */
function link_is_not_created_with_an_invalid_url()
{
    $this->withoutExceptionHandling();

    $cases = ['//invalid-url.com', '/invalid-url', 'foo.com'];

    foreach ($cases as $case) {
        try {
            $response = $this->post('/submit', [
                'title' => 'Example Title',
                'url' => $case,
                'description' => 'Example description',
            ]);
        } catch (ValidationException $e) {
            $this->assertEquals(
                'The url format is invalid.',
                $e->validator->errors()->first('url')
            );
            continue;
        }

        $this->fail("The URL $case passed validation when it should have failed.");
    }
}

Laravel有一个withoutExceptionHandling()方法,它可以禁用 Laravel 的路由异常控制代码,这段代码会在异常后生成一个 HTTP 响应,我们使用这个功能来查看验证异常的对象和断言错误消息。

我们遍历各种情况(如果你想涵盖更多场景,请自定义) 并且捕获 ValidationException 实例。我们期望路由每次都抛出一个 ValidationExcepiton,如果文本通过了异常处理,那么我们就手动地让测试失败。
这个 catch 代码块使用验证器对象检查 url 的错误并断言实际的错误消息匹配期望的验证错误消息。

相比使用 PHPUnit 提供的异常注解,我喜欢更用 try/catch 方式,然后跟着一个 $this->fail() 作为安全保障。为了避免让人困惑的测试失败,要确保捕获异常里有 return 。我觉得捕获异常可以执行其他情况下不可能实现的断言,并提供一个我喜欢的在大多数情况下更细粒度的控制。

测试最大长度验证

我们将使用 max255 验证规则测试一些场景:当字段未能通过长度为 256 个字符的最大长度验证时,以及当字段足够长以通过时在 255 字符处进行验证。

尽管 Laravel 包含 max 验证规则功能,但我还是想对其进行测试以验证我的应用程序是否应用了规则。如果有人删除了 max 验证规则,则测试将捕获该规则。

我喜欢测试最小和最大验证规则的阈值,以确保我的应用程序遵守我设置的最小和最大边界。

首先,让我们测试「最大长度」方案:

/** @test */
function max_length_fails_when_too_long()
{
    $this->withoutExceptionHandling();

    $title = str_repeat('a', 256);
    $description = str_repeat('a', 256);
    $url = 'http://';
    $url .= str_repeat('a', 256 - strlen($url));

    try {
        $this->post('/submit', compact('title', 'url', 'description'));
    } catch(ValidationException $e) {
        $this->assertEquals(
            'The title may not be greater than 255 characters.',
            $e->validator->errors()->first('title')
        );

        $this->assertEquals(
            'The url may not be greater than 255 characters.',
            $e->validator->errors()->first('url')
        );

        $this->assertEquals(
            'The description may not be greater than 255 characters.',
            $e->validator->errors()->first('description')
        );

        return;
    }

    $this->fail('Max length should trigger a ValidationException');
}

再次,我们禁用异常处理并创建一个字符过长而无法通过验证的数据。

我们断言每个字段,确保它们都有一个最大长度的验证错误消息。

最后,我们需要在捕获异常里 return 并使用 $this->fail() 作为测试失败的安全保障。

接下来,我们测试 「最大值」 场景:

/** @test */
function max_length_succeeds_when_under_max()
{
    $url = 'http://';
    $url .= str_repeat('a', 255 - strlen($url));

    $data = [
        'title' => str_repeat('a', 255),
        'url' => $url,
        'description' => str_repeat('a', 255),
    ];

    $this->post('/submit', $data);

    $this->assertDatabaseHas('links', $data);
}

我们创建一个超过了 max:255 不能通过验证的表单数据,并且断言提交数据后数据已经在数据库里。

运行测试套件并且确保通过测试:

$ php artisan test tests/Feature/SubmitLinksTest

   PASS  Tests\Feature\SubmitLinksTest
  ✓ guest can submit a new link
  ✓ link is not created if validation fails
  ✓ link is not created with an invalid url
  ✓ max length fails when too long
  ✓ max length succeeds when under max

  Tests:  5 passed
  Time:   0.58s

结语

祝贺你读完了本教程!

本教程的目的是让你开始构建你的应用,并且它也可能是你开发应用的一砖一瓦式的技能,我知道本教程涵盖了很多功能,如果你不熟悉这个框架你会不知所措。

我希望这个关于 Laravel 的介绍能让你知道为什么会这么多人对这个框架如痴如醉。

本文中的所有译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。

原文地址:https://laravel-news.com/your-first-lara...

译文地址:https://learnku.com/laravel/t/55314

本文为协同翻译文章,如您发现瑕疵请点击「改进」按钮提交优化建议
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
讨论数量: 1

谢谢各位的翻译,希望论坛多一些这种面向新手的简明教程。

4周前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!