Blogger Information
Blog 29
fans 0
comment 0
visits 14886
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
PHP后期静态绑定、单例模式、重载小结及单例模式连接数据库实例
cool442
Original
397 people have browsed it

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. }
Correcting teacher:PHPzPHPz

Correction status:qualified

Teacher's comments:
Statement of this Website
The copyright of this blog article belongs to the blogger. Please specify the address when reprinting! If there is any infringement or violation of the law, please contact admin@php.cn Report processing!
All comments Speak rationally on civilized internet, please comply with News Comment Service Agreement
0 comments
Author's latest blog post