Отключение PDO и ссылка на переменную PHP

Я новичок в PHP высокого уровня. Но не новичок в программировании.

У нас есть программное обеспечение (находящееся в процессе ликвидации, но все еще активное), которое убивает нашу БД.

Внутри используется PDO, проблема после большого количества потраченного времени — режим отключения PDO и использование PDO внутри класса Wrap.

public function connect() {
if(!$this->connected){
$col = 'mysql:host='
.$this->parametri->getHOST()
.';'
.'dbname='
.$this->parametri->getDB()
.';'
.'charset=utf8';

try {
// connessione tramite creazione di un oggetto PDO
$db = new PDO($col , $this->parametri->getDBUSER(),
$this->parametri->getPASS());
$this->pdoconn=$db;
$this->connected=TRUE;
}
catch(PDOException $e) {
$this->connected=FALSE;
return NULL;
}
}
return  $this->pdoconn;
}

public function getPDO(){
if ($this->connected){
return $this->pdoconn;
}else {
return NULL;
}
}

public function disconnect() {
$this->pdoconn=null;
$this->connected=FALSE;
}

При чтении документации PDO и комментариев на официальном сайте соединение освобождается, когда $ this-> pdoconn = null;
но он прошел через getPDO ().

В соответствии с Эта статья а также это диссертация, где-то может быть переменная, указывающая на соединение, поэтому соединение никогда не освобождается; класс думает, что соединение освобождено, и когда запрос создает новое соединение, теряет последнее для пользователя класса.

Таким образом, идея состоит в том, чтобы вернуть соединение обратно null, также это или есть другой способ защитить pdoconn и заставить быть нулевым.

public function disconnect(&$var) {
$var=null;
$this->pdoconn=null;
$this->connected=FALSE;
}

Другой способ — создать еще один класс wrap, который никогда не выставляет pdo conn и заставляет выполнять запрос внутри него, чтобы управлять также отключением.

1

Решение

Возможно, попробуйте установить соединение и / или класс singletonЗатем он должен сохранить соединение с базой данных, и каждый раз, когда вы используете его, это будет одно и то же соединение. Если вы делаете это таким образом, вам не нужно сосредотачиваться на закрытии соединения каждый раз, когда вы его используете, потому что на странице только одно соединение. Вот простой пример:

class MyClass
{
// You can make the class itself persist to save on resources
private static $obj;
// You can save the connection specifically to reuse it
private static $singleton;
// Return itself to static var
public function __construct()
{
if(!empty(self::$obj)) {
echo 'OLD OBJ<br />';
return self::$obj;
}
echo 'NEW OBJ<br />';
self::$obj = $this;
return self::$obj;
}
// Return connection if already set
public function connect($username = "username",$password = "password",$host = "host",$database = "dbname")
{
if(!empty(self::$singleton)) {
echo 'OLD CONN<br />';
return self::$singleton;
}

try {
self::$singleton = new PDO('mysql:host='.$host.';dbname='.$database.';charset=utf8',$username,$password);
}
catch(PDOException $e) {
die('connection failed');
}
echo 'NEW CONN<br />';
return  self::$singleton;
}
}

Примеры использования:

    // Creates first PDO connection
$database = new MyClass();
$con1 = $database->connect();

function getConnection()
{
// Creates first connection
$database = new MyClass();
return $database->connect();
}

// Won't create a new instance, but rather use the same.
$con2 = getConnection();

Напишет:

NEW OBJ
NEW CONN
OLD OBJ
OLD CONN
1

Другие решения

Вот как я реализовал одноэлементный экземпляр БД, чтобы сохранить постоянное соединение с БД:

class DB implements IConnectInfo {
public static function factory() {
if( self::$_instance === null ) {
self::$_instance = new DB( 'HOST', 'USERNAME', 'PASSWORD', 'DATABASE' );
}

return self::$_instance;
}

protected function __construct( $host, $username, $password, $database ) {
try {
$this->_link = new PDO( "mysql:host={$host};dbname={$database}", $username, $password, array( PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8" ) );
$this->_link->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
$this->_link->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
} catch(PDOException $e) {
$this->_link = null;
die( "ERROR: Could not connect to the database" );
}
}

public function __destruct() {
if ( $this->_hasActiveTransaction ) {
$this->commit();
}
}

final private function __clone() {
}

public function &link() {
return $this->_link;
}

public function beginTransaction() {
if ( $this->_hasActiveTransaction == false ) {
try {
$this->_link->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$this->_link->beginTransaction();
$this->_hasActiveTransaction = true;
return true;
} catch (PDOException $e) {
error_log($e);
die();
return false;
}
}

return true;
}

public function rollBack() {
if( !$this->beginTransaction() ) {
return false;
}

try {
$this->_link->rollBack();
$this->_hasActiveTransaction = false;
return true;
} catch (PDOException $e) {
error_log($e);
return false;
}
}

public function commit() {
if( !$this->beginTransaction() ) {
return false;
}

try {
$this->_link->commit();
$this->_hasActiveTransaction = false;
return true;
} catch (PDOException $e) {
$this->rollBack();
return false;
}

}

private $_hasActiveTransaction = false;
private $_result = null;
private $_link = null;
static private $_instance = null;
}

И тогда я использую это так:

$DB = DB::factory();
$query = "SELECT * FROM myTable";
$stmt = $DB->link()->prepare( $query );
$stmt->execute();
while( $myTableObj = $stmt->fetch( PDO::FETCH_OBJ ) ) {
echo $myTableObj->myField
}
0

По вопросам рекламы [email protected]