Awesome tips for Laravel.
善用集合
Collections 是 Laravel 提供的一个巨大特性,它允许我们轻松地操作数组,可以为我们节省大量时间。
比如想要对下面这组数据进行求和:
1 | $orders = [ |
使用传统的 foreach
方式:
1 | $total_price = 0; |
试试使用集合:
1 | $total_price = collect($orders)->pluck("price")->sum(); |
虽然两种方式都可以实现,但显然使用集合更容易一些,更多集合的最佳实践可以查看我的另一篇笔记——Laravel Collection 实际使用。
善用集合,可以帮我们减少很多重复的代码。
查询作用域
通常,在Laravel Eloquent ORM 查询时,需要匹配某些条件时,一般会这样写:
1 | $admin = Admin::where("is_enable", true) |
这样写并没有什么问题,但为了使我们的代码更具可读性,而不是重复性,可以使用 query scope
,在对应模型中创建查询作用域:
1 | public function scopeEnable($query) |
现在,可以通过如下方式进行查询:
1 | $admin = User::enable() |
如果某个查询条件频繁使用到了,可以在模型中添加全局查询作用域,这样可以默认加上该查询条件:
1 | protected static function booted() |
取消全局查询作用域?
1 | // 指定类 |
Eloqunt Query
实际开发中,因为需求的复杂性,我们往往需要写出各种各样的SQL 来满足查询。
selectRaw()
、whereRaw()
、havingRaw()
允许我们在查询构造器中,加入原始SQL 查询,例如,统计分组数量:
1 | $count = User::groupBy("is_enable") |
Log and Debug
Laravel 为我们提供了便捷的调试代码方式——dd()
,但某些场景下并不适合使用 dd()
,比如测试回调是否正常。
这时可以使用 Log
助手函数进行调试,生成的日志在storage/logs
目录下。
1 | \Log::debug('Test Message', $result]); |
dd()
作为现代开发者的调试利器,日常开发基本上离不开它,也许你一直都是这么用的:
1 | $users = User::where('name', 'Taylor')->get(); |
其实有一种更简单的方式:
1 | $users = User::where('name', 'Taylor')->get()->dd(); |
它可以作为一个链式方法,直接放在 Eloquent Query 或者集合的后面进行调用。
Tinker
Laravel 的另一大特性就是提供了交互式的命令行——Tinker,在这里你可以执行各种代码,而无需考虑环境,在某些时候,进行调试时是极为方便的。
1 | php artisan tinker |
我通常会使用 Tinker
做以下事情:
- 检测某段代码是否符合预期
- Eloquent Query 测试
- SDK 测试
分页求和
在有分页的情况下,如何统计某个字段所有记录的总和?
1 | // 创建一个查询构造器 |
Data Get Function
如果有一个复杂的数组对象数据结构,可以使用 data_get
助手函数使用.
表示法和 *
通配符从嵌套数组或对象中检索值:
1 | $data = [ |
optional
optional()
方法允许你获取对象的属性时调用该方法。如果该对象为 null,那么属性或者方法也会返回 null 而不是引起一个错误:
1 | // User 2 exists, without account |
封装SDK
通常在安装了一个 SDK 之后,我们可以做一些简单的封装,这样使用起来会更方便。
1 | php artisan make:provider JpushServiceProvider |
这里以极光推送 这个第三方推送服务商为例:
1 |
|
加入到 config/app.php
:
1 | 'providers' => [ |
创建配置文件:
1 |
|
在 env 文件中填写 Jpush 的 key 和 secret:
1 | # jpush |
这样我们可以直接依赖注入 JPush\Client
或者 app('jpush')
来使用 Jpush 的 SDK。
密码
在Laravel 中,流行两种加密方式,一种是 OpenSSL 所提供的 AES-256 和 AES-128 加密,另外一种是 Bcrypt 和 Argon2 的哈希加密方式。
加密解密
使用 Crypt
门面提供的 encryptString
来加密一个值,或者使用 encrypt
助手函数:
1 | encrypt(122410); |
使用 Crypt
门面提供的 decryptString
来进行解密,或者使用decrypt
助手函数:
1 | decrypt("eyJpdiI6IlJhd3h6amtXTFh5cit2bU9ySldNU2c9PSIsInZhbHVlIjoiZlRTdWx6Wk5oTVhjSnZyR0pMdkJ0dz09IiwibWFjIjoiYWVmMTE2NWUyZjkwMWZmNWI0N2I5Y2EwNzgxMjU5ZGI4NDE0OTU2MzJhY2I1ZWFkNzJmOWMyNjMwNzIxMTBjMiJ9") |
哈希
Bcrypt 是哈希密码的理想选择,因为它的「加密系数」可以任意调整,这意味着生成哈希所需的时间可以随着硬件功率的增加而增加。
使用 Hash
门面提供的 make
方法来进行加密,或者使用bcrypt
助手函数。
1 | Hash::make(122410); |
哈希加密无法解密,只能通过验证的方式来判断加密前后密码是否一致。
使用Hash
门面提供的check
方法进行哈希验证,或者使用password_verify
助手函数。
1 | Hash::check(122410, '$2y$10$DsKye7lBalaUkvBOEk6cvOrLGvgPD2EKkV/QtWuChbJ8It5JiVoM2'); |
统计
开发中,我们常会遇到这样的需求:
- 统计今天的注册量
- 统计昨天的注册量
- 统计每个月第一天的注册量
- 统计这个月的注册量
多数时候,我们会这样写:
1 | UserModel::whereBetween("created_at", [$startTime, $endTime])->count(); |
其实使用Carbon 配合Laravel 查询构造器可以很好地解决这类问题:
1 | // 统计今天的注册量 |