1、类的内部返回当前对象
从标题看起来,我们可能理解得比较模糊,实际上可以统称为类的内部返回自身,在成员函数的最后使用:return $this;
表示返回自身。
<?php
class Test {
public $orderName;
# 函数链
public function upd_1($name) {
$this->orderName = $name;
return $this;
}
# 函数链
public function upd_2($name) {
$this->orderName = $name;
return $this;
}
# 终结函数
public function getName() {
echo $this->orderName.'<br/>';
}
}
$obj = new Test();
# 链式操作
$obj->upd_1('你妹')->upd_2('你哥')->getName();
# 函数链可以随意调换位置
$obj->upd_2('你哥')->upd_1('你妹')->getName();
# 函数链可以重复使用
$obj->upd_2('你哥')->upd_2('你妹')->getName();
2、什么是链式操作
从上面的代码中,我们可以看出在调用成员函数时,我们与正常的调用方式不一样,
我们可以通过很多个->将一些成员函数连接起来使用,
而通过函数链返回类的自身,下一个函数链就能获得上一个函数链所操作的对象状态,
从而向下进行链式操作,例如:upd_1()
将$orderName
修改为1
,那么upd_2()
在修改之前,就能获得$orderName
被修改后的值。
这就是类返回自身在链式操作时的作用。
链式函数的特点是:
1、使用顺序可以随意调换在任意位置(除开末尾)
2、在一条链式操作中,可以重复使用。
3、必须要返回自身。
3、什么是终结函数
终结函数是链式操作中最重要的一个成员函数,它用于对一条链式操作进行最后的总结(逻辑处理), 所以终结函数是不能返回自身的。 终结函数的特点是:
1、只能出现一条链式操作的末尾
2、在一条链式操作中,不能重复使用。
3、不能返回自身。
4、链式操作的优点和缺点
优点:
可以将一些复杂的逻辑处理优化成一条处理流程进行各种组合操作,
将复杂的场景进行看逻辑分离(可以封装成一些懒人类库)。
缺点:
由于链式函数需要返回自身,所以实际上每一次返回都需要隔外的内存开销。
内存消耗要把单独调用一个成员函数要多许多。
5、封装数据库操作
上面我们说过,链式操作最多的优点是可以封装一些懒人类库,而数据库在这一块就是重中之重了。
数据库操作在实际项目开发中,常用率、代码量绝对是榜首。
所以封装一个Mysql操作类是毋庸置疑的,为了减少操作逻辑,我们一般都会利用链式操作,
将一些简单常用的SQL语句,拆分,封装成链式函数与终结函数,实现傻瓜式数据库操作。
同时学习下静态成员函数,实现链式操作的具体语法。
简单案例如下:
<?php
# 傻瓜式数据库操作类
class Mysql {
/**
* PDO链接实例
*/
private static $_PDO;
/**
* 表名带前缀
*/
private static $_TABLE;
/**
* 表前缀
*/
private static $_PREFIX = 'niu_';
/**
* 数据容器
*/
private static $_DATA = [];
/**
* 条件节点
*/
private static $_WHERE;
/**
* 最终组装后的SQL语句
*/
private static $_SQL;
/**
* 初始化PDO链接
*/
public function __construct() {
try {
$PDO = new PDO('mysql:dbname=love_niu;host=127.0.0.1;port=3306', 'root', 'root');
$PDO->query('SET NAMES utf8;');
self::$_PDO =$PDO;
} catch(PDOException $e) {
die ('数据库连接失败,错误信息:'.$e->getMessage());
}
}
/**
* 选择数据表(起始函数)
* @param string $name 表名不带前缀
*/
public static function name($table) {
self::$_TABLE = self::$_PREFIX . $table;
return new self;
}
/**
* 条件(函数链)
* @param array $array 二维数组,条件 [ '字段名' => ['=', '12'] ]
*/
public static function where($array) {
$where = '';
foreach ($array as $key=>$val) {
$where .= $key.$val[0]."'$val[1]' AND ";
}
self::$_WHERE .= $where;
return new self;
}
/**
* 注入数据内容(函数链)
* @param array $data 一维数组,内容 [ '字段名' => '内容' ]
*/
public static function data($data) {
self::$_DATA = array_merge(self::$_DATA, $data);
return new self;
}
/**
* 修改数据(终结函数)
* @param bool $debug 调试模式开启则返回解析后的SQL语句
*/
public static function update($debug=false) {
self::$_SQL = 'UPDATE '. self::$_TABLE .' SET ';
# 修改内容
foreach (self::$_DATA as $key=>$val) {
self::$_SQL .= $key."='".$val."', ";
}
self::$_SQL = rtrim(self::$_SQL, ', '). ' ';
# 有条件
if (!empty(self::$_WHERE)) {
self::$_SQL .= 'WHERE '. rtrim(self::$_WHERE, 'AND ').';';
}
# 是否开启调试
if ($debug) {
return self::$_SQL;
}
# 执行SQL语句
return self::$_PDO->exec(self::$_SQL);
}
}
# 使用demo
$sql = Mysql::name('user')->where(['id' => ['=', 1]])->data(['id'=>999])->data(['nice'=>'你妹的'])->update();
var_dump($sql);
6、练习题
上面的封装实际上已经完成了Update修改语句,的系列操作封装,
下面同学们基于上面案例的代码,封装剩下的:
Select查询,
Insert新增,
Delete删除,
三种系列语句所对应的终结函数,还有其需要用到的一些函数链。
答案:下载