Laravel 自带的 Eloquent ORM 提供了一个美观、简单的与数据库打交道的 ActiveRecord 实现,每张数据表都对应一个与该表进行交互的“Model模型”,模型允许你在表中进行数据查询,以及插入、更新、删除等操作。
(1)定义位置
定义模型的位置,默认是在app目录下面:
(2)命名规则
本身laravel对模型的命名没有严格的要求,一般采用 表名(首字母大写).php
比如:Member.php User.php Goods.php
(3)创建模型
可以使用artisan命令;例如创建一个member模型【模型也可分目录管理】
[project] > php artisan make:model Member
基础结构代码:
(4)定义模型注意事项(重点);
第一:(必做)定义一个$table属性,值是不要前缀的表名(真实的表名),如果不指定则使用类名的复数形式作为表名。如果模型为Member模型在不指定table属性的情况下,其默认会去找members表。修饰词:protected
第二:(可选)定义$primaryKey属性,值是主键名称,如果需要使AR模式的find方法,则可能需要指定主键(Model::find(n)),在主键字段不是id的时候则需要指定主键。修饰词:protected
第三: (可选)定义$timestamps属性,值是false,如果不设置为false,则默认会操作表中的created_at和updated_at字段,我们表中一般没有这两个字段,所以设置为false,表示不要操作这两个字段。修饰词:public
第四:(可选)定义$fillable属性,表示使用模型插入数据时,允许插入到数据库的字段信息。格式是一维数组形式,修饰词:protected(当使用模型的create、save方法的时候最好就得写上这个属性) ,反向指定的属性叫做:$guarded
注意:使用模型中create插入数据时,要设置 f i l l a b l e 允 许 入 库 的 字 段 , 使 用 fillable允许入库的字段,使用 fillable允许入库的字段,使用guarded是设置排除入库的字段。(暂时性先不设置,等到用的时候再设置)。
引入Member模型类;
模型的使用:模型在控制器中的使用方式有2种
①直接像使用DB门面一样的操作方式:以调用静态方法为主的形式,该形式下模型不需要实例化,例如:Member::get() 等价于 DB::table(‘member’) -> get();
②实例化模型然后再去使用模型类(普通)
例如: m o d e l = n e w M e m b e r ( ) ; model = new Member(); model=newMember();model -> get();
两种形式的选择标准:
如果使用的方法都是laravel框架自带的,则任意选择;
如果使用的方法有用户自己在模型中定义的,使用第②种形式。
增:/model_add
删:/model_del
改:/model_mod
查:/model_select
在laravel里面完成数据的添加可以使用两种方式:
方式一(AR模式):使用AR模式必须要实例化模型
注意:在laravel里面添加数据的时候,需要先实例化模型,然后为模型设置属性,最后调用save方法即可。
$member = new Member(); //映射关系1:将表映射到模型
$member-> name = value; //映射关系2:将字段映射到属性,属性名和字段名一致
$member -> age = value;
…
$member -> save(); //映射关系3:将记录映射到实例
上面的这种方法可以完成数据的插入,但是不建议使用。我们可以使用laravel提供的更高级的操作。
方式二:(隐性的效果)
建立简易表单,表单中有姓名、年龄、邮箱的字段,要求能够提交
首先,在控制器文件引入Request这个类
use Illuminate\Http\Request;【框架自身在创建控制器的时候已经引入】
Request类的使用:
①对象传递,需要在方法的括号里以形参的形式接收Request类,只有接收了才能在方法中使用
②request语法(与input门面有点类似,方法名一致,但是input调用的是静态方法,而当前的不是)
$request->all() //获取全部传递数据
$request->input(‘name’); //获取指定的
$request->only([‘name1’,’name2’…])
$request->except([‘name1’,’name2’…])
$request->has(‘name’)
$request->get(‘name’)
添加操作代码语法如下;
Member::create($request->all())//返回值是一个对象
一定要设置模型的fillable属性,否则会报错。
报错:
注意:如果使用create方法,则需要在模型中定义fillable属性,允许写入字段的定义,如果没有时间相关字段也需要禁用时间自动更新功能:
执行的结果:
注意:
a. DB类中的insert方法,在模型中也是可以使用的(其他方法也是如此);
b. insert方法必须要求先排除不写入数据表的字段,模型中的fillable属性对insert不生效,如果不事先排除如“_token”等字段,则会报错;
获取指定主键的一条数据
$info = Member::find(4); // 静态方法调用,获取主键为4的数据【等价于条件where id = 4】
其结果集默认是一个对象。
如果需要在laravel中对象的结果集转化成数组,则需要在最终添加方法的调用:
-> get() -> toArray();
所以刚才的案例,如需要数组结果,则可以写成:
$data = Member::find(4) -> toArray();
Member::all() //查询全部的数据,类似于get()
Member::all([字段1,字段2]) //与get方法的区别,all不支持连接其他的辅助查询方法
相当于get方法
Member::get()
Member::get([字段1,字段2])
按条件查询指定多个字段
Member ::where(‘id’,’>’,2)->get([’ 列 1’,’ 列 2’]); //数组选列
Member::where(‘id’,’>’,2)->select(‘列1’,‘列2’)->get(); //字符串选列
Member::where(‘id’,’>’,2)->select( [’ 列 1’,’ 列 2’] )->get(); //数组选列
案例:测试在all方法之前,写一些辅助方法实现连贯操作(报错)
注意:all方法之前,必须是模型/DB类,不能是其他的辅助方法(例如where等),否则会报错,此时可以使用get方法替代all。
注意:在laravel里面如果需要更新数据(ORM模型方式),需要先调用模型的find方法获取对应的记录,返回一个模型对象,然后为该模型对象设置要更新的数据(对象的属性),最后调用save方法即可。
例如:
u s e r = U s e r : : f i n d ( user = User::find( user=User::find(id); //查询出需要修改的记录实例
$user->title = $_POST[‘title’];
$user->content= $_POST[‘content’];
return $user->save() ? ‘OK’ : ‘fail’;
案例:实现ORM形式模型的修改操作。修改为5 的用户的邮箱地址为[email protected]
该操作返回的是布尔值:
问题:能不能用模型去update呢?
答:可以使用update方法进行更新,也可以使用AR模式的方式进行更新。
上述两种方法都可以实现更新,哪种简单用哪种。
注意:在laravel里面如果要删除数据,如果需要使用AR模式删除数据必须先根据主键id查询对应的记录,返回一个模型对象,然后调用模型对象的delete方法即可。
例如代码:
u s e r = U s e r : : f i n d ( user = User::find( user=User::find(id); //先查询需要删除的记录
return $user->delete() ? ‘ok’ : ‘fail’; //再删除
案例:使用AR模式删除id为6的记录
返回值也是布尔值:
问题:DB里面的删除方式能否在模型中使用?【可以】
总之一句话:在DB::table中能使用的方法,在模型中同样可以使用。
DB::table(‘xxx’) 等价于 Xxx模型
如果不需要自己定义数据处理方法,则可以使用DB或者模型门面。如果需要自己定义一些DB门面中没有的方法,则这些方法就需要定义在模型中,此时就得去使用模型了。
比较常见的使用模型的场景:
a. 可能在数据入表之前需要对数据进行比较的处理步骤,这个时候建议在模型中自定义方法对数据进行处理;
b. 如果需要使用关联模型的话,则必须要定义与使用模型;
自动验证:前端会有一些对表单的验证操作(通过JavaScript),但是JavaScript有些情况下是不好用的(例如禁用JavaScript)。因此后端也需要有一套类似的机制,能够在后端实现对用户提交的数据进行验证,这个就是后端的自动验证。
①使用之前的test8表单页面,将其提交到test9路由
创建test9的路由
②编写控制器方法
修改test8页面的提交地址为test9
先验证,再入库。
建议去查看手册
使用控制器中的validate方法来完成, t h i s − > v a l i d a t e ( this->validate( this−>validate(request,[验证规则]);
如果验证失败,laravel会自动将用户重定向回上一个位置,并将验证错误信息一次性存放到session中。
请求验证:
required: 不能为空
max:255最长255个字符,
min:1最少1个字符
email:验证邮箱是否合法
confirmed:验证两个字段是否相同,如果验证的字段是password,则必须输入一个与之匹配的password_confirmation字段
integer:验证字段必须是整型
ip:验证字段必须是IP地址
numeric 验证字段必须是数值
max:value 验证字段必须小于等于最大值,和字符串,数值,文件字段的size规则一起使用。
min:value 验证字段的最小值,对字符串、数值、文件字段而言,和size规则使用方式一致。
size:value 验证字段必须有和给定值value想匹配的尺寸,对字符串而言,value是相应的字符数目,对数值而言,value是给定整型值;对文件而言,value是相应的文件字节数。
string 验证字段必须是字符串
unique:表名,字段,需要排除的ID
注意:多个验证规则可以通过 “|” 字符进行隔开
语法:$this -> validate(数据对象,[数组形式的验证规则]); validate是基类控制器方法
方法1:自定义翻译
可以在定义自动验证的时候,给validate方法传递第三个参数,第三个参数即错误提示:
该方式比较繁琐,每个规则都要自己定义错误信息。
方法2:借助于第三方的语言包。
由于中文和英文都是属于语言范畴,如果要切换提示文字,则需要有中文语言包的支持。目前框架只有en语言包,则需要其他语言包需要去下载。
网址:https://packagist.org composer主要的代码托管网站
在官网搜索laravel-lang
注意:后期下载软件依赖的时候一般会综合一下下载量和收藏量进行下载选择。
①需要寻找下载命令
安装命令:# composer require caouecs/laravel-lang:~3.0
②使用composer进行安装
在项目根目录下运行上述的命令
③使用方法
翻译:
语言包文件在vendor/caoue/laravel-lang中;将你需要的语言目录复制到resources/lang目录下即可。
将需要的语言包复制到语言包目录:
根据提示:
翻译:在文件(config/app.php)中修改locale的值,改成你需要使用的语言简称。
简称其实就是语言包的文件夹名称。
测试效果:
注意:并不是所有的字段都有对应的翻译(或者有的翻译可能不是很准确),如果想自己定义翻译,则需要去修改语言包文件代码。
修改后续的值,或者新增需要的元素:
提醒:自动验证除了使用语言包翻译之外,还支持通过验证方法validate方法指定翻译内容。
t h i s − > v a l i d a t e ( this -> validate( this−>validate(request,规则数组,错误信息数组);
提示:刚才的案例是表单提交的,遇到验证不通过会302到上一个页面并且会带错误到session里,可以通过在页面中访问$errors来获取错误。那么如果使用AJAX提交会怎么呢?
答:如果提交方式是AJAX,那么遇到验证不通过的情况下,则不会302到任何页面,会直接被返回json格式的错误信息。
在laravel里面实现文件的上传是很简单的,压根不用引入第三方的类库,作者把上传作为一个简单的http请求看待的。使用时可以参考手册。
ALTER TABLE member
ADD COLUMN avatar
varchar(100) NOT NULL AFTER email
;
(2)创建添加数据的表单和路由
表单还是可以使用test8页面
提交路由可以使用test9路由
创建视图页面并且添加csrf_token(如果没有关闭csrf验证的话一定要加)
回顾:要想表单能够上传(此处不考虑异步方式),则表单应该具备哪些要求?
答:
a. 具有form标签,method必须为post,必须具备enctype属性;
b. 至少有一个input类型为file类型;
c. 得具备一个提交按钮;
(3)在控制器中,添加上传业务处理逻辑
【此处操作建议查看手册】
关于上传错误状态码error的取值:0 – 7,共7个,没有5.
问题:请你说出文件上传的本质(核心思想)?就是临时文件的移动,move_upload_file
更多的方法请访问:
http://api.symfony.com/3.0/Symfony/Component/HttpFoundation/File/UploadedFile.html
思路:
a. 先去判断文件是否正常和存在
b. 获取相关的信息(可选)
c. 保存文件(其实就是移动文件到新的目录)
获取文件的方式:既可以通过file方法来获取也可以通过动态属性来获取,二选一。
(4)创建上传文件的保存路径(一定要在public下,确保浏览器能够访问)
关于项目中使用路径(“./”与“/”)的说明:
如果一个路径是给php代码使用的则建议使用“./”,如果路径是给前端浏览器使用的则使用“/”。【在后端代码中,/表示的不是站点或项目根目录,而是表示磁盘根目录】
为了保存的文件不被覆盖,建议在保存文件的同时对文件名进行尽量唯一的重命名:
(5)注意:如果使用的是create方法添加数据到数据表中,则这里还要修改一下模型里面的一个fillable属性,代表允许插入到数据库的字段
在laravel里面要完成分页是很简单的,它的思想之前的框架有些不一样,之前框架使用的是分页类完成分页,laravel是直接调用模型的分页方法,返回对应的数据和分页的字符串。
分页类的在框架中的位置(了解):
案例:使用分页功能实现当前member数据表的分页效果。由于数据量较少,可以考虑每页显示1个记录,重点是分页的效果
回忆/问题:分页效果的实现大致需要哪几个步骤才能实现?
a. 查询符合分页条件的总的记录数
b. 计算总的页数(总记录数/每页记录数,并且向上取整)
c. 拼凑分页的链接
d. (核心)使用limit语法来限制分页的记录数
e. 展示分页的页码和分页数据
f. 如果可以,建议去考虑下分页的样式显示问题
在laravel中步骤分为:
a. 分页
b. 展示
c. 处理样式
①创建路由,并且展示简易列表页面(table标签布局)
路由:
/test10
创建test10方法获取数据,渲染视图, 编写控制器中的方法代码,实现没有分页的效果(先不考虑分页效果)
②展示数据
无分页展示效果:
③【案例】使用分页展示上述的页面
要求:每页显示一条记录。
在laravel中分页有2个提供者:DB查询构建器,另外可以使用模型来实现。
用法基本一致。
以模型为例:
分页的基本语法:
Model::paginate(每页显示的记录数) 同样,paginate和get一样,支持使用where以及orderBy等辅助查询的方法。
不展示分页链接的效果:
在页面中展示分页链接:
语法:{{KaTeX parse error: Expected 'EOF', got '}' at position 19: …据的对象 -> links()}̲}生成的链接【使用render…info = Member::orderby(‘age’,‘desc’)->simplePaginate(2);
附:分页数据对象的其他实用方法如下
分页数据对象->count() //当前页数据条数
分页数据对象->currentPage() //当前页码
分页数据对象->firstItem() //当前页第一条数据的序号
分页数据对象->hasMorePages() //是否有后续页码
分页数据对象->lastItem() //当前页最后一条数据的序号
分页数据对象->lastPage() //最后页序号
分页数据对象->nextPageUrl() //下一页的链接地址
分页数据对象->perPage() //每页显示数据条数
分页数据对象->previousPageUrl() //上一页的链接地址
分页数据对象->total() //记录总条数
分页数据对象->url(5) //制作指定页码的链接地址
将页码稍作处理,写的好看点:
样式代码可以百度上寻找:https://www.cnblogs.com/lamp01/p/6869762.html
将css代码引入到当前的分页页面,最终显示效果:
最终效果如下:
验证码:captcha,全自动区分人与计算机的图灵测试。
回顾:生成验证码需要经过:画画布、生成干扰线、生成噪点、生成验证码、生成验证码存入session、输出图片。
常见的验证码类型:字符验证码、短信验证码、电话验证码、12306类型验证码、拖拽验证码等。
去packagist网站搜索验证码的代码依赖:关键词:captcha
地址:https://packagist.org/packages/mews/captcha
环境要求:php>=5.4,需要开启GD库,同时需要开启fileinfo和mbstring扩展
Composer方法安装代码依赖包:composer require mews/captcha
修改配置文件:config/app.php
配置:配置provider信息,添加一行信息:
配置别名aliases键,添加一个别名记录
如果(可选)需要定义自己的配置,则需要生成配置文件:
#php artisan vendor:publish
发布之后会在config目录下找到对应的配置文件:
案例:在之前test8的基础之上,实现验证码的显示
①需要在页面上显示出来
注意:要去除末尾的分号“;”,否则报语法错误。
展示效果
如果需要自定义配置(如长度、宽高等),可以修改配置文件config/captcha.php文件(当前默认是9个长度),可以去进行修改。
②验证码验证操作
注意:验证码有效性验证规则,手册里是没有的,如果使用mews验证码包的话,其验证码验证规则就是captcha
显示效果:
解决翻译的问题:
在数组中添加captcha元素即可解决“validation.captcha”的显示问题,此处的validation表示的是validation.php里面的数组,而capctha表示的是数组里的captcha元素,因此补上captcha元素即可。
也可以在控制器自动验证方法中直接定义第三个参数作为错误信息:
显示效果:
补充:如果需要实现点击验证码切换功能,则还需要写一段JavaScript代码(jQuery)
先引入jQuery代码,然后再去编写如下代码:
迁移:创建数据表的操作+删除数据表的操作
填充:往数据表里填充写入测试的数据(数据的插入操作)
在迁移过程中,操作可以分为两个部分:创建与编写迁移文件(创建&编写sql)、执行迁移文件(执行sql)。
迁移文件默认的位置:
已经存在的2个文件,如果不打算使用系统自带的认证模块的话需要删除掉。
①创建迁移文件
案例:需要创建试卷的数据表,假设数据表的名字叫做paper。迁移文件名:create_paper_table
创建的时候可以通过自动代码生成工具artisan命令来执行迁移文件的生成。
#php artisan make:migration 迁移文件名 Create a new migration file
迁移文件不需要分目录进行管理,可以直接书写名称即可。
#php artisan make:migration create_paper_table
初始代码:
Up方法表示创建数据表的方法
Down方法表示删除数据表的方法
②编写迁移文件代码,让其能够实现数据表的创建(up方法)与删除(down方法)
在写之前,可以参考项目初始化提供的user迁移文件:
真正在自己写迁移文件的时候需要变换的代码就只有矩形框选中的那一块。
Schema门面(类)是用于操作数据表的门面,调用其具体的方法之后就可以实现创建数据表与删除数据表,语法如上。照搬上述语法实现试卷表paper的创建:
试卷表的字段分析:
Id 表的主键,自增
Paper_name 试卷名称,唯一,varchar(100),不为空
Total_score 试卷总分,整型数字,tinyint,默认为100
Start_time 试卷开始考试时间,时间戳类型(整型int)
Duration 考试时间长度,单位分钟,整型tinyint
Status 试卷是否启用的状态,1表示启用,2表示禁用,默认为1,tinyint类型
在创建数据表的列的时候遵循语法:
$table 表示整个表的实例
语法:$table -> 列类型方法(字段名,[长度/值范围]) -> 列修饰方法([修饰的值]);
列类型方法的作用:指定列的名称并且设置列的类型长度或者其值范围(仅针对枚举类型)
修饰方法:主要是补充列的一些特征,例如有些列不能为空,或者有默认值等等
常见的修饰方法有:
具体可以参考“43、数据库 —— 迁移”
执行分为up执行和down执行。
Up方法的执行:
如果在当前的项目中第一次执行迁移文件的话,则需要先去执行:
#php artisan migrate:install
在执行过上述的命令之后,在数据表中会多出一个数据表,migrations
作用:用于创建记录迁移文件的记录数据表(可以看作类似于SVN的版本控制机制)。
需要执行up方法,则需要执行命令:(注意:需要删除系统自带的迁移文件,只保留自己的)
删除的原因,默认迁移操作会执行迁移文件夹中所有没有被执行的迁移文件。
#php artisan migrate 【执行迁移文件的:创建数据表(up方法)】
产生的记录:
产生的数据表:
问题:如果再次执行php artisan migrate会怎么样?
不会怎么样,不会有任何操作。(在执行迁移的时候系统会将迁移文件夹里面文件与数据表的迁移记录表进行匹配,匹配上则不执行,匹配不上则执行)
Down方法执行:(回滚操作,删除数据表)
#php artisan migrate:rollback 【回滚最后一次(批次号,针对的是批次号,不是单个表)的迁移操作,回滚操作不删除迁移文件】
回滚操作只删除迁移表中的记录和对应的数据表,其他操作不执行。
注意:删除(回滚)之后会删除上一个批次的迁移记录,并且同批次建立的数据表也会删除,但是迁移文件依旧存在,方便后期继续迁移(创建数据表)。
批次号:同一次被执行的多个迁移文件其批次号相同。
针对迁移文件名的提示:如果迁移文件已经创建好并且执行了,就不要去修改迁移文件的名称,容易出错的。
迁移操作与sql语句操作类似,区别在于迁移文件将原先的sql语句从标准查询语言形式转化成了面向对象的形式。
填充操作就是往数据表中写测试数据的操作(增加操作),在开发阶段是很实用的功能。
②创建填充器
#php artisan make:seeder 填充器名称 【约定俗成的写法:大写表名+TableSeeder】
例如:以paper表为例,则名称应该为PaperTableSeeder
#php artisan make:seeder PaperTableSeeder
创建好的种子文件:
③【重点】编写填充器的代码,实现往数据表中写入数据
注意:在填充器文件中可以使用DB门面去新增数据,但是需要注意,DB门面在使用的时候不需要用户自己引入,一旦引入则报错,可以直接使用。建议使用DB门面方法写入新的数据
使用DB类进行数据写入:
命令:
#php artisan db:seed --class=需要执行的种子文件名(不带.php)
种子文件不像迁移文件,迁移操作有单独的对应关系表去记录,由于种子文件的执行没有任何的记录,所以在执行种子文件的时候需要指定需要执行的种子文件。
#php artisan db:seed --class=PaperTableSeeder
如果没任何提示则说明其执行成功。
执行之后数据表中的对应的数据就存在:
填充器的执行操作没有回滚一说,没有删除。如果需要回滚,则可以手动清空对应的数据表。