首页 » Web技术 » Laravel » 正文

Laravel入门教程实战:任务列表(基础版)

1. 介绍

该快速入门指南提供了Laravel框架的基本介绍,包含了数据库迁移、Eloquent ORM、路由、验证、视图、Blade模版等内容。如果你是Laravel框架或者PHP框架的新手,这将是一个很好的起点。如果你已经在使用Laravel框架或者其他PHP框架,你可以参考我们更高级的快速入门。

本节将通过建立一个任务列表来讲解Laravel的功能,该任务列表可以用来追踪所有我们想要完成的任务(典型的“待办事项”的例子)。完整的代码已经放在Github上。

2. 安装

首先,你需要安装一个新的Laravel框架。你可以使用Homestead或者本地PHP环境来运行该框架。当环境配置好之后,可以使用 Composer 来安装框架:

composer create-project laravel/laravel quickstart --prefer-dist

你可以选择根据该入门剩下的部分来自行完成,也可以直接下载代码,然后在机器上运行它,你可以从Git仓库clone它然后安装依赖:

git clone https://github.com/laravel/quickstart-basic quickstart
cd quickstart
composer install
php artisan migrate

关于如何建立本地Laravel环境的更详细文档,请查看 Homestead安装 文档。

3. 数据库准备

3.1 数据库迁移

首先,我们用数据库迁移(migration)来定义保存任务所需的数据库表。Laravel通过PHP代码提供了一个非常简单的方法来定义数据库结构和修改使用流程。你的团队成员可以通过运行你提交的源代码来管理数据库,而不需要告诉他们,然后手动添加列。

下面就让我们来建立一个保存所有任务的数据库表。当你建立Laravel项目的时候,Artisan CLI可以用来生成各种类,节省你很多打字 时间。这里,我们使用 make:migration 来为 tasks 表建立一个新的数据库迁移:

php artisan make:migration create_tasks_table --create=tasks

迁移文件会被放在项目下的 database/migrations 文件夹中。你可能已经注意到了,make:migration 已经自动的为迁移文件添加了一个自增的ID和时间戳。下面编辑该文件,添加一个保存任务名称的 string 列。

<?php

use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateTasksTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('tasks', function (Blueprint $table) {
            $table->increments('id');
            $table->string('name');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::drop('tasks');
    }
}

我们将使用 migrate Artisan命令来运行迁移。如果你使用的是Homestead,你应当在虚拟机中来运行该命令,因为你的主机不能访问到数据库:

php artisan migrate

该命令会创建我们需要的所有的表。如果你使用数据库管理工具来查看我们创建的 tasks 表,你将看到,其中已经包含了我们在文件中定义的所有的列。下面就可以为我们的任务定义 Eloquent ORM 模型了。

3.2 Eloquent ORM 模型

Eloquent 是 Laravel 默认的ORM(object-relational mapper 对象关系映射)。Eloquent 使用清晰定义的“models(模型)”来检索和存储数据库中的数据。通常情况下,每一个Eloquent 模型都对应与一个数据库中的表。

因此,让我们定义一个 Task 模型来对应数据库中的 tasks 表。这里我们还是可以使用 Artisan 命令来生成该模型。此处我们使用 make:model 命令:

php artisan make:model Task

模型会被放在应用的 app 目录下。默认情况下,该模型类是空的。我们不用明白的指出该 Eloquent 模型对应的数据库表,因为一般会假设它对应的是该模型名称的复数形式的数据库表。因此,Task 模型被假定与 tasks 表相对应。我们的空数据模型应该是这样的:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Task extends Model
{
    //
}

当我们为应用添加路由的时候会学习更多关于模型的内容。当然,你也可以查看完整的 Eloquent 文档来了解更多内容。

4. 路由

4.1 定义路由

下面我们来为应用添加一些路由。路由是当用户访问一个给定的页面时,用来指定需要执行的控制器地址或者匿名函数。默认情况下,Laravel的所有路由都被定义在 app/Http/routes.php 文件中。

对于该应用,我们至少需要三个路由:一个用来显示所有任务列表、一个用来添加任务、以及一个用来删除任务的路由。所以,让我们在 app/Http/routes.php 文件中来定义这三个路由:

<?php

use App\Task;
use Illuminate\Http\Request;

/**
 * Display All Tasks
 */
Route::get('/', function () {
    //
});

/**
 * Add A New Task
 */
Route::post('/task', function (Request $request) {
    //
});

/**
 * Delete An Existing Task
 */
Route::delete('/task/{id}', function ($id) {
    //
});

4.2 显示视图

首先我们来定义 / 路由,该路由用来渲染HTML模版,其中包含了添加任务及所有任务的列表。

在Laravel中,所有的视图文件都保存在 resources/views 目录中,并且我们可以使用 view 辅助函数来指定所要现实的视图文件:

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

当然,我们还需要定义视图文件,下面就开始吧。

5. 建立布局和视图

该应用只需要一个视图,其中包含了添加任务的表单及显示所有任务的列表。为了让你更加明白,下面是一个已经完成的使用Bootstrap定义样式的页面截图:

basic-overview

5.1 定义布局

几乎所有WEB应用都使用同一个布局。例如,每一个页面顶部都有一个导航栏。Laravel通过使用 Blade 模版使得共用布局变得很简单。

在前面我们已经讨论过了,所有视图文件都存放在 resources/views 目录下。所以让我们来定义一个新的布局文件 resources/views/layouts/app.blade.php.blade.php 后缀告诉框架使用 blade 模版引擎来渲染视图。当然,你也可以在Laravel中使用普通的PHP模版。然而,Blade 提供了更简洁的模版。

我们的 app.blade.php 视图文件看起来应该是这样的:

// resources/views/layouts/app.blade.php

<!DOCTYPE html>
<html lang="en">
    <head>
        <title>Laravel Quickstart - Basic</title>

        <!-- CSS And JavaScript -->
    </head>

    <body>
        <div class="container">
            <nav class="navbar navbar-default">
                <!-- Navbar Contents -->
            </nav>
        </div>

        @yield('content')
    </body>
</html>

注意布局中的 @yield('content') 部分,这是一个特殊的 Blade 指令,指定所有子页面可以在这里注入自己的代码来扩展布局。下面让我们使用该布局来定义一个子视图,并添加内容。

5.2 定义子视图

前面我们已经完成了应用的布局,下面我们需要定义一个包含添加任务的表单及展示所有任务的列表的子视图。我们在 resources/views/tasks.blade.php 文件中定义该视图。

我们跳过 Bootstrap CSS 样式而专注于更重要的事,你可以在Github上下载所有的源码:

// resources/views/tasks.blade.php

@extends('layouts.app')

@section('content')

    <!-- Bootstrap Boilerplate... -->

    <div class="panel-body">
        <!-- Display Validation Errors -->
        @include('common.errors')

        <!-- New Task Form -->
        <form action="/task" method="POST" class="form-horizontal">
            {{ csrf_field() }}

            <!-- Task Name -->
            <div class="form-group">
                <label for="task" class="col-sm-3 control-label">Task</label>

                <div class="col-sm-6">
                    <input type="text" name="name" id="task-name" class="form-control">
                </div>
            </div>

            <!-- Add Task Button -->
            <div class="form-group">
                <div class="col-sm-offset-3 col-sm-6">
                    <button type="submit" class="btn btn-default">
                        <i class="fa fa-plus"></i> Add Task
                    </button>
                </div>
            </div>
        </form>
    </div>

    <!-- TODO: Current Tasks -->
@endsection

一些额外的说明:

在继续之前,我们先来讨论下该模版。首先, @extends 告诉 Blade 我们使用的是在 resources/views/layouts/app.blade.php 中定义的布局。而所有位于 @section('content') 和 @endsection 之间的内容都会被注入到 app.blade.php 布局中 @yield('contents') 的位置。

下一步我们准备添加 POST /task 中的代码,它将处理表单提交过来的数据,并把它插入到数据库中。

注:@include('common.errors') 命令将自动载入 resources/views/common/errors.blade.php 模版文件,现在我们还没有定义该文件,但是下面将会做这件事。

6. 添加任务

6.1 验证

现在,我们在视图中已经定义了一个表单,我们需要做的是为 POST /task 路由添加用来验证表单输入及创建新的任务的代码。首先,我们来验证输入的数据。

对于这个表单,我们需要确保 name 是必填的,并且不能多于 255 个字符。如果验证失败,将重定向到 / 路由,并且会把原输入和错误信息缓存到 session 中:

Route::post('/task', function (Request $request) {
    $validator = Validator::make($request->all(), [
        'name' => 'required|max:255',
    ]);

    if ($validator->fails()) {
        return redirect('/')
            ->withInput()
            ->withErrors($validator);
    }

    // Create The Task...
});

$errors 变量

这里,我们先暂停一下,讨论一下例子中的 ->withErrors($validator)  部分。 ->withErrors($validator) 的调用会把验证实例的返回信息缓存到 session 中,以便于我们能够在视图中访问 $errors 变量。请记得我们在前面使用 @include('common.errors') 来显示表单验证失败返回的信息。common.errors 视图允许我们在所有的页面使用相同的格式来显示验证的错误信息。下面我们来定义视图的内容:

// resources/views/common/errors.blade.php

@if (count($errors) > 0)
    <!-- Form Error List -->
    <div class="alert alert-danger">
        <strong>Whoops! Something went wrong!</strong>

        <br><br>

        <ul>
            @foreach ($errors->all() as $error)
                <li>{{ $error }}</li>
            @endforeach
        </ul>
    </div>
@endif
注意:$errors 变量在Laravel的所有视图中都是可用的。如果没有验证错误信息的话,它只是返回一个空的 ViewErrorBag 实例。

6.2 创建任务

既然已经完成了验证,现在是时候来完成创建任务的路由了。当任务创建完成之后,我们将会重定向会 / 。要创建一个任务,我们可以在创建和设置完 Eloquent 模型的属性后调用 save 方法:

Route::post('/task', function (Request $request) {
    $validator = Validator::make($request->all(), [
        'name' => 'required|max:255',
    ]);

    if ($validator->fails()) {
        return redirect('/')
            ->withInput()
            ->withErrors($validator);
    }

    $task = new Task;
    $task->name = $request->name;
    $task->save();

    return redirect('/');
});

太棒了,现在我们已经可以成功的创建任务了。接下来我们继续完成显示已存在任务列表的功能。

6.3 显示已存在任务

首先我们需要编辑 / 路由,把已存在的任务传递给视图。view 函数接受第二个参数,它可以为视图提供数组数据。数组中的每一个键将成为视图中的变量:

Route::get('/', function () {
    $tasks = Task::orderBy('created_at', 'asc')->get();

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

一旦数据传递给视图,我们就可以在 tasks.blade.php 视图中显示它们了。Blade 中的 @foreach 结构可以快速的编译为普通的PHP代码:

@extends('layouts.app')

@section('content')
    <!-- Create Task Form... -->

    <!-- Current Tasks -->
    @if (count($tasks) > 0)
        <div class="panel panel-default">
            <div class="panel-heading">
                Current Tasks
            </div>

            <div class="panel-body">
                <table class="table table-striped task-table">

                    <!-- Table Headings -->
                    <thead>
                        <th>Task</th>
                        <th>&nbsp;</th>
                    </thead>

                    <!-- Table Body -->
                    <tbody>
                        @foreach ($tasks as $task)
                            <tr>
                                <!-- Task Name -->
                                <td class="table-text">
                                    <div>{{ $task->name }}</div>
                                </td>

                                <td>
                                    <!-- TODO: Delete Button -->
                                </td>
                            </tr>
                        @endforeach
                    </tbody>
                </table>
            </div>
        </div>
    @endif
@endsection

到这里,我们的任务应用基本上就完成了。但是当我们已经完成了任务的时候,还没有办法删除它,现在就来实现此功能。

7. 删除任务

7.1 添加删除按钮

我们在需要显示删除按钮的地方添加了 “TODO” 注释。让我们为 tasks.blade.php 视图中每一个任务的后面添加删除按钮。我们为列表中每一个任务创建一个小的单按钮表单。当点击按钮的时候,会向 DELETE /task 发送请求:

<tr>
    <!-- Task Name -->
    <td class="table-text">
        <div>{{ $task->name }}</div>
    </td>

    <!-- Delete Button -->
    <td>
        <form action="/task/{{ $task->id }}" method="POST">
            {{ csrf_field() }}
            {{ method_field('DELETE') }}

            <button>Delete Task</button>
        </form>
    </td>
</tr>

关于方法欺骗(Method Spoofing)的说明

请注意删除表单是POST,即使我们需要使用 Route::delete 路由响应请求。因为HTML表单只接受 GETPOST 两个动词,因此我们需要给表单添加一个伪装的 DELETE 请求。

我们可以在表单中使用 method_field('DELETE') 函数来伪装 DELETE 请求。它会生成一个Laravel可以识别的隐藏域,并用它覆盖实际的HTTP请求方法。它会生成下面的HTML代码:

<input type="hidden" name="_method" value="DELETE">

7.2 删除任务

最后,让我们来添加实际删除任务的逻辑代码。我们可以使用 Eloquent 的 findOrFail 方法根据 ID 来检索数据,或者当模型不存在时返回一个 404 异常。一旦我们获取到模型,就可以使用 delete 方法来删除记录。一旦记录被删除,我们就可以重定向会 / 路由:

Route::delete('/task/{id}', function ($id) {
    Task::findOrFail($id)->delete();

    return redirect('/');
});

完!

翻译自:laravel.com

本文共 4 个回复

发表评论