DB Objeto passando entre classes singleton, static ou other?

5

Então, estou projetando um sistema de relatórios no trabalho, é meu primeiro projeto escrito em OOP e estou preso na escolha de design para a classe DB. Obviamente, eu só quero criar uma instância da classe DB por sessão / usuário e depois passá-la para cada uma das classes que precisam dela. O que eu não sei qual é a melhor prática para implementar isso. Atualmente tenho código como o seguinte: -

class db
{
    private $user = 'USER';
    private $pass = 'PASS';
    private $tables = array( 'user','report', 'etc...');

    function __construct(){
        //SET UP CONNECTION AND TABLES
    }
};

class report{
function __construct ($params = array(), $db, $user)
 {        
    //Error checking/handling trimed
    //$db is the database object we created
    $this->db = $db;

    //$this->user is the user object for the logged in user
    $this->user = $user;

    $this->reportCreate();
 }

public function setPermission($permissionId = 1)
{
    //Note the $this->db is this the best practise solution?
   $this->db->permission->find($permissionId)

    //Note the $this->user is this the best practise solution?        
    $this->user->checkPermission(1)

    $data=array();
    $this->db->reportpermission->insert($data)
}
};//end report

Eu tenho lido sobre o uso de classes estáticas e acabei de encontrar Singletons (embora elas pareçam já ultrapassadas?), então qual é a melhor prática atual para fazer isso?

    
por Stephen 25.10.2012 / 06:50
fonte

2 respostas

7

Singletons no PHP são completamente inúteis, suas instâncias são criadas quando o script é executado e morrem quando o script termina, independentemente de serem singletons ou não. Isso ocorre por design, o PHP segue uma arquitetura de compartilhamento de nada .

Continue fazendo o que você já faz, ele ainda tem um nome sofisticado: injeção de construtor . Leia sobre injeção de dependência , e se você quiser tornar seu construtor um pouco mais robusto, considere insinuando o tipo :

class report {
    function __construct (array $params = array(), db $db, $user)
    {        
        ....
    }

    ...
}

Leitura adicional:

por 25.10.2012 / 07:08
fonte
1

Eu vejo o que Yannis Rizos está dizendo, mas não é válido no contexto da implementação de um padrão de design no PHP. Sim, eles são de curta duração, o que eu admito limita o uso de "alguns" padrões, mas que não menos o impede de implementá-los, afinal, eles são "conceitos" feitos usando um Paradigma Orientado a Objetos.

O singleton (e outros como factory) SÃO úteis no PHP como qualquer outra linguagem. Singleton é, na verdade, um dos mais usados dentre os muitos padrões e é tão útil em PHP quanto em qualquer outra linguagem, o que me confundiu com a resposta de Yannis Rizos. Então, para o seu próprio bem, eu ignoraria sua ignorância em entender o uso e o propósito dos padrões de design, especialmente no PHP, pois isso irá confundir ainda mais você.

Um singleton significa simplesmente que você só pode criar UMA instância da classe e é isso. Ele tem todos os benefícios usuais do padrão de design, como em qualquer outro idioma (incluindo os que são executados por uma fração de segundo ou por dias a fio - até mesmo scripts PHP podem ser daemonizados e, em seguida, podem ser executados por dias também ).

Você pode implementá-lo desta forma (observe o construtor privado, MUITO importante na prevenção de várias instâncias e observe também a palavra-chave estática usada ao longo do processo):

class db {

    private static $connection = null;

    /**
    * private so it can ONLY be instantiated from within itself and never created outside of the class - this gives you the control you need
    */
    private function __construct(){
        self::$connection = 'connected'; //replace with the actuall connection to the db code
    }

    /**
    * connects to db and creates instance
    */
    public static function get_instance() {

        if (self::$connection === null) {
            return new self();
        }

        return self::$connection;

    }

    /**
    * access the connection
    */
    public function query($query) {
        return mysql_query($query, self::$connection);
    }

    public function __clone() {
        trigger_error('Can not be cloned.', E_USER_ERROR);
    }

    public function __wakeup() {
        trigger_error('Can not be deserialized.', E_USER_ERROR);
    }

}

//first time used, so will create a NEW connection to the db and store it
$db = db::get_instance();
$db->query("SQL QUERY HERE");

//will NOT create a new connection, but instead use the existing one - this is the singleton pattern because you can only use a SINGLE INSTANCE of the object.
$another_connection = db::get_instance();
$db->query("fdsfdsfsd");
    
por 26.10.2012 / 00:57
fonte