2016-02-06 1 views
1

Я новичок в PHP высоком уровне. Но не новичок в программировании.PDO disconnect и ссылка на переменную PHP

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

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

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().

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

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

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

Другим способ заключается в создании класса обруча соседнего, который никогда не подвергать PDO соед и силу для выполнения запроса внутри него, чтобы управлять и разъединением.

+0

Что о наличии статической переменной (Singleton), назначаемые соединение. Почти то, что у вас есть сейчас, но статическое, поэтому оно повторяет одно и то же соединение, потому что статичность будет сохраняться без создания новых соединений. – Rasclatt

+0

Оба решения очень интересны. Я не знаю, какой из них проголосовать. – user1594895

+0

Попробуйте один из них и посмотрите, разрешается ли ваша загрузка базы данных. – Rasclatt

ответ

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 
0

Это, как я реализовал одноплодной DB экземпляра к поддерживать постоянное соединение БД:

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 
}