1、类的内部返回当前对象

从标题看起来,我们可能理解得比较模糊,实际上可以统称为类的内部返回自身,在成员函数的最后使用:return $this;

表示返回自身。

  1. <?php
  2. class Test {
  3. public $orderName;
  4. # 函数链
  5. public function upd_1($name) {
  6. $this->orderName = $name;
  7. return $this;
  8. }
  9. # 函数链
  10. public function upd_2($name) {
  11. $this->orderName = $name;
  12. return $this;
  13. }
  14. # 终结函数
  15. public function getName() {
  16. echo $this->orderName.'<br/>';
  17. }
  18. }
  19. $obj = new Test();
  20. # 链式操作
  21. $obj->upd_1('你妹')->upd_2('你哥')->getName();
  22. # 函数链可以随意调换位置
  23. $obj->upd_2('你哥')->upd_1('你妹')->getName();
  24. # 函数链可以重复使用
  25. $obj->upd_2('你哥')->upd_2('你妹')->getName();

2、什么是链式操作

从上面的代码中,我们可以看出在调用成员函数时,我们与正常的调用方式不一样,

我们可以通过很多个->将一些成员函数连接起来使用,

而通过函数链返回类的自身,下一个函数链就能获得上一个函数链所操作的对象状态,

从而向下进行链式操作,例如:upd_1()$orderName修改为1,那么upd_2()在修改之前,就能获得$orderName被修改后的值。

这就是类返回自身在链式操作时的作用。

链式函数的特点是:

  1. 1、使用顺序可以随意调换在任意位置(除开末尾)
  2. 2、在一条链式操作中,可以重复使用。
  3. 3、必须要返回自身。

3、什么是终结函数

终结函数是链式操作中最重要的一个成员函数,它用于对一条链式操作进行最后的总结(逻辑处理), 所以终结函数是不能返回自身的。 终结函数的特点是:

  1. 1、只能出现一条链式操作的末尾
  2. 2、在一条链式操作中,不能重复使用。
  3. 3、不能返回自身。

4、链式操作的优点和缺点

优点:

  1. 可以将一些复杂的逻辑处理优化成一条处理流程进行各种组合操作,
  2. 将复杂的场景进行看逻辑分离(可以封装成一些懒人类库)。

缺点:

  1. 由于链式函数需要返回自身,所以实际上每一次返回都需要隔外的内存开销。
  2. 内存消耗要把单独调用一个成员函数要多许多。

5、封装数据库操作

上面我们说过,链式操作最多的优点是可以封装一些懒人类库,而数据库在这一块就是重中之重了。

数据库操作在实际项目开发中,常用率、代码量绝对是榜首。

所以封装一个Mysql操作类是毋庸置疑的,为了减少操作逻辑,我们一般都会利用链式操作,

将一些简单常用的SQL语句,拆分,封装成链式函数与终结函数,实现傻瓜式数据库操作。

同时学习下静态成员函数,实现链式操作的具体语法。

简单案例如下:

  1. <?php
  2. # 傻瓜式数据库操作类
  3. class Mysql {
  4. /**
  5. * PDO链接实例
  6. */
  7. private static $_PDO;
  8. /**
  9. * 表名带前缀
  10. */
  11. private static $_TABLE;
  12. /**
  13. * 表前缀
  14. */
  15. private static $_PREFIX = 'niu_';
  16. /**
  17. * 数据容器
  18. */
  19. private static $_DATA = [];
  20. /**
  21. * 条件节点
  22. */
  23. private static $_WHERE;
  24. /**
  25. * 最终组装后的SQL语句
  26. */
  27. private static $_SQL;
  28. /**
  29. * 初始化PDO链接
  30. */
  31. public function __construct() {
  32. try {
  33. $PDO = new PDO('mysql:dbname=love_niu;host=127.0.0.1;port=3306', 'root', 'root');
  34. $PDO->query('SET NAMES utf8;');
  35. self::$_PDO =$PDO;
  36. } catch(PDOException $e) {
  37. die ('数据库连接失败,错误信息:'.$e->getMessage());
  38. }
  39. }
  40. /**
  41. * 选择数据表(起始函数)
  42. * @param string $name 表名不带前缀
  43. */
  44. public static function name($table) {
  45. self::$_TABLE = self::$_PREFIX . $table;
  46. return new self;
  47. }
  48. /**
  49. * 条件(函数链)
  50. * @param array $array 二维数组,条件 [ '字段名' => ['=', '12'] ]
  51. */
  52. public static function where($array) {
  53. $where = '';
  54. foreach ($array as $key=>$val) {
  55. $where .= $key.$val[0]."'$val[1]' AND ";
  56. }
  57. self::$_WHERE .= $where;
  58. return new self;
  59. }
  60. /**
  61. * 注入数据内容(函数链)
  62. * @param array $data 一维数组,内容 [ '字段名' => '内容' ]
  63. */
  64. public static function data($data) {
  65. self::$_DATA = array_merge(self::$_DATA, $data);
  66. return new self;
  67. }
  68. /**
  69. * 修改数据(终结函数)
  70. * @param bool $debug 调试模式开启则返回解析后的SQL语句
  71. */
  72. public static function update($debug=false) {
  73. self::$_SQL = 'UPDATE '. self::$_TABLE .' SET ';
  74. # 修改内容
  75. foreach (self::$_DATA as $key=>$val) {
  76. self::$_SQL .= $key."='".$val."', ";
  77. }
  78. self::$_SQL = rtrim(self::$_SQL, ', '). ' ';
  79. # 有条件
  80. if (!empty(self::$_WHERE)) {
  81. self::$_SQL .= 'WHERE '. rtrim(self::$_WHERE, 'AND ').';';
  82. }
  83. # 是否开启调试
  84. if ($debug) {
  85. return self::$_SQL;
  86. }
  87. # 执行SQL语句
  88. return self::$_PDO->exec(self::$_SQL);
  89. }
  90. }
  91. # 使用demo
  92. $sql = Mysql::name('user')->where(['id' => ['=', 1]])->data(['id'=>999])->data(['nice'=>'你妹的'])->update();
  93. var_dump($sql);

6、练习题

上面的封装实际上已经完成了Update修改语句,的系列操作封装,

下面同学们基于上面案例的代码,封装剩下的:

  1. Select查询,
  2. Insert新增,
  3. Delete删除,

三种系列语句所对应的终结函数,还有其需要用到的一些函数链。

答案:下载