# web实践进阶 **Repository Path**: pardon110/advancement_of_web_practice ## Basic Information - **Project Name**: web实践进阶 - **Description**: laravel5.7 实战进阶教程,构建了一个论坛系统。涉及到多角色用户权限系统、管理员后台、注册验证码、图片上传、图片裁剪,XSS 防御、自定义命令行、自定义中间件、任务调度、队列系统的使用、应用缓存、Redis、模型事件监控、表单验证、消息通知、邮件通知、模型修改器等 - **Primary Language**: PHP - **License**: Not specified - **Default Branch**: develop - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 1 - **Created**: 2019-04-20 - **Last Updated**: 2020-12-19 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Larabbs 构建论坛系统 ## 小札 - 配置及自定义辅助函数 - `composer.json`自动加载项配置 `files`键: 文件路径数组 - `Route::currentRouteName` 当前命名路由名称 - `laravel-mix` 之 `version`方法解决静态文件缓存问题 - `__()`辅助函数实现本地化,语言文件存储在`resources/lang` - auth认证 - 登录,注册,重置,验证四控制器由`/home` 改为`/` - `RedirectIfAuthenticated` 中间件重定向同上改变 - 同一字段通常只显示第一个验证错误 `{{ $errors->first('password') }}` - 邮箱认证laravel框架提供接口和实现的Trait,支持邮件验证事件 - `php artisan event:generate` 依据注册的事件,生成事件监听器 - 队列 - 适用延迟耗时任务,比如翻译 - 生成任务类 `php artisan make:job QueueJob` - 分发任务 `dispatch(new QueueJob($aModel)` - 队列监控 `php artisan queue:listen` - 失败任务 `php artisan queue:failed-table` - **为了避免模型监控器死循环调用,使用 DB 类直接对数据库进行操作** - **队列任务构造器中接收了 Eloquent 模型,将会只序列化模型的 ID,需要在 saved 监听方法中分发任务,而非saving** - 锦上添花可延迟执行的逻辑,尽量使用队列来操作 ## 扩展包 - `mews/captcha`验证码扩展包 - `intervention/image` 图片处理,裁剪图片的宽度 - `summerblue/generator` 代码生成器工具 - 生成迁移文件,种子,工厂及数据生成器,模型类,资源控制器,表单请求类,策略类,更新视图,路由,创建增改共享视图文件 - 用法示例 - `php artisan make:scaffold -s title:string:index,body:text Topic` - `barryvdh/laravel-debugbar:~3.2` 性能优化分析器 - `hieu-le/active` 基于当前url获取对应的激活样式类名 - `simditor` 一款小巧的ide编辑器 - `mews/purifier` 防止XSS注入漏洞,使用白名单机制,名单上有的标签才会允许解析 - `overtrue/pinyin` 翻译成SEO的url,如中文标题译成拼音 - 生成 Slug 只是一个 优化 功能,并非是发帖的 必要 功能,可选路由 - 此时应用队列,队列允许异步执行消耗时间的任务,比如请求一个 API 并等待返回的结果,降低请求响应时间 - `guzzlehttp/guzzle` 一个php的http库 - `predis/predis` 使用redis扩展包 - `laravel/horizon`使用队列仪表盘 - `spatie/laravel-permission` 授权 - 支持权限缓存文件 - 先建 角色,权限, 后授权 权限->角色 - 角色,权限,用户 五张表 - 单表 权限表,角色表 - (中间表)权限角色关系表,模型角色关系表(多态表),模型权限关系表(多态表) - 用户认证模型引入trait - `use Spatie\Permission\Traits\HasRoles Trait` - 权限具体内容需要实现,通常就是gate内的闭,管理员使用策略类的全局过滤器 - 比如策略类的can方法 - `viacreative/sudo-su` - 多用户切块登录,用于权限开发测试必备包 - 发布资源(单个发布使用tag标志) - `php artisan vendor:publish --provider="VIACreative\SudoSu\ServiceProvider"` - 配置顶级域名,配置认证的用户模型 - `summerblue/administrator` - 后台管理包,发布资源 - `php artisan vendor:publish --provider="Frozennode\Administrator\AdministratorServiceProvider"` - 配置文件内用env方法,不要用config函数 - 基于模型配置的后台管理 - 分清鉴权(Authenticatable)与 授权(Authorizable)接口 ## 技巧 - `expectsJson` - `session()->flash()`存储一次性消息,在session端 - 验证规则 - `unique:table,column,except,idColumn`, 在 table 数据表里检查 column ,除了 idColumn 为 except 的数据。 - `mimes:jpeg,bmp,png,gif|dimensions:min_width=200,min_height=208` 限制图片分辨率 - 使用函数作限制性条件a - 表单伪造 - 支持函数生成字段 `csrf_field(),method_field('PUT')` - 支持`input:hidden[name=_method value=PUT]`, `input:hidden[name=_token value={{ csrf_token() }}]` - 分页追加参数`appends`, 排除请求中的若干查询字段返回数组`request:except(str)` - $request->method() 获取Http谓词 - 通过模型事件观察者实现,数据联动写入 `csrf_field()` 实现表单数据写入 - 消息与错误 - 消息存储于当前`session`,错误亦不过是在子项,由中间件织入`$errors` - 规约:控制器方法内,类型注入实例在前,隐式路由参数实例在后 - `withInput(),with()` 响应体上自带当前session信息 - 迁移文件 - `php artisa make:model Models/Category -m` 创建表迁移 - `php artisan make:migration seed_categories_data` 数据填充表迁移 - 利用数据迁移功能具有执行顺序的特点,可以生成自动化生成一些预定义数据 - `Eloquent` 方法有事件监听,`db` 的操作没有相关的方法 - 查询性能优化 - `with` 将各自单独查询,合为一条渴求式查询 - `Scope`开头模型动态作用域方法,默认第一个参数是由系统注入的查询构建器,第二个参数是传入的值 - 原理: 根据不同的参数,使用不同的查询约束条件,使约束条件可复用,通常使用在排序方式上 - 模型上的with查询一般与关联方法相关,通用的约束集合,本地作用域 - `array_unshift($parameters, $this);` 将当前$this作为参数插入到数组$parameters首位,故构造标识前置注入 - 关联关系中的外键通常放在从表上,即由A->B,B为从表 - 所有通过属性关联查询的,关联的属性模型会先提取出来统一作渴求式查询一次,后续查询复用 - 处理不需要事件监听器的模型操作时,通常使用DB类,查询构建器,比如在级联删除最后一层删除时 - Blade 模板 - `$loop` 循环变量 - `$loop->first,$loop->last` 可在循环第一行后最后一项据此做点样式调整 - `@includeWhen($boolean,view,$data)` 条件加载子视图 - `Auth` 返回当前认证通过的用户数据 - 消息通知 - 通知频道 通知传播途径 - 如:数据库、邮件、短信(通过 Nexmo)以及 Slack - 使用 - 准备数据库 `php artisan notifications:table`, 使用了模型自带的多态关系 - 创建通知类 `php artisan make:notification ANotification` - 构造方法中注入需要的模型 - via 方法标明通知频道,用来实现通知的方式 `toDatabase,toMail` `via...to` - 针对不同的通知类型,需要实现不同的方法 toXXX($notifiable),返回数组,后会存放在通知数据表中 - 触发通知 `Notifiable.notify`, 调用 User 中的 `notify` 方法,并新建一个*通知实例*作为参数传入 - 删除授权逻辑源码分析 - `app(Gate::class)->authorize($ability, $arguments)` - `$ablility` 策略类方法 `destroy` - `$arguments` 模型实例数组 - `Illuminate\Contracts\Auth\Access` - `Illuminate\Auth\Access\Gate` - Trait - `Flat service` 不要将过多的业务逻辑放到控制器及模型内 - 使用模型trait或service层 - `array_reverse($users, true)` 反转保持键不变 - DB适用场景的SQL,一次性查询操作,无复用性的操作 - `Topic::query()->select(DB::raw('user_id, count(*) as topic_count'))` 指定查询字段 `->where('created_at', '>=', Carbon::now()->subDays($this->pass_days))` 时间条件限定 - `Cache::put,Cache::remmeber,Cache::forget` 有记忆功效 - `php artisan schedule:run` 执行注册的laraval调度任务,控制台kernel的schedule方法下 - 它的执行依赖于系统任务的调度 - 防止数据损坏 - 关联数据删除 - 代码监听器 - 好处是灵活、扩展性强,不受底层数据库约束,坏处当删除时不添加监听器,就会出现漏删 - 外键约束---- 级联删除 - 有些数据库不支持 - Cache - 使用缓存一般要配置缓存的键及过期的时间 - 可以把缓存当作临时的数据库使用 - 数据库结合缓存一起使用,不经常修改的数据库数据,而需要常查询的使用缓存 - 注意在保存的时候,通过事件观察者监听器清空缓存键对应的内容 - 数据操作 - **在数据库操作中,写入对数据库造成的压力,远比读取压力高得多** - 最近活跃时间 - 通常通过中间来处理访问请求记录,只记录会员的访问时间 - 使用Redis来记录用户的访问时间 - 定期将redis数据同步到数据库中,防止redis数据清理及执行丢失,计划任务 - Redis使用 - 数据写入`Redis::hSet($hash, $field, $now)`; 入库单条记录 - 数据获取 `Redis::hGetAll($hash)`;多条记录 - `Redis::hGet($hash, $field)` 哈希表内单个字段记录 - 数据删除 `Redis::del($hash)` - 哈希表,字段,值, hash特别适合用于存储对象,批量读取与删除 - `select index` 切换库 默认是0 - `keys *` 查看所有的键,相当于查看当前库数据表 - `flushall` 清空所有数据库数据 - `flushdb` 清空当前数据库数据 - `info Keyspace` 查看数据库信息 - `help @` 查看命令组 - `redis-cli` 连接客户端 - 模型访问器 - 可设置数据访问策略,比如从redis获取还是从数据库 - Carbon包 - Carbon::now(),yesterday(),Carbon($datetime) 实体 - Laravel 会自动把 created_at 和 updated_at 转成 Carbon 对象 - 自定义二选一 - `protected $casts = ['last_active_at' => 'date'];` - `protected $dates = ['last_active_at'];`