如何制作PDO的单件包装器? [英] How can I make a singleton wrapper for PDO?

查看:81
本文介绍了如何制作PDO的单件包装器?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何使PDO扩展单例?扩展不起作用,因为尝试时会出现致命错误...

How can I make a singleton of the PDO extention? Extending doesn't work, because I get a fatal error when I try it ...

推荐答案

您没有不需要单身人士.

但是要回答这个问题:

您不能将公共可见性变成更严格的可见性.因此,PDO不能将构造函数的可见性更改为public.因此,您需要将PDO实例包装为Singleton:

You cannot turn a public visibility to a stricter visibility. So PDO cannot have the constructor's visibility changed to anything but public. So you need to wrap the PDO instance into a 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();

这篇关于如何制作PDO的单件包装器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆