PDO::FETCH_CLASS 具有多个类

2024-01-20

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

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

这工作得很好,但是类名myclass取决于列值。

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


用户示例:

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

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

所以“乔恩”应该是一个实例child。 “sue”和“tom”应该是实例adult.


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

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

/**
 * 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()函数对每个返回的对象返回您的特定类型,将您的决策逻辑绑定到数据库返回。

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

从技术上讲,也可以将其提供给私有成员和受保护成员,但这需要真正的反思,并且还需要解析序列化数据。该类仅重命名类名,但不会重命名私有属性内部。

然而,这只是这样做的一种方法。你可能只需要一个->isChild() or ->isAdult()功能在你的Person class.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

PDO::FETCH_CLASS 具有多个类 的相关文章