Comme vous ne connaissez pas le type (classname) des objets retournés avant de faire la requête, vous ne pouvez pas le spécifier.
Cependant, vous pouvez encapsuler cette logique dans un autre type que vous utilisez comme type de retour, qui peut ensuite renvoyer le type de retour spécifique :
/**
* 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;
}
}
Vous pouvez ensuite utiliser le getConcrete()
fonction sur chaque objet renvoyé pour renvoyer votre type spécifique, votre logique de décision liée au retour de la base de données.
Modifier : Je l'ai changé en une version qui initialisera d'abord les propriétés des objets via unserialize (veuillez tester si cela fonctionne, c'est basé sur l'hypothèse que nous parlons uniquement de propriétés publiques et je ne sais pas si PDO ne fait que les setters ou plus via la réflexion dans le mode que vous utilisez) puis appelle la fonction constructeur. Le constructeur doit être public (et il doit exister) pour que cela fonctionne.
Il est techniquement possible de le rendre également disponible pour les membres privés et protégés, mais cela nécessite une réelle réflexion et nécessite également une analyse des données sérialisées. Cette classe renomme uniquement le nom de la classe, mais pas à l'intérieur des propriétés privées.
Cependant, ce n'est qu'une façon de le faire. Vous n'avez probablement besoin que d'un ->isChild()
ou ->isAdult()
fonction sur votre Person
classe.