Mysql
 sql >> Database >  >> RDS >> Mysql

PDO::FETCH_CLASS con più classi

Poiché non conosci il tipo (nome classe) degli oggetti restituiti prima di eseguire la query, non puoi specificarlo.

Tuttavia, puoi incapsulare quella logica all'interno di un altro tipo che usi come tipo restituito che può quindi restituire il tipo restituito specifico:

/**
 * 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;
    }
}

È quindi possibile utilizzare getConcrete() funzione su ogni oggetto restituito per restituire il tuo tipo specifico, la tua logica decisionale legata alla restituzione del database.

Modifica: L'ho cambiato in una versione che inizializzerà prima le proprietà degli oggetti tramite unserialize (per favore prova se funziona, si basa sul presupposto che stiamo parlando solo di proprietà pubbliche e non so se PDO fa solo i setter o più tramite riflessione nella modalità in uso) e quindi chiama la funzione di costruzione. Il costruttore deve essere pubblico (e deve esistere) affinché funzioni.

È tecnicamente possibile renderlo disponibile anche per i membri privati ​​e protetti, tuttavia ciò richiede una riflessione reale e anche l'analisi dei dati serializzati. Questa classe rinomina solo il nome della classe, ma non all'interno delle proprietà private.

Tuttavia questo è solo un modo per farlo. Probabilmente hai solo bisogno di un ->isChild() o ->isAdult() funzione sulla tua Person classe.