我正在尝试将查询结果转换为类。
$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
的实例。
答案 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)
我认为最好的答案就在这里。