Laravel 快速入门

上周我在团队内做了 Laravel 入门分享,希望能够帮助对这款框架不熟悉的同学快速上手,最好听完就能撸个接口。作为前端小哥的我自知对后端了解有限,于是我事先写了个 demo,围绕一个假定的需求 —— 学生信息的增删改查来讲这堂课。

这篇文章假设读者已经掌握 Laravel 的安装,若不了解请先移步 文档

数据库

迁移

首先我们要建一个班级表和一个学生表。Laravel 提供了迁移(migration)功能用于创建和更新数据表。

简单地说,我们把表结构用编程的方式写在文件中,然后执行这些文件,达到建表和更新表结构的目的。每个迁移文件都包含一个 up 方法和一个 down 方法,分别用于执行和回滚迁移。

在 CLI 执行以下命令创建两张表的迁移文件:

1
2
php artisan make:migration create_classes_table
php artisan make:migration create_students_table

此时可在 database/migrations 目录下找到新增的 2 个迁移文件。

我们先来看看 classes 表的迁移文件,Laravel 已经帮我们写了一些代码。

1
2
3
4
Schema::create('classes', function (Blueprint $table) {
$table->increments('id'); // 创建一个自增的 id 字段
$table->timestamps(); // 创建 created_at 和 updated_at 字段
});

我增加了一个 name 字段,用来保存班级名称。实际上,这句代码在数据库中创建的是一个 varchar 类型,最大长度 16 个字符的字段。

1
$table->string('name', 16);

接下来编辑 students 表的迁移文件:

1
2
3
4
5
6
7
8
Schema::create('students', function (Blueprint $table) {
$table->increments('id');
$table->string('number', 16); // 学生编号
$table->string('name', 16); // 学生姓名
$table->tinyInteger('class_id'); // 班级 ID
$table->timestamps();
$table->softDeletes(); // 创建 deleted_at 字段
});

然后在 CLI 中执行 php artisan migrate 运行迁移,数据库中便创建了 classesstudentsmigrations 等表。

migrations 表用于记录执行过哪些迁移。

created_atupdated_at 字段分别用于存储创建时间和更新时间。当使用 Eloquent ORM 方式修改数据时,它们将自动更新。

deleted_at 字段用于软删除数据,即记录不会真的从数据库中删除,而是存储一个删除时间,这些数据便不会再被查询出来。

填充

有时候我们希望给数据表批量写入一些数据。例如,在建完 classes 表后将已知的所有班级信息插入到表中。Laravel 提供了填充(seed)功能用于填充测试数据。

在 CLI 执行以下命令创建一个填充器。

1
php artisan make:seeder ClassesTableSeeder

编辑 database/seeds 目录下新增的 ClassesTableSeeder.php ,在 run 方法中插入代码:

1
2
3
DB::table('classes')->insert(['name' => '三年一班']);
DB::table('classes')->insert(['name' => '三年二班']);
DB::table('classes')->insert(['name' => '三年三班']);

执行以下命令运行填充器:

1
php artisan db:seed --class=ClassesTableSeeder

然后便可以在 classes 表中看见刚刚填充进去的 3 个班级。

路由

API 路由应该在 route/api.php 中声明,Route 类提供了 get/post/patch/delete 等路由方法用于定义不同类型的路由。

我们先定义一个简单的路由:

1
2
3
4
Route::get('hello', function (Request $request) {
$name = $request->input('name'); // 获取请求参数
return "Hello Laravel, I am {$name} !"; // 响应字符串内容
});

然后我们访问 http://{你的域名}/api/hello?name=YIMING,浏览器将显示:

1
Hello Laravel, I am YIMING !

通过这个 Hello World 路由可以知道,路由方法的第一个参数是 URI ,第二个参数是一个 callback 。

URI 中可以使用 {} 声明路由参数,并在回调函数中使用:

1
2
3
Route::get('hello/{name}', function ($name) {
return "Hello Laravel, I am {$name} !";
});

路由也可以指向某个控制器动作(方法):

1
2
3
4
5
Route::get('students', 'StudentController@index');
Route::post('students', 'StudentController@store');
Route::get('students/{student}', 'StudentController@show');
Route::patch('students/{student}', 'StudentController@update');
Route::delete('students/{student}', 'StudentController@destory');

如果控制器是一个符合要求的 RESTful 资源控制器(见下文),上面这些路由等价于。

1
Route::resource('students', 'StudentController');

模型

Laravel 提供了 Eloquent ORM(对象关系映射),一个模型对应一张数据表,通过模型类操作数据表。模型文件默认放在 app 目录下。

举个例子,假设存在 User 模型,那么它将默认对应数据库中的 users 表,我们可以这样查询数据:

1
User::where('id', 1)->get(); // 查询 id 等于1的用户

执行以下命令分别为班级表、学生表创建模型:

1
2
php artisan make:model StudentClass
php artisan make:model Student

Student 模型默认对应 students 表。

对于 StudentClass 模型,我们可以显式地声明它的关联表为 classes

1
2
3
4
class StudentClass extends Model
{
protected $table = 'classes';
}

然后编辑 Student 模型:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
namespace App;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;

class Student extends Model
{
// 启用软删除
use SoftDeletes;
// 可被批量赋值的字段
protected $fillable = [
'number',
'name',
'class_id'
];
// 与班级表的关联关系
public function studentClass ()
{
return $this->hasOne('App\StudentClass', 'id', 'class_id');
}
}

控制器

基础

在路由小节中,我们注册了一个指向 StudentController 控制器的资源路由。

1
Route::resource('students', 'StudentController');

执行以下命令创建 StudentController 控制器:

1
php artisan make:controller StudentController

由于 StudentController 是一个资源控制器,下列请求将自动指向相应控制器方法。

请求方式 URI 控制器方法 操作
GET /api/students index 查询全部
GET /api/students/{student} show 查询单条
POST /api/students store 创建
PATCH /api/students/{student} update 修改
DELETE /api/students/{student} destroy 删除

首先,在控制器中导入 Request、Validator 和 Student 模型:

1
2
3
use Illuminate\Http\Request;
use Validator;
use App\Student;

请求类(Request)用于获取参数,验证类(Validator)用于验证参数的合法性,Student 模型用于 students 表的增删改查操作。

查询

index 方法使用模型查询数据表,然后返回学生列表:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public function index ()
{
// 查询全部记录
return Student::all();
// 查询三年一班的学生
return Student::where('class_id', '1')->get();
// 查询前两个班的学生
return Student::where('class_id', '<=', '2')->get();
// 包含软删除的记录
return Student::withTrashed()->get();
// 分页 每页15条记录
return Student::paginate(15);
// 同时查询关联数据
return Student::with('studentClass')->get();
}

启用分页时,返回的结果中会包含页码、总页数等数据。

在请求时传递 page 可以查询指定页码的数据,否则默认返回第一页。

1
/api/students?page=2

由于在 Student 模型中声明了和 StudentClass 模型(即班级表)的关联关系,我们可以使用 with 同时查出学生的班级信息。

1
2
3
4
5
6
7
8
9
[{
number: '2018090201'
name: '张三'
...
studentClass: {
name: '三年一班',
...
}
}]

show 方法接收一个路由参数,返回指定 id 的学生:

1
2
3
4
public function show ($id)
{
return Student::find($id);
}

新增

store 方法接收用户输入,验证参数的合法性,然后创建一名学生。这里不再赘述验证(Validation)功能的用法,感兴趣的同学可以移步官方文档了解。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public function store (Request $request)
{
// 验证器
$validator = Validator::make($request->all(), [
// 必填,在 students 表中唯一,不多于10个字符。
'number' => 'required|unique:students|max:10',
// 必填,不多于8个字符。
'name' => 'required|max:8',
// 必填,只能是1、2或3。
'class_id' => 'required|in:1,2,3'
]);
// 当验证失败时响应 422 错误
if ($validator->fails()) {
return response($validator->errors(), 422);
}
return Student::create($request->all());
}

修改

update 方法接收用户输入和路由参数(学生 id),然后更新相应学生的信息。

1
2
3
4
public function update (Request $request, $id)
{
Student::where('id', $id)->update($request->all());
}

删除

destroy 方法接收一个路由参数(学生 id),然后删除相应的学生。由于模型中启用了软删除,不会真的从数据表中删除记录,而是更新其 deleted_at 字段。

1
2
3
4
public function destory ($id)
{
Student::destroy($id);
}

最后

你可以在 Postman 中调试一下这几个接口了,happy hacking !

相关链接:

Laravel 5.6 官方文档

Laravel 5.6 中文文档

本文中的 demo 代码

相关环境:macOS 10.13 / Laravel Homestead / Laravel 5.6