我正在尝试实现单例模式,我收到以下错误
致命错误:Database :: __ construct()的访问级别必须是公共的 (在类PDO中)在第29行的/config/database.php中
<?php
class Database extends PDO
{
private static $instance;
private function __construct()
{
return parent::__construct(
"mysql:host=localhost;dbname=live",
"root",
"root"
);
}
public function getInstance() {
if(self::$instance === null) {
self::$instance = new Database();
}
return self::$instance;
}
public function __clone()
{
die(__CLASS__ . ' class cant be instantiated. Please use the method called getInstance.');
}
}
$mySingleton = Database::getInstance();
var_dump($mySingleton);
?>
答案 0 :(得分:4)
通过将__construct()函数声明为像private function __construct()
这样的私有函数,您实际上禁止PHP在创建对象时自动调用它。
相反,您应始终将__construct()以及其他声明方法声明为public。
public function __construct()
{
// Now PHP can access me
}
至于让你的Database
类遵循单例模式,扩展一个没有(即PDO)的类是没有意义的。相反,做这样的事情:
<?php
class Database
{
private static $instance;
public function __construct()
{
// Check to see if static PDO instance
// has already been created, so we create only one (singleton)
if(!self::$instance)
{
self::$instance = new PDO(
"mysql:host=localhost;dbname=live",
"root",
"root"
);
}
}
public function getInstance() {
if(self::$instance === null) {
self::__construct();
}
return self::$instance;
}
public function __clone()
{
die(__CLASS__ . ' class cant be instantiated. Please use the method called getInstance.');
}
}
$mySingleton = Database::getInstance();
var_dump($mySingleton);
?>
答案 1 :(得分:3)
由于PDO的__construct()
功能是公开的,因此您无法使用私有__construct()
功能对其进行扩展。
所以“真正的”单身人士是不可能的
您必须设置public function __construct()
。
答案 2 :(得分:3)
您无法更改覆盖方法的访问级别。
您可以在Database
中拥有一个PDO实例,而不是扩展PDO。
组合比继承更灵活。
答案 3 :(得分:0)
你应该
1)通过将构造函数设置为private来禁用构造函数。
2)仅通过调用静态方法创建单个PDO对象。静态方法必须返回PDO对象的实例。
在Silex或Symfony中,您必须使用“\”为类名添加前缀或使用“use \ PDO;”。这仅仅意味着这是一个全球级的。
聚苯乙烯。如果你将__constructor设置为public并使用return functino注意它不会产生任何异常或警告,但你会得到一个返回的类对象而不是return语句的实际值。
所以$ db = new Database()将返回类Database的对象。然后从那里你必须使用类方法访问你的PDO。 $ pdo = $ db-&gt; getInstance() 这不是构建合适单身人士的正确方法。
如果您有兴趣阅读有关单身人士的优缺点和一些用例,请阅读此Best practice on PHP singleton classes,您将找到有关此模式设计的更多信息。
/**
* Singleton pattern
*/
class Database
{
/**
* holds the only PDO instance
*/
private static $_instance;
/**
* private __constructor not accesible
*/
private function __construct()
{
self::$instance = new PDO(
"mysql:host=localhost;dbname=live",
"root",
"root"
);
}
/**
* clone will not duplicate object
*/
public function __clone()
{
die(__CLASS__ . ' class cant be instantiated. Please use the method called getInstance.');
}
/**
* the only public function to access or create PDO object
*/
public static function getInstance()
{
if(!self::$_instance instanceof PDO){
new self;
}
return self::$_instance;
}
}
答案 4 :(得分:0)
除了涉及PHP源代码的技术问题之外,在父项和子项构造函数之间具有不同访问级别的需求是完美的lecit 。
事实上,它已被归档为错误(#61970)。
在2017年3月的提交中,如果我没有错,开发商表示已经关闭:
http://git.php.net/?p=php-src.git;a=commitdiff;h=5324fb1f348f5bc979d9b5f13ac74177b73f9bf7
我使用7月发布的PHP 7.0.24,但我仍然认为它尚未修复。