PDO :: FETCH_CLASS具有多个类

时间:2011-10-12 14:23:26

标签: php mysql pdo

我正在尝试将查询结果转换为类。

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

这很有效,但是类名myclass取决于列值。

是否可以获取每一行并根据行值将其转换为不同的类?


用户示例:

ID # name # age
1  # jon  # 12
2  # sue  # 23
3  # tom  # 24

我想让所有年龄小于21岁的用户成为班级child的实例。 年龄为21岁及以上的行应为班级adult的实例。

所以“jon”应该是child的一个实例。 “sue”和“tom”应该是adult的实例。

4 个答案:

答案 0 :(得分:1)

由于在执行查询之前不知道返回对象的类型(类名),因此无法指定它。

但是,您可以将该逻辑封装在您用作返回类型的另一个类型中,然后可以返回特定的返回类型:

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

然后,您可以在每个返回的对象上使用getConcrete()函数返回您的特定类型,您的决策逻辑绑定到数据库返回。

编辑:我将其更改为首先通过反序列化初始化对象属性的版本(请测试是否有效,这是基于我们只讨论公共属性的假设而我不知道PDO是否只通过你正在使用的模式中的反射来完成setter或更多,然后调用构造函数。构造函数需要是公共的(并且它必须存在)才能生效。

技术上可以使私有和受保护成员也可以使用它,但是这需要真正的反映,并且它也需要解析序列化数据。该类仅重命名类名,但不重命名私有属性。

然而,这只是这样做的一种方式。您可能只需要在->isChild()课程中使用->isAdult()Person功能。

答案 1 :(得分:0)

这不能自动完成,它太具体了。您可以遍历每一行并使用适当的参数实例化正确的类。

答案 2 :(得分:0)

我不会使用PDO :: FETCH_CLASS。 您可以根据年龄值

更改SQL以返回类名
SELECT 
id,
name,
age,
CASE WHEN age < 21 THEN 'child'
ELSE 'adult' END
AS class_name
FROM SOME_TABLE";

Then use your PDO::FETCH_ASSOC as fetch type
Then when you loop over your results
you can easily instantiave class based on
$result['class_name'] like this:
$class = $result['class_name'];
$obj = new $class;

答案 3 :(得分:0)

我认为最好的答案就在这里。

How to use PDO::FETCH_CLASS with abstract class?