今天有人问我thinkphp里initialize()和构造函数的效果都是一样的,到底有啥区别。
这个问题我曾经也想问,后来我看tp源码才知道它们的关系。
实际上它俩使用的效果是一致的,__construct()是PHP自带的构造函数,其效果就是创建新对象时会自动先执行的方法,说白点就是我执行一个方法,会首先执行当前类的构造函数,如果当前子类没有构造,会执行父类的构造,如果当前子类有构造会只执行当前子类的构造,如果也想执行父类构造,可以使用parent::__construct();
那为什么initialize也能达到每次访问当前类的方法都会被调用呢,就拿tp5来说吧,我想测试控制器方法,直接看tp基类源码:
它的意思就是每次执行构造函数的时候会先执行到tp底层的构造函数里,也会执行控制器初始化,所以initialize()就起到了和构造函数同样的效果,就是每次执行类方法的时候,和构造函数一样会被先执行。
initialize使用方法:实际上initialize你可以修改tp源码随便起名,那咋用呢?
就和构造函数一样,你想执行这个类时都要先处理一件事,你就在这个类加上一个带initialize()的方法体就行。
引申:构造函数怎么用,先看看官方文档怎么说:
构造函数 ¶
void __construct ([ mixed $args
[, $...
]] )
PHP 5 允行开发者在一个类中定义一个方法作为构造函数。具有构造函数的类会在每次创建新对象时先调用此方法,所以非常适合在使用对象之前做一些初始化工作。
Note: 如果子类中定义了构造函数则不会隐式调用其父类的构造函数。要执行父类的构造函数,需要在子类的构造函数中调用parent::__construct()。如果子类没有定义构造函数则会如同一个普通的类方法一样从父类继承(假如没有被定义为 private 的话)。
注意最后()里的话:假如没有被定义为 private 的话。。
如果定义为私有会出现什么后果?报错呗。。
那我就想把构造函数定义为私有的,而且我还就要不报错使用咋办?
解决办法:单例模式
想私有化构造函数且能用就只能在构造函数所在的类里加个静态方法,为什么必须静态方法?因为不能在执行类去new实例化带私有构造的这个类了啊。虽然在执行类不能new,但可以在静态方法里new 自己啊,我new自己我就可以执行到私有构造了嘛。
然后我在执行类使用私有构造类::静态方法()即可。
直接来个例子:
/**
* 单例类
* Singleton.class
*/
class Singleton
{
/**
* 静态成品变量 保存全局实例
*/
private static $_instance = NULL;
/**
* 私有化默认构造方法,保证外界无法直接实例化
*/
private function __construct()
{
}
/**
* 静态工厂方法,返还此类的唯一实例
*/
public static function getInstance() {
if (is_null(self::$_instance)) {
self::$_instance = new Singleton();
// 或者这样写
// self::$_instance = new self();
}
return self::$_instance;
}
/**
* 防止用户克隆实例
*/
public function __clone(){
die('Clone is not allowed.' . E_USER_ERROR);
}
/**
* 测试用方法
*/
public function test()
{
echo 'Singleton Test OK!';
}
}
/**
* 客户端
*/
class Client {
/**
* Main program.
*/
public static function main() {
$instance = Singleton::getInstance();
$instance->test();
}
}
Client::main();