在PHP5类中,何时调用私有构造函数?
比方说,我正在写一个PHP(> = 5.0)类,这是一个单身人士。 我读过的所有文档都说,使类构造器是私人的,所以类不能直接实例化。
所以如果我有这样的事情:
class SillyDB { private function __construct() { } public static function getConnection() { } }
有没有什么情况下__construct()被调用,而不是如果我正在做一个
new SillyDB()
在课堂内部打电话?
为什么我允许从内部实例化SillyDB呢?
__construct()
只会在包含私有构造函数的类的方法中调用。 所以对于你的单身人士,你可能有这样的方法:
class DBConnection { private static $Connection = null; public static function getConnection() { if(!isset(self::Connection)) { self::Connection = new DBConnection(); } return self::Connection; } private function __construct() { } } $dbConnection = DBConnection::getConnection();
你能够/想要从本身实例化类的原因是,你可以检查以确保在任何给定的时间只有一个实例存在。 毕竟,这是一个单身人士的重点。 使用Singleton进行数据库连接可确保您的应用程序一次不会进行大量的数据库连接。
这是一个非常简单的单一的生成date/时间string:
class TheDate { private static $DateInstance = null; private $dateVal; public static function getDateInstance() { if(!isset(self::$DateInstance)) { self::$DateInstance = new TheDate(); } return self::$DateInstance; } public static function getDateVal() { return self::$DateInstance->dateVal; } private function __construct() { $this->dateVal = strftime("%Y-%m-%d %H:%M:%S"); } }
做这样的事情显然给了我一遍又一遍的相同的date:
$date1 = TheDate::getDateInstance(); echo $date1->getDateVal() . "<br />"; $date2 = TheDate::getDateInstance(); echo $date2->getDateVal() . "<br />";
这样做不会产生任何错误:
class NewDate extends TheDate { public function __construct() { } }
好吧,我跑了一些我自己的testing。
- 如果你没有在子类中声明自己的构造函数,试图实例化它将会引发一个致命的错误,因为它试图调用超类的构造函数。
- 在数据库连接的情况下,当你想要返回(在PHP中,无论如何)一个mysqli实例或
mysql_connect()
函数返回的资源(或其他一些其他的RDBMS链接),只要你标记实例私有,没有任何人对其进行分类和篡改链接的威胁。 - 正如我之前提到的,如果有人真的想要覆盖你的行为并build立多重联系,那么他们也可以写一个新的课程。
testing代码,马克,让我知道你发现了什么。
编辑:此外,在这种特殊情况下,我不知道为什么你需要关心防止一个人的子类。 如果有人可以访问您的PHP代码来进行子类化,那么他们也可以访问您的代码来复制它,并将访问修饰符更改为(无论什么原因)适合的。
在这种情况下,Singleton的实际用处在于,通过使用它,可以确保您始终对给定的HTTP请求使用相同的数据库连接。 它完成了。 其他的东西(使用final
和private构造函数)从理论的angular度来看是有用的,甚至更有用的知道你是否想把API级的代码分发给其他的程序员,但是在这个例子中,所有的关键字正在做的是将字节添加到您的类文件的大小。
一个小挑剔:为了完整性,你可能会声明这个类是最终的,因为你不希望有人inheritance这个类并实现自己的公共构造函数。
(请原谅我,如果编译器捕获重写的私有构造函数,但我不认为它)