在PHP开发中,单例模式是一种常见的设计模式,它确保一个类只有一个实例,并提供一个全局访问点。单例模式主要用于控制资源的使用,比如数据库连接、日志记录器等。本文通过实例展示了PHP中的单例类写法。
单例模式的关键点有三个:
1. 私有化构造函数,防止外部直接实例化对象。
2. 持有自己类的私有静态变量。
3. 提供一个公共的访问点,让外界获取这个唯一实例。
我们定义了一个单例类`UTIL`,这个类包含了一个私有的静态变量`$instance`用于存储类的唯一实例,以及一个公共的静态方法`get()`用于获取这个实例。这个方法内部会判断`$instance`是否已存在,如果不存在则创建一个新实例,返回已存在的实例或新创建的实例。此外,`UTIL`类还定义了公共属性`$number`和方法`change()`、`getNum()`用于操作或获取`$number`的值。
```php
class UTIL {
private static $instance;
public $number = 10;
public function get() {
if (!self::$instance) {
self::$instance = new UTIL();
}
return self::$instance;
}
public function change($num) {
$this->number += $num;
}
public function getNum() {
return $this->number;
}
}
```
接下来,我们定义了两个使用单例类的应用类`SINGLEA`和`SINGLEB`。这两个类的构造函数都会调用`UTIL::get()`来获取`UTIL`类的实例。这样无论创建多少个`SINGLEA`或`SINGLEB`实例,它们都使用相同的`UTIL`实例进行操作,实现了数据共享和内存的节省。
```php
class SINGLEA {
private $numInst;
function __construct() {
$this->numInst = UTIL::get();
}
public function change($num) {
$this->numInst->change($num);
}
public function getNum() {
return $this->numInst->getNum();
}
}
class SINGLEB {
private $numInst;
function __construct() {
$this->numInst = UTIL::get();
}
public function change($num) {
$this->numInst->change($num);
}
public function getNum() {
return $this->numInst->getNum();
}
}
```
在使用单例类的示例代码中,我们创建了`SINGLEA`和`SINGLEB`的实例,并对`UTIL`类的实例进行了操作。通过`change()`方法改变了`$number`的值,然后通过`getNum()`方法获取新的值并打印出来。
```php
$instA = new SINGLEA();
$instA->change(100);
var_dump('SINGLEA CHANGED:');
var_dump($instA->getNum());
$instB = new SINGLEB();
$instB->change(-510);
var_dump('SINGLEB CHANGED:');
var_dump($instB->getNum());
```
最终输出结果如下:
```
string(17) "SINGLEA CHANGED:"
int(110)
string(17) "SINGLEB CHANGED:"
int(-400)
```
在最后的输出结果中,我们可以看到即使`SINGLEA`和`SINGLEB`分别对同一个`UTIL`实例进行了不同的操作,`UTIL`的`$number`值是共享的,这体现了单例模式的核心思想。
在实际的Web应用开发中,单例模式的使用需要谨慎,因为全局状态可能会导致测试困难、数据冲突等问题。在设计系统时,要根据实际需要决定是否采用单例模式。