问题
I´ve made a database connection with PDO and the singleton pattern.
Everything works fine as long as I have the $_db
variable set as public but it needs to be private... When I make it private I off course get the Error: Cannot access private property Database::$_db
Can someone tell me how to make it private and still be able to get an instance?
When I call the database connection from another file I call the function getInstance()
Here is an example how I call it from one file:
$db = Database::getInstance();
$query = $db->_db->prepare("SELECT `password`, `id` FROM `users` WHERE `username` = ?");
This is what my database connection file looks like:
class Database
{
private $_db;
static $_instance;
private function __construct()
{
$this->_db = new PDO('mysql:host=localhost;dbname=mvcuser', 'root', '');
$this->_db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
private function __clone(){}
public static function getInstance()
{
if (!(self::$_instance instanceof self))
{
self::$_instance = new self();
}
return self::$_instance;
}
public function query($sql)
{
return $this->_db->query($sql);
}
}
回答1:
You don't need to write
$db->_db->
Because you're already using instance of your class.
Here you have a reference of your DB class
$db = Database::getInstance();
Every time when you decide to make a query or someting use only $db->query();, $db->prepare();
Look at your code: you're already using $_db reference in you DB class. So, you don't need to call $_db as public variable.
回答2:
Oh, I can't stand all that static struggle no more.
Here is a minified version of @nikic's static PDO class
class DB
{
protected static $instance = null;
final private function __construct() {}
final private function __clone() {}
public static function instance()
{
if (self::$instance === null)
{
$dsn = 'mysql:host='.DB_HOST.';dbname='.DB_NAME;
self::$instance = new PDO($dsn, DB_USER, DB_PASS);
self::$instance->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
return self::$instance;
}
public static function __callStatic($method, $args) {
return call_user_func_array(array(self::instance(), $method), $args);
}
}
Used the way static classes ought to be
echo DB::query("SELECT 'foo'")->fetchColumn();
echo DB::lastInsertId();
Without this __callStatic()
magic you will have to mirror all the PDO methods manually, just like ComFreek said.
来源:https://stackoverflow.com/questions/20101082/pdo-with-singleton-cannot-access-private-property