如何制作PDO扩展的单例?扩展不起作用,因为当我尝试它时会出现致命错误...
答案 0 :(得分:11)
但是要回答这个问题:
您无法将公众可见度变为更严格的可见性。因此PDO不能将构造函数的可见性更改为除public之外的任何内容。所以你需要将PDO实例包装成Singleton:
class MyPdo
{
/**
* @var MyPdo
*/
protected static $_instance;
/**
* @var Pdo
*/
protected $_pdo;
/**
* Creates instance and returns it on subsequent calls
*
* @throws InvalidArgumentException
* @param array $options PDO connection data
* @returns MyPdo
*/
public static function getInstance(array $options = NULL)
{
if(self::$_instance === NULL) {
if($options === NULL) {
throw new InvalidArgumentException(
'You must supply connection options on first run');
}
// call constructor with given options and assign instance
self::$_instance = new self(
$options['dsn'],
$options['user'],
$options['password'],
$options['driver_options']
);
}
return self::$_instance;
}
/**
* Creates new MyPdo wrapping a PDO instance
*
* @throws PDOException
* @param String $dsn
* @param String $user
* @param String $password
* @param Array $driver_options
* @return void
*/
private function __construct($dsn, $user, $password, $driver_options)
{
try {
$this->_pdo = new PDO($dsn, $user, $password, $driver_options);
} catch (PDOException $e) {
echo 'Connection failed: ' . $e->getMessage();
}
}
/**
* Singletons may not be cloned
*/
private function __clone() {}
/**
* Delegate every get to PDO instance
*
* @param String $name
* @return Mixed
*/
public function __get($name)
{
return $this->_pdo->$name;
}
/**
* Delegate every set to PDO instance
*
* @param String $name
* @param Mixed $val
* @return Mixed
*/
public function __set($name, $val)
{
return $this->_pdo->$name = $val;
}
/**
* Delegate every method call to PDO instance
*
* @param String $method
* @param Array $args
* @return Mixed
*/
public function __call($method, $args) {
return call_user_func_array(array($this->_pdo, $method), $args);
}
}
你会这样使用它:
$db = MyPdo::getInstance(array(
'dsn'=>'mysql:dbname=mysql;host=127.0.0.1',
'user' => 'root',
'password' => 'minnymickydaisydonaldplutogoofysanfrancisco',
'driver_options' => array(
PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8"
)));
$version = $db->query( 'SELECT version();' );
echo $version->fetchColumn();
// remove reference to instance
unset($db);
// doesn't require connection data now as it returns same instance again
$db = MyPdo::getInstance();
$version = $db->query( 'SELECT version();' );
echo $version->fetch();