php设计模式——单例模式

时间:2023-11-29 20:43:44

单例模式概念

单例模式是指整个应用中类只有一个对象实例的设计模式。

单例模式的特点

  • 一个类在整个应用中只有一个实例
  • 类必须自行创建这个实例
  • 必须自行向整个系统提供这个实例

php中使用单例模式的原因

我用php大部分操作都是和各种数据库打交道,包括mysql,redis,memcache等各种关系型和非关系型数据库,所以一个应用中会 存在大量连接数据库的操作,如果不用单例模式,那每次都要new操作,但是每次new都会消耗大量的内存资源和系统资源,而且每次打开和关闭数据库连接都 是对数据库的一种极大考验和浪费。
贴出我之前常用的不好的数据库连接代码,给大家一个错误示范:
  1. <?php
  2. class MysqlConn
  3. {
  4. // MYSQL数据库连接信息
  5. const MYSQLHOSTNAME = "127.0.0.1";
  6. const MYSQLUSERNAME = "root";
  7. const MYSQLPASSWORD = "***";
  8. const MYSQLDBNAME = "test";
  9. const MYSQLCHARSET = "utf8";
  10. /**
  11. * Description:mysql数据库连接函数
  12. * Return value:连接成功返回数据库连接句柄;连接失败返回错误消息
  13. */
  14. public function MysqlConnect()
  15. {
  16. $db = new mysqli(self::MYSQLHOSTNAME, self::MYSQLUSERNAEM, self::MYSQLPASSWORD, self::MYSQLDBNAME); // 连接数据库
  17. $db->set_charset(self::MYSQLCHARSET);
  18. if (mysqli_connect_errno())
  19. {
  20. throw new CircleMysqlException("服务器系统故障", 1001);
  21. }
  22. else
  23. {
  24. return $db;
  25. }
  26. }
  27. }

缺陷:

每次数据库连接都要new这个类,然后调用mysqlconnect方法,返回close掉,频繁的new和数据库连接关闭操作是非常消耗资源的

改进:

每次应该直接返回当前应用中已经打开的数据库连接句柄

  1. //单例模式返回数据库连接句柄
  2. $db = MysqlConn::SingleMysqlConnect();

php单例模式的实现

  1. <?php
  2. class Singleton
  3. {
  4. /**
  5. * Description:(1)静态变量,保存全局实例,跟类绑定,跟对象无关
  6. *             (2)私有属性,为了避免类外直接调用 类名::$instance,防止为空
  7. */
  8. private static $instance;
  9. /**
  10. * Description:数据库连接句柄
  11. */
  12. private $db;
  13. /**
  14. * Description:私有化构造函数,防止外界实例化对象
  15. */
  16. private static function __construct()
  17. {
  18. }
  19. /**
  20. * Description:私有化克隆函数,防止外界克隆对象
  21. */
  22. private function __clone()
  23. {
  24. }
  25. /**
  26. * Description:静态方法,单例访问统一入口
  27. * @return Singleton:返回应用中的唯一对象实例
  28. */
  29. public static function GetInstance()
  30. {
  31. if (!(self::$instance instanceof self))
  32. {
  33. self::$instance = new self();
  34. }
  35. return self::$instance;
  36. }
  37. /**
  38. * Description:获取数据库的私有方法的连接句柄
  39. */
  40. public function GetDbConnect()
  41. {
  42. return $this->db;
  43. }
  44. }
  • 需要一个保存类的唯一实例的静态成员变量(通常$instance为私有变量)
  • 构造函数和克隆函数必须声明为私有的,为了防止外部程序new类从而失去单例模式意义
  • 必须提供一个访问这个实例的公共静态方法,从而返回唯一实例的一个引用