PDO :: FETCH_CLASS具有多个类别 [英] PDO::FETCH_CLASS with multiple classes

查看:159
本文介绍了PDO :: FETCH_CLASS具有多个类别的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am trying to turn an query result into classes.

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

这很好用,但是类名myclass取决于列值.

This works quite well however the class name myclass depends on the column values.

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

Is it possible to fetch each row and turn it into a different class depending on the rows values?

用户示例:

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

我希望所有年龄小于21岁的用户成为类child的实例. 年龄大于等于21岁的行应为类adult的实例.

I want to have all users with an age less then 21 to be instances of the class child. Rows with age of 21 and above should be instances of the class adult.

因此,"jon"应该是child的实例. "sue"和"tom"应为adult的实例.

So "jon" should be an instance of child. "sue" and "tom" should be instances of adult.

推荐答案

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

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

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

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

我将其更改为一个版本,该版本将首先通过反序列化来初始化对象属性(请测试是否可行,它基于我们仅在谈论公共属性的假设,而我不知道PDO是否只是在您使用的模式下通过反射来执行setter或更多操作),然后调用构造函数.构造函数必须是公共的(并且必须存在),这样才能起作用.

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.

但是,这只是这样做的一种方法.您可能只需要在Person类上使用->isChild()->isAdult()函数.

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

这篇关于PDO :: FETCH_CLASS具有多个类别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆