PDO::FETCH_CLASS with multiple classes

后端 未结 4 1295
春和景丽
春和景丽 2021-01-29 02:35

I am trying to turn an query result into classes.

$result->setFetchMode(PDO::FETCH_CLASS, \'myclass\', array());

This works quite well howev

4条回答
  •  醉梦人生
    2021-01-29 03:19

    As you do not know the type (classname) of the returned objects before you do the query, you can not specify it.

    However, you could encapsulate that logic inside another type you use as return type which can then return the specific return type:

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

    You can then use the getConcrete() function on each returned object to return your specific type, your decision logic bound to the database return.

    Edit: I changed it into a version that will first initialize the objects properties via unserialize (please test if this works, it's based on the assumption that we're talking about public properties only and I don't know if PDO just does the setters or more via reflection in the mode you're using) and then calls the constructor function. The constructor needs to be public (and it must exist) so that this works.

    It's technically possible to make this available for private and protected members as well, however this needs real reflection and it as well needs parsing of the serialized data as well. This class only renames the classname, but not inside private properties.

    However this is only one way for doing so. You probably only need a ->isChild() or ->isAdult() function on your Person class.

提交回复
热议问题