php 单例模式

进行单例模式之前来一个热身

function test()
{
static $nm = 2;
$nm = $nm * $nm;
print $nm."
";
}
// 第一次执行,$nm = 4
test();
// 第一次执行,$nm = 16
test();
// 第一次执行,$nm = 256
test();

静态变量只存在于函数作用域内,也就是说,静态变量只存活在栈中。一般的函数内变量在函数结束后会释放,比如局部变量,但是静态变量却不会。就是说,下次再调用这个函数的时候,该变量的值会保留下来。

单例类需要注意以下几点:
1、构造函数需要标记为private(访问控制:防止外部代码使用new操作符创建对象),单例类不能在其他类中实例化,只能被其自身实例化;
2、拥有一个保存类的实例的静态成员变量,下次访问 该变量的值会保留下来。
3、拥有一个访问这个实例的公共的静态方法(常用getInstance()方法进行实例化单例类,通过instanceof操作符可以检测到类是否已经被实例化)
4、需要创建__clone()方法防止对象被复制(克隆)

为什么要使用PHP单例模式?

1、php的应用主要在于数据库应用, 所以一个应用中会存在大量的数据库操作, 使用单例模式, 则可以避免大量的new 操作消耗的资源。
2、如果系统中需要有一个类来全局控制某些配置信息, 那么使用单例模式可以很方便的实现. 这个可以参看ZF的FrontController部分。
3、在一次页面请求中, 便于进行调试, 因为所有的代码(例如数据库操作类db)都集中在一个类中, 我们可以在类中设置钩子, 输出日志,从而避免到处var_dump, echo。

代码实现:

<?php
 function test()
  {
    static $nm = 2;
    $nm = $nm * $nm;
    print $nm."<br />";
  }
  // 第一次执行,$nm = 4
  test(); 
  // 第一次执行,$nm = 16
  test(); 
  // 第一次执行,$nm = 256
  test();
Class Db{
    public $_dbname;
    private static $_instance;
    private function __construct(){
        echo 'This is a Constructed method;';
    }
    public static function getInstance(){
        if(self::$_instance === null){
              self::$_instance = new self();
        }
        return self::$_instance;
    }
    private function __clone(){
        echo  'this is clone Object';
        trigger_error('Clone is not allow!',E_USER_ERROR);
    }
    public function getDbName(){
        echo $this->_dbname;
    }
    public function setDbName($dbname){
        $this->_dbname=$dbname;
    }
    public function ceshi(){
        return 2323;
    }
}
$instance = Db::getInstance();
// $instance1 = Db::getInstance();

// 克隆对象
$db_clone = clone $instance;

// if($db_clone === $instance){
//     echo '相等';
// }
// echo $db_clone->ceshi();
// echo '不相等';
// die;
// echo $instance1->ceshi();
// echo $instance2->ceshi();
// if($instance1 === $instance2){
//     echo  '相等';die;
// }
// echo '不相等';die;

单例模式防止被克隆有两种方式:

1、:设置魔术方法__clone();访问权限为private
        private function __clone(){
                echo  'this is clone Object';
                trigger_error('Clone is not allow!',E_USER_ERROR);
        }

2、若__clone()为公用方法,则在函数中加上自定义错误,如trigger_error('Clone is not allow!',E_USER_ERROR);
public function __clone(){
trigger_error('Clone is not allow!',E_USER_ERROR);
}

posted @ 2017-09-13 09:51  赤热的心  阅读(144)  评论(0编辑  收藏  举报