使用工厂模式连接PHP的PDO太多连接

时间:2014-05-14 09:35:17

标签: php pdo factory-pattern

在teresko的帮助下,我设法实现了工厂设计方法,只连接到我的数据库一次(这就是我的想法),但现在我收到了这个错误:

  

致命错误:未捕获的异常' PDOException'消息' SQLSTATE [1040]连接太多'在

然后继续描述不同地方的8个不同的连接。我是如何建立这么多联系的?

这是我的工厂类:

namespace App\Core;

class structureFactory
{
    protected $provider = null;
    protected $connection = null;

    public function __construct( callable $provider )
    {
        $this->provider = $provider;
    }

    public function create( $name)
    {
        if ( $this->connection === null )
        {
            $this->connection = call_user_func( $this->provider );
        }
        return new $name( $this->connection );
    }
}

因为我只需要模型类中的连接,所以我创建了一个baseModel类,它从structureFactory获取数据库连接,如下所示:

namespace App\Core\Models;

use App\Core\structureFactory as SF;

abstract class baseModel {

    public $getConnection;
    protected function getAdapter() {

        $this->getConnection = function() {

            $m_rdbms = 'mysql';
            $m_host = 'localhost';
            $m_db_name = 'cvcms';
            $m_host_name = $m_rdbms . ':host=' . $m_host. ';dbname=' . $m_db_name;
            $m_uname = 'root';
            $m_pwd ='';

            $instance = new \PDO($m_host_name, $m_uname, $m_pwd);
            $instance->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
            $instance->setAttribute(\PDO::ATTR_EMULATE_PREPARES, false);
            return $instance;
        };

        $factory = new SF($this->getConnection);
        return $factory->create('App\\Core\\Models\\DAL');
    }

} 

所以这基本上会在getConnection函数中创建一个带有Connection的新SF,然后返回一个新的DAL。

这是我的控制器的一个例子,它创建一个新的DAL并调用函数safeQuery:

namespace App\Frontend\Base\Index;

use App\Frontend\Base\baseController as base;
use App\Core\Models\DAL as DAL;

class indexController extends base{

public $data;

public function __construct(){
    parent::__construct();
}

function indexMethod(){
    $query = "SELECT site_data FROM site_data WHERE site_data = :name;";
    $args = array(":name" => 'site_name');
    $this->data = new DAL;
    $this->data = $this->data->safeQuery($query,$args);
}

function render(){

    //Render the index template/view parsing the data acquired from model.
}

}

在我的DAL构造中,我将连接存储在一个局部变量中,就像从baseModel中获取它一样:

use App\Core\Models\baseModel as BM;

class DAL extends BM {

private $c_arr_database_connection_messages;
private $c_obj_pdo;
private $c_obj_stmt;

public function __construct() {
    $this->c_arr_database_connection_messages = array();
    $this->c_obj_pdo = $this->getAdapter();
    echo $this->c_obj_pdo;
    $this->c_obj_stmt = null;
}

...

}

你能帮助我解决我出错的地方吗?

干杯 汤姆

1 个答案:

答案 0 :(得分:3)

您的structureFactory可能看起来像这样。

namespace App\Core;

class structureFactory
{
    protected $connection;

    public function getConnection() 
    {
        if (!$this->connection) {
            $this->connection = new PDO('dsn');
        }
        return $this->connection;
    }
}



namespace App\Core\Models;

use App\Core\structureFactory as structureFactory;

abstract class baseModel {

    protected $factory;

    public function __construct(structureFactory $factory) 
    {
        $this->factory = $factory;
    }

    protected function getAdapter() {
        return $this->factory->getConnection();
    }

} 



use App\Core\Models\baseModel as BM;

class DAL extends BM {

    private $c_arr_database_connection_messages;
    private $c_obj_pdo;
    private $c_obj_stmt;

    public function __construct(App\Core\structureFactory $factory) {
        parent::__construct($factory);

        $this->c_arr_database_connection_messages = array();
        $this->c_obj_pdo = $this->getAdapter();
        echo $this->c_obj_pdo;
        $this->c_obj_stmt = null;
    }

...

}