关于PHP单例模式,有一点不明白,求指教!


首先,我定义个类,实现单例模式:(这里是简单一写,就是个最基本的单例)


 class Demo()
{
    public static $instance;

    private function __Construct()
    {
        //TODO
    }

    public static function getInstance()
    {
        if(self::$instance){
            return self::$instance;
        }else{
            $instance = new static();
            return $instance;
        }
    }

    public function call()
    {
        //其他方法
    }
}

下面有两种方式实例化类:

1.在需要用的地方


 $aa = Demo::getInstance();
$bb = Demo::getInstance();
$cc = Demo::getInstance();

这样调用肯定是没问题的,一般情况也是这样初始化。

2.定义一个普通类,写个函数初始化,保存在一个静态变量,如下:

类:


 class Demo(){
    public function __Construct(){
        //TODO
    }
}

函数:


 function get_obj(){
    static $obj;
    if($obj){
        return $obj;
    }else{
        $obj = new Demo;
        return $obj;
    }
}

在需要调用的地方这样写:


 $obj = get_obj();
$obj->call();

$obj2 = get_obj();
$obj2->call();

$obj3 = get_obj();
$obj3 = get_obj();

这样不是也只实例化一次这个类吗?

php 设计模式 单例

醒了在睡。。。 9 years, 1 month ago

楼主给了我启发,过程式编程中,在全局函数内用静态变量存储数据库连接实现单例:


 <?php
// config.php
$app = array(
    'db_host'        => '127.0.0.1',
    'db_username'    => 'root',
    'db_password'    => '',
    'db_name'        => 'mysql'
);
// functions.php
function cn_db() {
    global $app;
    static $mysqli;
    if ($mysqli) {
        return $mysqli;
    } else {
        $mysqli = new mysqli($app['db_host'], $app['db_username'], $app['db_password'], $app['db_name']);
        return $mysqli;
    }
}
function cn_foo1() {
    $mysqli = cn_db();
    return $mysqli->query('select user,host from user where user = \'root\'')->fetch_all();
}
function cn_foo2() {
    $mysqli = cn_db();
    return $mysqli->query('select user,host from user')->fetch_all();
}
// controller + view
print_r(cn_foo1());
print_r(cn_foo2());

KiraHI answered 9 years, 1 month ago

静态变量可以定义在函数里或者类属性,两种写法都可以,但前者封装性会比较好些。

karad answered 9 years, 1 month ago

= = 所以呢?
两种写法而已啊。。。
另外,你无论怎么看,都还是第一种更清晰,更独立,更好用啊。。。
第一种封装、抽象的更好,更加符合面向对象啊。
存一个静态变量或者另外弄个函数什么的,你不觉得乱嘛。。。

姉ヶ崎宁々 answered 9 years, 1 month ago

Your Answer