ASCII码 ASCII码

PHP后期静态绑定、单例模式、重载小结及单例模式连接数据库实例

发布于:2022-06-27 08:51:46  栏目:技术文档

1.后期(延迟)静态绑定

  • 在创建类层次结构时,self关键字在编译时就已经确定了它的作用范围,而不是在运行时(后期),self不能动态地与调用类进行绑定。解决办法:用static替换self进行后期(延迟)静态绑定。
  • $this能动态地与调用类进行绑定。
  1. <?php
  2. /**
  3. * 后期(延迟)静态绑定 static
  4. *
  5. */
  6. class sports
  7. {
  8. // 静态属性
  9. public static $sport_event = '足球';
  10. // 静态方法
  11. public static function live_TV()
  12. {
  13. // 用self引用静态属性
  14. echo '正在直播' . self::$sport_event . '节目。<br>';
  15. // 用static引用静态属性
  16. echo '回放' . static::$sport_event . '节目。<br>';
  17. }
  18. }
  19. // 继承sports类
  20. class basketball extends sports
  21. {
  22. // 重定义静态属性
  23. public static $sport_event = '篮球';
  24. }
  25. echo sports::live_TV();
  26. echo basketball::live_TV();
  27. // 结果说明self不能动态地与调用类进行绑定,用static可以。

2. 单例模式: 只允许类被实例化一次

  1. // 单例模式 只允许类被实例化一次
  2. class father
  3. {
  4. // 只可子类访问的静态属性,用于存贮类的实例
  5. protected static $_class;
  6. // 定义构造函数不可用
  7. private function __construct()
  8. {
  9. }
  10. // 定义克隆函数不可用
  11. private function __clone()
  12. {
  13. }
  14. // 获取类的实例函数
  15. static function get_class()
  16. {
  17. // 存贮类实例的变量不存在,则实例化类并存入变量。
  18. if (static::$_class === null) {
  19. static::$_class = new static;
  20. }
  21. // 返回实例对象
  22. return static::$_class;
  23. }
  24. }
  25. class son1 extends father
  26. {
  27. protected static $_class;
  28. }
  29. class son2 extends father
  30. {
  31. protected static $_class;
  32. }
  33. var_dump($a1 = father::get_class());
  34. var_dump($a2 = son1::get_class());
  35. var_dump($a3 = son2::get_class());
  36. var_dump($b1 = father::get_class());
  37. var_dump($b2 = son1::get_class());
  38. var_dump($b3 = son2::get_class());
  39. var_dump($a = new basketball);
  40. var_dump($b = new basketball);
  41. var_dump($a1 === $b1);
  42. var_dump($a2 === $b2);
  43. var_dump($a3 === $b3);
  44. var_dump($a === $b);

从显示结果可以看到,单例模式只能实例化一次,多次实例化的都是同一个类。

3. php重载

  • php重载 属性, 是指动态地创建类属性和方法。我们是通过魔术方法(magic methods)来实现的。__get __set __callStatic __call
  • 当访问类中不存在或者不可见的类成员时,会自动调用魔术方法set get
  • 因为魔术方法都是公开的,所以一些私有成员的不可见性就不会生效
  1. <?php
  2. /**
  3. * php重载 overload
  4. *
  5. */
  6. class Id_card
  7. {
  8. public $name; // 姓名属性可公开
  9. private $id; // 身份证号不可公开
  10. public function __construct($name, $id)
  11. {
  12. $this->name = $name;
  13. $this->id = $id;
  14. }
  15. // 这个魔术方法是系统带有的,这里可以注释掉
  16. public function __set($name, $value)
  17. {
  18. $this->$name = $value;
  19. return $this->$name;
  20. }
  21. // 这个魔术方法是系统带有的,这里可以注释掉
  22. public function __get($name)
  23. {
  24. return $this->$name;
  25. }
  26. }
  27. $id = new Id_card('成龙', '486136196501221035');
  28. var_dump($id);
  29. $id->age = 68; // 自动执行魔术方法__set
  30. echo $id->age; // 自动执行__get
  31. // 类没有定义age属性,但系统会自动执行魔术方法,这就是重载
  32. echo $id->id; // 虽然id属性定义了不可公开,但是系统自动执行__get方法,导致定义失效

3. 单例模式连接数据库

  1. <?php
  2. /**
  3. * 单例模式连接数据库
  4. */
  5. namespace DB\pdo {
  6. // 使用了命名空间,因此要使用系统pdo对象就要引用
  7. use pdo, PDOException, Exception;
  8. // 定义数据库查询通用接口
  9. interface DB_query
  10. {
  11. // 连接数据库接口方法
  12. static function do_conn($dsn, $username, $password);
  13. // 查询数据库接口方法
  14. static function select($table, $where = []);
  15. // 插入数据接口方法
  16. static function insert($table, $date);
  17. // 更新数据接口方法
  18. static function update($table, $date, $where);
  19. // 删除数据接口方法
  20. static function delete($table, $where);
  21. }
  22. /**
  23. * 定义数据库连接抽象类,采用数据库查询通用接口DB_query
  24. * 使用单例模式实现连接数据库
  25. */
  26. abstract class DB_conn implements DB_query
  27. {
  28. protected static $pdo; // 存放连接数据库pdo对象
  29. // 禁用魔术方法
  30. private function __construct()
  31. {
  32. }
  33. private function __clone()
  34. {
  35. }
  36. // 创建唯一实例,存放pdo对象
  37. static function do_conn($dsn, $username, $password)
  38. {
  39. // 判断属性$pdo是否存在,不存在则创建pdo对象
  40. if (is_null(self::$pdo)) {
  41. // 创建pdo,进行错误识别
  42. try {
  43. self::$pdo = new PDO($dsn, $username, $password);
  44. return self::$pdo;
  45. } catch (PDOException $err) {
  46. //PDOException异常类,指定变量$err为异常类型变量;
  47. die('错误:' . $err->getMessage());
  48. }
  49. }
  50. }
  51. }
  52. /**
  53. * 定义工作类,实现接口方法
  54. *
  55. */
  56. class DB extends DB_conn
  57. {
  58. private static $sql;
  59. private static $sql_state;
  60. // 预处理查询操作
  61. static function do_sql($sql)
  62. {
  63. if (!is_null(self::$pdo)) {
  64. $stmt = self::$pdo->prepare($sql);
  65. $stmt->execute();
  66. self::$sql_state = ($stmt->rowCount() > 0) ? true : false;
  67. return $stmt->fetchAll(PDO::FETCH_ASSOC);
  68. }
  69. }
  70. // 查询数据库接口方法
  71. static function select($table, $where = [])
  72. {
  73. if (count($where) < 1) {
  74. $where = '';
  75. } else {
  76. $where = "WHERE {$where[0]}{$where[1]}'{$where[2]}'";
  77. }
  78. self::$sql = "SELECT * FROM `{$table}` {$where}";
  79. var_dump(self::$sql);
  80. return self::do_sql(self::$sql);
  81. }
  82. // 插入数据接口方法
  83. static function insert($table, $date = [])
  84. {
  85. $keys = '';
  86. $values = [];
  87. if (count($date) > 0) {
  88. $keys = implode(',', array_keys($date));
  89. foreach ($date as $key => $value) {
  90. $values[] = "'{$value}'";
  91. }
  92. $values = implode(',', $values);
  93. }
  94. self::$sql = "INSERT INTO `{$table}` ({$keys}) VALUES ({$values})";
  95. try {
  96. self::do_sql(self::$sql);
  97. echo "插入数据成功!";
  98. } catch (Exception $err) {
  99. echo '插入数据失败';
  100. }
  101. }
  102. // 更新数据接口方法
  103. static function update($table, $date, $where)
  104. {
  105. $dates = [];
  106. if (count($date) > 0) {
  107. foreach ($date as $key => $value) {
  108. $dates[] = " $key =' $value ' ";
  109. }
  110. $dates = implode(',', $dates);
  111. }
  112. self::$sql = "UPDATE `$table` SET $dates WHERE $where";
  113. // var_dump(self::$sql);
  114. try {
  115. self::do_sql(self::$sql);
  116. if (self::$sql_state) {
  117. echo "更新数据成功!";
  118. } else {
  119. echo '更新数据失败';
  120. }
  121. } catch (Exception $err) {
  122. echo '更新数据失败';
  123. }
  124. }
  125. // 删除数据接口方法
  126. static function delete($table, $where)
  127. {
  128. self::$sql = "DELETE FROM `$table` WHERE $where";
  129. try {
  130. self::do_sql(self::$sql);
  131. if (self::$sql_state) {
  132. echo "删除数据成功!<br>";
  133. } else {
  134. echo '删除数据失败<br>';
  135. }
  136. } catch (Exception $err) {
  137. echo '删除数据失败<br>';
  138. }
  139. }
  140. }
  141. // mysql数据库类
  142. class DB_mysql
  143. {
  144. public static $dsn;
  145. public static $username;
  146. public static $password;
  147. private static $DB_config = [
  148. 'DB_type' => 'mysql', // 连接数据库类型名
  149. 'host' => 'localhost', // 数据库服务器名
  150. 'port' => '3308', // 数据库数据库服务器端口
  151. 'dbname' => 'php', // 数据库名
  152. 'charset' => 'utf8mb4', // 字符集
  153. 'username' => 'root', // 数据库服务器用户名
  154. 'password' => '', // 数据库服务器密码
  155. ];
  156. // 禁用魔术方法
  157. private function __construct()
  158. {
  159. }
  160. private function __clone()
  161. {
  162. }
  163. static function get_dsn()
  164. {
  165. // 用extract()函数将数组转为变量,即数组索引为变量名
  166. extract(self::$DB_config);
  167. self::$username = $username;
  168. self::$password = $password;
  169. // 用sprintf格式化字符串,用占位符代入变量
  170. self::$dsn = sprintf('%s:host=%s;port=%s;charset=%s;dbname=%s', $DB_type, $host, $port, $charset, $dbname);
  171. }
  172. }
  173. }
  174. // 客户端代码
  175. namespace user {
  176. use DB\pdo\DB_mysql, DB\pdo\DB;
  177. DB_mysql::get_dsn();
  178. DB::do_conn(DB_mysql::$dsn, DB_mysql::$username, DB_mysql::$password);
  179. var_dump(DB::select('user', ['name', '=', '小李']));
  180. DB::insert('user', ['name' => '小王', 'pass' => '7c4a8d09ca3762af61e59520943dc26494f8941b', 'gender' => 1]);
  181. DB::update('user', ['name' => '小s', 'gender' => 1], 'id=8');
  182. DB::delete('user', 'id=9');
  183. }
相关推荐
阅读 +