Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

PDO::FETCH_CLASS com várias classes


Como você não sabe o tipo (classname) dos objetos retornados antes de fazer a consulta, não pode especificá-lo.

No entanto, você pode encapsular essa lógica dentro de outro tipo que você usa como tipo de retorno que pode retornar o tipo de retorno específico:
/**
 * Should not have any private, public or protected members in it's definition.
 * 
 * Does only work for public properties.
 */
class ReturnObject {
    public function getConcrete()
    {
        /* decide here which class */
       $classname = 'Child'; // or 'Adult'

       return $this->selfAs($classname);
    }

    private function selfAs($classname)
    {
        $l = strlen(__CLASS__);
        $s = sprintf('O:%d:"%s"', strlen($classname), $classname).substr(serialize($this), 5+strlen($l)+$l);
        $instance = unserialize($s);
        $instance->__construct();
        return $instance;
    }
}

Você pode então usar o getConcrete() função em cada objeto retornado para retornar seu tipo específico, sua lógica de decisão vinculada ao retorno do banco de dados.

Editar: Eu mudei para uma versão que inicializará primeiro as propriedades dos objetos via unserialize (por favor, teste se isso funciona, é baseado na suposição de que estamos falando apenas de propriedades públicas e não sei se o PDO apenas faz os setters ou mais via reflexão no modo que você está usando) e, em seguida, chama a função construtora. O construtor precisa ser público (e deve existir) para que isso funcione.

É tecnicamente possível disponibilizar isso também para membros privados e protegidos, no entanto, isso precisa de reflexão real e também precisa de análise dos dados serializados. Esta classe apenas renomeia o nome da classe, mas não dentro de propriedades privadas.

No entanto, esta é apenas uma maneira de fazê-lo. Você provavelmente só precisa de um ->isChild() ou ->isAdult() função em sua Person classe.