Laravel5: 学习笔记

Migration 应该是整个 laravel 框架的核心功能了。

nullable

除了 nullable 之外,官网介绍里还提供了一些其他函数,真的很赞。

很神奇的是,强大如 PhpStorm,居然识别不出这个函数的来源,不过运行起来是 ok 的,后来查了下,要稍微修改一下一个文件,就可以识别了:

然后就可以操作数据库了,用的是 Eloquent Model,这是个很神奇的东西。

orderby

当然,还可以在 get() 之前再排序一下,然后取多少条,非常 elegant,Query Builder 里有更多的介绍。

然后视频介绍了 create() 方法,同时提到了这时候可能存在的安全问题,因为 POST 是可以模拟提交的,如果有人 POST 的时候自定义了 ID 或者自定义了 IS_ADMIN 这种字段,就会带来安全问题,所以这些字段如果被包含在 create() 里面,应该要返回一个失败页面。

相关资料:

  1. 从 Github 被 hack,谈 Rails 的安全性(mass-assignment)
  2. 网路安全
  3. 官方 Document 关于 Mass Assignment 的描述(翻译版)
  4. Laravel – Mass Assignment
  5. understanding-mass-assignment

看了一圈,大概理解 mass assignment 安全设定的重要性了。因为如果你要修改单个字段的值,你必定会手动通过一个查询语句把这条记录查出来,然后手动写一个 save() 命令把字段值更新进去。也就是说,你明确知道自己更新的是什么字段,也知道需要做什么安全方面的考虑。而如果你用 create() 方法,就会一次性把所有字段传到数据库里,这时候就容易被黑客 manipulate,因为你没有指定哪些点可以被更新,哪些点不能被更新,而是完全 trust 用户 input 的信息了。所以基于这点考虑,需要设定 $fillable 或者 $guard 来进行防范,比方 $id、$is_admin 这样的字段,不能让用户通过 post 表单的方式写进去,否则会带来很大的安全隐患,只能让 php 程序的内置函数生成这些值,而不是通过 post 方法传入。

以前因为都是手动写,所以没有想到过这个问题。

mass assignment

设好之后我执行了很多次,都还是提示 mass assignment,后来才想到要退出 tinker 重新进一次,视频里也是这么做的。

update

另外发现一个神奇的现象,用 find 方法无法后接 update,where 就可以,不过 find 确实不常用就是了,官方 document 也是用的 where。

试验了一下,update 方法不受 mass assignment 的管理,也可以理解,因为 update 那个字段是自己写的,自己要对自己负责。

最后就是把 MVC 连起来用,测试过程中发现要先做好 nginx 伪静态的设置:

找到 location / { } 这段,加入第三行,注意不能写两个 location / { },会出错,重启 nginx 就可以让 route 生效。

MVC 的知识点有点杂,不一一列举,这里记录一个很有用的 softdelete 的方法。巨灵在数据库建立的时候,一定要加一个字段叫 Isvalid,0 就已经置无效,1 就是有效。这是非常有必要的做法,数据记录如果真的删除了,恢复起来很麻烦,而如果只是变成 Isvalid=0 的记录,可以很方便地进行数据恢复。以前做批量清洗,很多就是批量设为 0,然后重新导入。

Laravel 里把这个较为软删除(softdelete),首先需要在表内加一个新的 column 叫 deleted_at:

这就完成了准备,然后在调用 delete() method 的时候,它就不会真的删除整条记录,而是把 deleted_at 加上一个时间,正常情况下不查询 deleted_at not null 的记录,这比 isvalid 更好,有个 delete time 可以查询,当然,如果不对 deleted_at 做编辑,updated_at 其实就是 deleted_at。

如果想让查询结果包含被软删除的记录,可以这么做:

很简单明了,恢复为有效记录就是:

真的是简单到不用学 SQL,彻底删除是 forcedelete(),我应该是不会用到它的。

官方 Document

再然后是关于 hyperlink 的写法,有 3 种。

  1. 第一种比较直观,直接写

2. 第二种是利用 controller

其实这么做反而麻烦了,当然如果地址比较复杂,也有一定好处,因为可以直接用 compact 把多个变量交给 controller 去处理。

3. 第三种是用 url 函数

比较有意思的是,url 函数会返回绝对路径,而前面两种是相对路径。

Route 里面是这么设置:

获取地址里的,然后把 id 传入向 RequestsContorller 里的 show method。

当然,这么做不好的地方就是暴露了数据库 id,比方 2015-EU-OE,这样的地址,会更安全一些,缺点是加个字段,而且要人维护,还要保证 unique。

接下来是关于表单,视频里建议安装一个插件叫 illuminate\html:

然后修改配置:

这样就可以用了,Form 可以这样:

我想说,这样的事情我干过,我是这写的:

殊途同归的感觉,其实自己造轮子确实也可以哈哈,说明我的思路是对滴,只是技术水平还不到家。

创建出来的 HTML 是这样的:

据说 token 是为了 security reason,据说是为了防止 CSRF 跨站攻击,具体我也不懂。比较神奇的是这个包在 4.2 是自带的,现在米有了。

接下来介绍了各种 input 的用法:

上面这一坨都可以弄成 live template,挺好玩的。

然后用户输入完数据之后跳转到哪里呢,通常我们说比较安全的做法是用 post,form::open() 默认的 method 也是 POST,所以我们在 route 里面建一个针对 post 的跳转:

然后,修改一下 FORM post 的地址,同样也是有 3 种方法,最高大上的似乎是 route 方法,视频里没介绍,action 相对比较好,url 方法最简单但后期如果地址改变也最麻烦:

然后回到 RequestsController,建立一个新的 method 叫 store,然后有个比较 tricky 的地方,视频说把开头的一个 class 改成这样子:

然后所有 input 的东西,都会传到 Request Model 里面,用下面这段,就可以看到我们刚才输入的东西:

挺神奇的,接着就是写入数据库,可以用 create 方法,但要注意 mass assignment 的问题,我觉得比较安全的还是手动建一个对象:

OK,这样就写入数据库了,然后 redirect 回 requests。为了把最新的记录放在最前面,稍微改一下排序:

OK,下一节作者又卖了个关子,开始讲了一些周边的东西,其中包括 Model 的两种用法,不过掌握的不是很好,暂且不提,这篇笔记就写到这里。

Leave a Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.