在PHP中,我有以下单例数据库类:
class Database
{
private static $instance;
private function __construct()
{
self::$instance = new mysqli('localhost', 'root', 'Matthias', 'financecontrol', '3307');
if (!self::$instance) {
throw new Exception('Could not connect to database in function __construct.');
}
}
public static function getInstance()
{
if (!self::$instance) {
self::$instance = new Database();
}
return self::$instance;
}
}
每当我尝试在另一个PHP文件中对数据库执行查询时,例如检查用户是否已经存在:
function userExists($username)
{
try {
$connection = Database::getInstance();
$result = $connection->query("select * from user where username='$username'");
if (!$result) {
throw new Exception("Connection to database failed in function userExists.");
}
if ($result->num_rows > 0) {
return true;
} else {
return false;
}
} catch (Exception $ex) {
$errorPager = new ErrorpageGenerator();
$errorPager->generateErrorPage($ex->getMessage());
return false;
}
}
我收到错误消息“PHP致命错误:在第44行的User.php中调用未定义的方法Database :: query()”
我已经尝试在Database类中添加查询功能,但似乎没有解决问题。有任何想法吗?感谢
答案 0 :(得分:2)
当然,您必须添加此方法。但是你不能将Database()和mySQLi对象分配给m_pInstance
所以:
class Database
{
private static $conn;
// ...
public function __construct()
{
self::$conn = new mysqli('localhost', 'root', 'root', 'database', '3307');
//...
然后
public function query($sql)
{
return self::$conn->query($sql);
// or
return mysqli_query(self::$conn, $sql);
}
修改强>
工作代码:
class Database
{
private static $instance = null;
private static $conn;
private function __construct()
{
self::$conn = new mysqli('localhost', 'root', 'root', 'database', '3307');
}
public static function getInstance()
{
if (self::$instance == null) {
self::$instance = new Database();
}
return self::$instance;
}
public function query($sql)
{
return self::$conn->query($sql);
}
}
答案 1 :(得分:1)
您收到此错误,因为Database::$m_pInstance
包含Database
类和非 MySQLi实例的实例。您在部分代码之间创建了“冲突”:
public static function getInstance()
{
if (!self::$m_pInstance) {
self::$m_pInstance = new Database(); // << PROBLEM
}
return self::$m_pInstance;
}
覆盖了构造函数的作用:
private function __construct()
{
self::$m_pInstance = new mysqli( /* .. */ ); // PROBLEM
if (!self::$m_pInstance) {
throw new Exception('Could not .. blah');
}
else {
return self::$m_pInstance;
}
}
即使构造函数为MySQLi对象的实例分配self::$m_pInstance
,它也会被self::$instance = new Database();
覆盖。
另外,在php __constuct()
中,方法不应该return
。
那就是说,我认为应该警告你单身被认为是反模式,应该避免。您的代码也有意想不到的副作用,迫使每个应用程序只有一个数据库(不是连接,数据库)。
您可能会从看几个讲座中受益:
答案 2 :(得分:0)
您的代码看起来不正确。
首先,为$ m_pInstance分配一个新的数据库实例。但是,在构造函数中,为它分配一个新的mysqli实例。我不确定php如何处理这种情况,但它似乎将它视为数据库对象,如您的错误消息所示。但是,Database类没有查询方法。
因此,解决方案是将mysqli对象保存在不同的字段中,并为其添加getter和setter,或者将方法委托给它。