zl程序教程

您现在的位置是:首页 >  后端

当前栏目

PHP的static关键字实现单例模式和享元模式

PHP模式 实现 关键字 单例 static 享元
2023-09-27 14:25:41 时间

码字不易,转载请附原链,搬砖繁忙回复不及时见谅,技术交流请加QQ群:909211071

发现

最近看公司底层源码,发现有很多方法里边用到了static变量,用于实现享元模式,之前没接触到过,今天特意研究一下。

提问

首先抛出一个问题,下面这段代码会输出什么?

<?php
 function test($key = '', $value = '')
 {
     static $data = array();
     if (!empty($key)) {
         $data[$key] = $value;
     }
     return $data;
 }

print_r( test(1, 111) );
print_r( test(2, 222) );

如果你的回答是下面,那么说明你对static没有真正理解

Array
(
    [2] => 222
)

探究

static在函数内使用,第一次调用时static变量不存在,所以会定义,第二次开始, static $data = array();这条语句并不会重新定义了,所以输出应该如下:

Array
(
    [1] => 111
)
Array
(
    [1] => 111
    [2] => 222
)

应用

我们平时实现单例模式是不是都是用面向对象的,三私一公?现在我们明白了static,用static实现单例,比面向对象的方法要轻便许多,直接上代码:

<?php

class A
{
    private $config;
    public function __construct($config)
    {
        $this->config = $config;
        echo 'new success config is:' . $config . "\n";
    }
    public function test()
    {
        echo 'echo' . $this->config . "\n";
    }
}

function load($class, $config)
{
    static $objs = array();

    $class = strtolower($class);

    if (isset($objs[$class]) && isset($objs[$class][$config])) {
        return $objs[$class][$config];
    }

    if (!isset($objs[$class])) {
        $objs[$class] = [];

        $className = ucfirst($class);
        $objs[$class][$config] = new $className($config);
        return $objs[$class][$config];
    }
}


$class_config1 = load('A', 'config1');
$class_config1->test();
echo "\n";

$class_config1 = load('A', 'config2');
$class_config1->test();
echo "\n";

$class_config1 = load('A', 'config1');
$class_config1->test();
echo "\n";

我们可以发现,配置为config1的构造函数只执行了一次,说明只实例化了一次