Доступ к нескольким схемам, используя паттерн Singleton


У меня ситуация, когда я должен подключиться к нескольким схемы для заполнения одной страницы.

Я изменил наш синглтон класса DB в том, чтобы помочь мне сделать это.

Теперь он будет уничтожать и вновь заявить о себе, когда мы проходим новый набор БД учетных данных.

Будет ли в PHP плюсы сознания-рецензирование? мы не имеем здесь комментарии код и это довольно большие изменения, как это повлияет на почти все в нашей системе, так что я надеялся, что кто-то здесь может дать мне вторую пару глаз...

Я немного дрожат на destroy() метод, может быть лучше для этого?

<?PHP
Class DB{
private static $instance;   //instance of db.
private $cursor;            //connection cursor
private $db_user;           //db username
private $db_pass;           //db password
private $db_sid;            //schema id
/**
* not allowed to publicly create this. Should be called ONLY from self::get_instance.
* Should be the ONLY place where db cursor is set.
*
* @see self::get_instance($db_user, $db_pass, $db_sid);
*/

private function __construct($db_user, $db_pass, $db_sid){
    $this->db_user = $db_user ? $db_user : DATABASE_USER;
    $this->db_pass = $db_pass ? $db_pass : DATABASE_PASS;
    $this->db_sid = $db_sid ? $db_sid : DATABASE_SID;
    $this->get_cursor();
}

/*
* not allowed to publicly clone this.
*/
public final function __clone(){}


/*
* retrieves the db connection.
*/
private function get_cursor(){
    if(isset($this->cursor)){
        return true;
    }

    $this->cursor = oci_pconnect($this->db_user, $this->db_pass, $this->db_sid);
    if($this->cursor == false){
        throw new exception__DBException();
        return false;
    }
    return true;
}


/**
* THE ONLY PUBLIC METHOD FOR GRABBING DB INSTANCE.
* Will automatically self destruct and reconnect with a new connection if new db_user/db_pass@db_sid is passed.
*
* @param string $db_user
* @param string $db_pass
* @param string $db_sid
* @return db the DB instance.
*
*/
public static function get_instance($db_user, $db_pass, $db_sid){

    /*
    We check if the instance is declared. If not declared we simply create a new DB instance and return.
    */
    if(!(self::$instance instanceof DB)){
        self::$instance = new DB($db_user, $db_pass, $db_sid);
        return self::$instance;
    }


    /*
    If we're here, there must be a db instance already declared. We will check if that instance have the same user/pass@sid as the function params.
    If not, it means we want to connect to a different DB. We destroy previous connection and reset instance again with new credential.
    Else we proceed as normal (return instance w/o doing anything).
    */

    if((self::$instance->get_user() !== $db_user) ||
        (self::$instance->get_pass() !== $db_pass) ||
        (self::$instance->get_sid() !== $db_sid)){

        self::$instance->destroy();
        self::$instance = new DB($db_user, $db_pass, $db_sid);
    }

    return self::$instance;
}

//unsets cursor, frees resource.
private function destroy(){
    if(isset($this->cursor)){
        oci_close($this->cursor);
        unset($this->cursor);
    }
}

//getters
public function get_user(){
    return $this->db_user;
}

public function get_pass(){
    return $this->db_pass;
}

public function get_sid(){
    return $this->db_sid;
}

/**
* executes the sql statement.
* @param string $statement
* @return the result.
*
*/

public function execute_query($statement){
    $rows_returned = 0;
    $result_set = array();

    $stmt = oci_parse($this->cursor, $statement);
    ocisetprefetch($stmt, 10000);
    if(oci_execute($stmt)){
        while($result = oci_fetch_array($stmt, OCI_ASSOC + OCI_RETURN_NULLS)){
            $rows_returned += 1;
            $result = array_change_key_case($result, CASE_LOWER);
            $result_set[] = $result;
        }
    }else{
        throw new exception__DBException(...);
    }
    return $result_set;
}

    /**
* executes the sql statement with binding vars.
* @param string $statement SQL statement
    * @param array $variables looks like array[binding_key]=variable.
* @return the result.
*/

public function execute_query_by_bind($statement, $variables){
    $rows_returned = 0;
    $result_set = array();
    $stmt = oci_parse($this->cursor, $statement);

    if(is_array($variables)){
        foreach($variables as $key => $value){
            oci_bind_by_name($stmt, ':'.$key, $variables[$key]);
        }
    }

    ocisetprefetch($stmt, 10000);

    if (oci_execute($stmt)){
        while($result = oci_fetch_array($stmt, OCI_ASSOC + OCI_RETURN_NULLS)){
            $rows_returned += 1;
            $result = array_change_key_case($result, CASE_LOWER);
            $result_set[] = $result;
        }
        oci_free_statement($stmt);
    }else{
        throw new exception__DBException();
    }
    return $result_set;
}
}
?>


472
4
задан 11 июля 2011 в 10:07 Источник Поделиться
Комментарии
1 ответ

Я не уверен, если я должен согласиться с идеей разрушения Синглтона и воссоздать связь с другими учетными данными. Возможно, есть конкретный случай для этого, что вы имеете в виду, но я бы лично не хотела этого делать.

Я как-то решена проблема, которая мне кажется похожа на вашу. Приложение было одноэлементный объект, контролируемый доступ к базе данных, аналогично свою анкету прямо сейчас. Мы получили новое требование о том, что участвует нам сделать новое подключение к базе данных учет на другого хозяина. Я просто добавил новый метод геттер называется getAccountsConnection(), которая возвращает экземпляр базы данных, который вел себя подобным образом с другими учетными данными.

Теперь, я не уверен, что вы бы обязательно назвал это "синглтон", но я чувствовал, что это было очень правильное решение вопроса, и насколько я знаю, это все еще внутри польза сегодня. Важная вещь, чтобы отметить здесь заключается в том, что два соединения будет существовать в то же время, когда они были призваны, и поведение нашего слоя базы данных на самом деле не подключиться, пока соединение не требуется.

1
ответ дан 12 июля 2011 в 06:07 Источник Поделиться