Yii2和thinkphp5中一个微小的差异造成bug的根源

16 Oct 2018 Category: php

考虑一个场景,一个函数需对相同表进行多次查询,多次查询中有部分查询条件相同。对于这种情况,Yii2和thinkphp5的实现方式要格外小心。在Yii2中,可以直接使用clone 复用共同的查询条件,但是thinkphp5的话,必须把相同条件再重复写一次。

例如,需要查询总有效文章数,以及今日发布有效文章数。

Yii2 版本


$query = Post::find();
$query->where(['status'=>1,'is_delete'=>0]);
$todayquery = clone $query;
$todayquery->andFilterWhere(['between','create_at',$start_date, $end_date])
$totalcount = $query->count();
$todaycount = $todayquery->count();

查看更多

高性能MySQL(第3版)阅读笔记

15 Oct 2018 Category: sql

  • char(5) 和varchar(200) 存储’hello’的空间开销相同,使用短列有什么优势?

  • mysql会分配固定大小内存块保存内部值,尤其使用内存表临时表进行排序,操作时。因此最好只分配需要的存储空间。

  • 数据类型越短越好,尽量避免NULL(NULL索引,统计,比较更复杂,可为NULL的列需要的存储空间更多)

  • 整数(tinyint 8位,smallint 16位,mediumint 24位,int 32位,bigint 64位储储空间)mysql 可为整数指定列宽,但是列宽只是为图像化界面显示字符个数

  • decimal 可指定小数点前后允许的最大位数,消耗存储空间,mysql 将数字打包在二进制字符串中,每4个字节存储9个数字,小数点战一个字节

  • float 在存储相同范围的数据,占用存储空间比decimal小,float 使用4个字节存储,double占用8个字节

  • varchar 存储变成字符串,需要1位或2位保存长度。长度小于255使用1位。由于变长,更新操作更费时间(更新使得行数据长度变化,myisam 将数据猜成不同存储片段,innodb则需要分裂页,将数据放进页内)。mysql5 在存储varchar 的时候,空格会保留??

  • 以下情况适合使用varchar[高性能MySQL(第3版)p115]: 字符串最大长度比平均长度大很多,列的更新少(不会产生碎片);使用类似UTF8字符集,每个字符使用不同字节数存储

  • char ,mysql会根据定义的长度分配固定空间,当存储cahr类型数据,mysql会去除末尾空格。char适合存储固定长度,或长度相近的数据。对于经常变更的数据,char比varchar好,因为不会产生碎片

  • binary,varbinary 固定长度二进制,变长二进制字符串,采用”\0”结束

  • blob,text blob以二进制方式存储,没有排序规则;text存储字符串,有字符集排序规则。mysql 对blob,text排序是对列前面max_sort_length排序,而不是整个字符串排序。

  • enum 类型。枚举类型将列表值压缩到一个或两个字节中,内部保存的是整数,并在.frm保存字符串,整数映射关系。枚举类型排序是按内部整数排序,而非字符排序。枚举列,字符串列表是固定的,每次添加修改都需要使用alter table。将char,varchar 和枚举类型关联时,会比直接cahr,varchar关联慢。

查看更多

sql语句执行顺序(mysql为例)

08 Oct 2018 Category: sql

测试数据表

  • slugs
CREATE TABLE `slugs` (
  `slug_id` int(11) NOT NULL AUTO_INCREMENT,
  `slug_name` varchar(255) DEFAULT '',
  `slug_type` tinyint(1) DEFAULT '1' COMMENT '类型1分类,2标签,3地区',
  PRIMARY KEY (`slug_id`)
) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8
slug_id slug_name slug_type
3 资讯 1
4 旅游 3
5 海外 2
6 香港 2
7 内地 2
8 汽车 3
9 财经 3
10 民生 3

查看更多

从Laravel,Yii,Thinkphp中学习php 操作数据库的事务嵌套

02 Sep 2018 Category: PHP

最近维护历史代码,使用的是phalapi 最初版本开发,数据库操作使用的是notorm。notorm本身不支持事务嵌套,但是在开发过程中,多个操作进行拆分,根据不同业务不同进行调用,必然会设计到多个事务嵌套在一起的问题。举个栗子:

1) 公共模块A,更新用户的账户余额,添加流水记录操作。 2) 模块B,根据用户的操作(消费或充值)根据活动配置赠送相应的优惠券。 基础业务A模块就够用了,但是出现一些业务活动的时候,需要在A成功之后调用B模块,只有两个操作成功之后才完整提交事务。要实现这样的功能,无非两种方式:

1) 模块内部不加事务,事务控制统一交给调用方。谁调用,谁负责事务。内部模块只提供内部模块执行结果。 2) 模块内部控制事务,外部调用只需知道内部执行是否成功。

如果设计的合理,还是比较倾向于使用第一种方案。但是不可否认,你无法确定你的调用模块会不会再被其他人调用,最终结果又演变成第二种方案。因此底层还是需要支持事务嵌套。

查看更多

Laravel5.6 文件上传以及文件管理后台

20 Aug 2018 Category: PHP

今天聊聊在Laravel5.6 如何实现文件上传功能,以及上传文件的管理功能。主要有文件列表,上传新文件,创建文件夹,删除文件夹以及删除文件。

首先添加一个控制器,在命令行中输入php php artisan make:controller Admin/FileController,创建一个空的FileController控制器,控制器中有下列四个方法:

  • index 显示文件和目录列表
  • upload 上传新文件
  • createFolder 创建新文件夹
  • delete 删除文件或目录

查看更多

Laravel5.6 博客搭建系列四--文章标签后台管理

09 Aug 2018 Category: PHP

创建标签模型和迁移

首先需要创建 Tag 模型类:php artisan make:model --migration Tag该命令会在 app 目录下创建模型文件 Tag.php,由于我们在 make:model 命令中使用了 –migration 选项,所以同时会创建 Tag 模型对应的数据表迁移。在标签(Tag)和文章(Post)之间存在多对多的关联关系,因此还要按照下面的命令创建存放文章和标签对应关系的数据表迁移:php artisan make:migration --create=post_tag_pivot create_post_tag_pivot

查看更多

读Yii2框架的web返回格式化类Response

06 Aug 2018 Category: PHP

一个完整的网络请求,最后都需要一个符合协议的返回。Yii2在处理web请求之后,统一通过web/Response处理返回。错误也会经过错误处理返回一个Response。

一个Response完整的流程有哪些?

  • 创建Response对象,设置Resonse响应格式json,html,xml等
  • 触发前置事件,暴露操给开发者在输出前对数据进行调整等
  • 数据格式化。将所有response的内容更加输出格式转换成响应的字符串,并确定http返回码。
  • 设置响应头。输出所有自定会返回头和标注http协议返回头。
  • 输出内容。将字符串内容输出,并刷新缓冲区
  • 触发后置事件。触发Response后置操作
  • 数据清理

查看更多

聊聊Yii2和ThinkPHP5的文件缓存

03 Aug 2018 Category: PHP

翻一翻Yii2和ThinkPHP5的源码,看看它们的文件缓存。看看这些使用广泛的框架如何设计一个缓存操作类。

Yii2和ThinkPHP5缓存操作提供的公共方法对比

Yii2缓存提供的方法
  • get 获取对应$key缓存,不存在或过期返回false
  • set 设置缓存数据
  • exists 判断缓存是否存在
  • mset multiSet 方法别名,用于批量设置缓存
  • mget multiGet 方法别名,用于批量获取缓存
  • add 添加缓存 返回true,如果缓存已经存在则不做操作返回false
  • madd 批量添加多个,返回成功插入的缓存键名数组
  • delete 删除缓存
  • flush 清空缓存所有数据
  • offsetExists exists别名
  • offsetGet get别名
  • offsetSet set别名
  • offsetUnset delete别名
  • getOrSet 获取缓存,如果不存在则根据传入的回调函数设置缓存

查看更多