我们都遇到过这个错误,至少可以说这很烦人。看起来我们总是做对了一切,一旦我们尝试渲染页面,就会产生万能的 Route Not Defined 错误。 在本文中,我们将发现如何修复 Laravel 中非常常见的路由未定义错误。此错误通常指向路由、控制器或视图文件。调查这些文件将帮助我们修复路由未定义问题。…
laravel 数据库操作 Migrations, Laravel 的 Migrations 详解, laravel Schema Builder
Laravel 为我们提供了数据库结构操作功能 Migrations (数据库迁移),我们可以通过它创建一张数据库表,改变其中的结构,并在此基础上提供迁移和回滚功能。
但是,我们公司在进行 Laravel 开发的时候没有用到这个功能,先谈谈我们是怎么做的:
- 通过数据库建模工具导出 SQL 到数据库
- 大家连接到服务器上的公共数据库进行开发
- 表结构因需求变化时用 Navicat for MySQL 直接更改
直到我发现 Django 和 Cake PHP、Ruby On Rails 也提供类似的功能,我觉得我需要重新认识 Migrations 了。
Install 安装
php artisan migrate:install
在配置好数据库以后,这条命令会在数据库中创建一个名叫 migrations
的表,包括字段:
- id
- migration
- batch
这张表是 Migrations 的基础,用来标识数据库哪个迁移已经执行,哪个迁移还未执行。
Migration
数据库迁移文件是这套系统的重要组成部分,假如需要在现有的系统中加入博客文章功能,我们创建一个数据库迁移文件。
创建迁移
使用 make:migration Artisan
命令来创建迁移
php artisan make:migration create_test_table
新创建的迁移会放在你的 database/migrations
目录。
你运行的时候肯定不会跟我这个文件名一样,因为我们很容易就发现这个文件加了时间前缀,也就是说我是在 2019-11-06 16:08:05 创建的这个文件。
--table
和 --create
选项也可用于确定表的名称以及是否在迁移中创建新的数据表。这些选项用指定的迁移模板预先填充指定的数据表,这里就不做过多演示了
php artisan make:migration create_test_table --create=test php artisan make:migration add_votes_to_test_table --table=test
迁移结构
除了我们创建的 test
表迁移文件,我们还发现了 laravel
框架自带的 2014 年的 users
表和 password_resets
表,直接打开2014_10_12_000000_create_users_table.php
我们来参考下它的内容
一共有两个方法 up
和 down
,up
方法是用于新增数据库的数据表、字段或者索引的,而 down
方法与 up
方法执行操作相反是用来删除表的。
在这两种方法中,你可以使用 Laravel
的结构生成器以表达式方式创建和修改表。 Schema
生成器上可用的所有方法 请查阅 官方文档
我们直接来读上图的代码,大致意思是
- 要创建一个
user
表 - 指定这个表的主键为
id
- 指定
name
字段为字符串类型 - 指定
email
字段为为字符串类型且限制唯一性 - 指定
email_verified_at
字段为TIMESTAMP类型并且此字段允许写入NULL
值 - 指定
password
字段为字符串 rememberToken
这个字段不通用就不多讲具体看手册- 重点要说下
timestamps
,$table->timestamps()
的作用是给表增加created_at
和updated_at
它们的类型是timestamps
laravel
插入和编辑数据的时候会自动通过这两个字段记录操作的日期时间
这我们就发现了 laravel 的又一特点,整个项目对于各种命名的斟酌,很多时候我们即便不看文档甚至不看源代码注释只看方法名就能猜到作用了,她不只是一个框架还是我们编程的一个范本。 参考了 users
表我们回到 2019_11_06_160805_create_test_table.php
通过命令行生成文件的同时自动已经生成了下面这样的代码
很明显 laravel
默认表的主键字段名为 id
然后默认表有 created_at
和 updated_at
字段,增删改查不分家,增和改都默认有了个字段记录操作日期了,那删怎么能没有呢?没错 laravel
又为我们设计好了。
$table->softDeletes();
这个方法就是为表增加一个 deleted_at
,laravel
会在删除数据的时候记录操作日期,具体到功能比如 回收站
的功能了,我们可能会删除某些数据,但是我们还希望能恢复删除的数据,当某条数据的 deleted_at
为 null
的时候表示正常,当有日期的时候就表示这条数据是在这个日期被删掉了。
运行迁移
现在回到 2019_11_06_160805_create_test_table.php
我们简单编辑下这个文件
我们在之前学习 artisan
的时候说过 artisan
主要2个作用 一个是创建迁移文件
、一个是执行迁移任务
,我们已经用 artisan
创建控制器和迁移了现在终于到了执行任务的时候了,我们上面的迁移文件定义了表的结构,执行迁移才会真正生成表
php artisan migrate
执行上面的命令的时候up遇到了这样的报错
SQLSTATE[HY000] [2054] The server requested authentication method unknown to the client
这是因为 up 本地 使用的是 MySQL 8
是由于 MySQL 8
默认使用了新的密码验证插件:caching_sha2_password
,而之前的PHP版本
中所带的 mysqlnd
无法支持这种验证。解决这个问题可以在MySQL 8中创建(或修改)使用caching_sha2_password
插件的账户,让其使用mysql_native_password
插件
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'R9s33P8,,8&BH;2';
修改后我们重新执行 php artisan migrate
我们可以看到这样的提示
这意思就是我们的迁移已经完成了,那我们再执行一遍命令呢?我们会看到这样的的提示
Nothing to migrate.
嗯哼?也就是说已经成功的迁移并不会重复执行,这是在哪控制的呢?让我们 连接上 mysql
show tables
一下
除了 laravel
自带的 users
表和 password_resets
表,除了我们创建的 test
表,我们还发现了个 migrations
表,我们看下这个表的内容
我们的3个迁移文件名都在里面记录着了,说明这个表里面存的是已经执行过的迁移的文件名,再查看下 test
表的结构.
完美跟我们迁移文件中写的是一样的表就这么轻松的创建了,但是再认真看会发现并没有 string 类型
,肯定的喽,因为 mysql
压根就没 string
,string
就是 varchar
了,再但是再认真看还会发现除了 timestamp
,其他的字段都多了个 NOT NULL
,这个我们并没有在迁移中指定,这里就需要解释下了,这个 NOT NULL
是 laravel
为我们默认添加的,那如果确实有字段想让它允许为 NULL
怎么办呢?别担心 laravel
还有个 ->nullable()
我们这里学习了最常用的 int 、 varchar 、 text
那更多的类型呢?这时候就是 laravel
官方手册真正的作用了,laravel
官方手册更适合作为一本工具书,我们去像查字典一样去查工具书就可以了。
修改字段
创建表的方式我们已经学会了,除了创建表,我们还经常需要改变表结构,默认的 users
并没有 deleted_at
字段,我们如果想为 用户 也增加一个类似回收站的字段怎么办呢?
我们再来创建一个表迁移文件
php artisan make:migration add_deleted_at_to_users_table
在 add_deleted_at_to_users_table 文件中添加如下代码
Schema::table('users', function (Blueprint $table) { $table->softDeletes(); });
up 中就是我们迁移的内容,创建表的时候我们使用的是 Schema::create
,编辑表的时候我们使用的是 Schema::table
,然后回调函数中的内容跟创建表的时候的格式是一样的,现在我们执行 php artisan migrate
迁移命令。
我们在来看看 users
表的结构 deleted_at
就这么加上了
回退 回滚迁移
down
方法中就是回退的内容了,创建表的时候down
中是drop
表,添加字段的时候down
中的自然就是drop
字段了
Schema::table('users', function (Blueprint $table) { $table->dropColumn('deleted_at'); });
我们一直在说回退说 laravel
的迁移功能可以让我们回退到某个状态,那到底是怎么回退呢?其实也很简单同样是运行命令,为了更深刻的理解 migrations
表的作用,在运行回退命令前我们先看下 migrations
表的内容
一共有5条记录 4条创建表的,1条添加字段的好我们来运行回退命令
php artisan migrate:rollback
migrations
表的第4条添加字段的记录没有了,users
表的 deleted_at
字段也没了,再回退一次就把第一次运行迁移的时候的3张表就全删了,如果再运行迁移命令一切就又有了。
重命名一个存在的数据库表,请使用 rename 方法:
Schema::rename($from, $to);
删除一个存在的数据表,你可以使用 drop 或者 dropIfExists 方法:
Schema::drop('users'); Schema::dropIfExists('users');
修改字段类型
到这里创建表、删除表、添加字段、删除字段我们都学习了,最后再来学习下修改字段的,修改字段需要借助 dbal扩展包
,先来执行下列命令安装扩展包
composer require doctrine/dbal
剩下的工作也很简单我这里举个栗子,比如 test
表没有几条数据,用 int
类型太奢侈了,我们改成 tinyint
就足够了。 那么我们先创建一个迁移文件
php artisan make:migration change_category_id_in_test_table
然后在 up 中写上修改的内容即可
Schema::table('test', function (Blueprint $table) { $table->tinyInteger('testId')->unsigned()->default(0)->comment('测试id')->change(); });
但是这里要讲一个坑,如果直接运行上面这个迁移文件是会报错的因为 dbal
并不支持修改成 tinyInteger
,为了兼容更多类型的数据库需要使用替代方案使用 boolean
类型
那 down
里面就是相反的内容了
总结下就是 up
中写需要迁移的内容 down
中写回退的内容。
本文:laravel 数据库操作 Migrations, Laravel 的 Migrations 详解, laravel Schema Builder