gpt4 book ai didi

php - 制作我自己的(非数据库)fetch_object 函数

转载 作者:搜寻专家 更新时间:2023-10-31 21:45:34 25 4
gpt4 key购买 nike

在 php mysql/mysqli/postgre/etc... 中有 fetch_object 函数,您可以在其中获取数据行的对象。默认情况下,它将返回一个 stdClass 的对象,但您也可以为构造函数定义一个类名和一个参数数组。

我想用一组简单的值做同样的事情。最好在调用构造函数之前设置对象的属性,这与数据库函数显示的行为相同。然而,这似乎是不可能的。

甚至创建具有属性集的对象的唯一方法似乎是 unserialize a preconstructed string .但该示例仍会创建一个新对象,然后从未序列化的对象设置该对象的属性以确保调用构造函数。但这意味着在设置属性之前调用构造函数。

简而言之:我想要以下内容:

array_fetch_object(数组 $properties,字符串 $class_name [,数组 $params ])

在设置属性后调用构造函数。

最佳答案

最后,我编写了以下类,它使用反序列化伪造的字符串来执行任务。它使用反射来确定属性的访问类型是什么以及构造函数的名称是什么(如果有的话)。

类的核心是下面这行:

$object = unserialize('O:'.strlen($class_name).':"'.$class_name.'"'.substr(serialize($properties), 1));

序列化属性数组并将序列化的重命名为所需的类名。

class ObjectFactory {

private $properties;
private $constructors;

public function __construct() {
$this->properties = array();
$this->constructors = array();
}

private function setClass($class_name) {

$class = new ReflectionClass($class_name);
$this->properties[$class_name] = array();

foreach($class->getProperties() as $property) {

$name = $property->getName();
$modifier = $property->getModifiers();

if($modifier & ReflectionProperty::IS_STATIC) {
continue;
} else if($modifier & ReflectionProperty::IS_PUBLIC) {
$this->properties[$class_name][$name] = $name;
} else if($modifier & ReflectionProperty::IS_PROTECTED) {
$this->properties[$class_name][$name] = "\0*\0".$name; // prefix * with \0's unserializes to protected property
} else if($modifier & ReflectionProperty::IS_PRIVATE) {
$this->properties[$class_name][$name] = "\0".$class_name."\0".$name; // prefix class_name with \0's unserializes to private property
}
}

if($constructor = $class->getConstructor()) {
$this->constructors[$class_name] = $constructor->getName();
}
}

private function hasClassSet($class_name) {

return array_key_exists($class_name, $this->properties);
}

private function hasClassProperty($class_name, $property_name) {

if(!$this->hasClassSet($class_name))
$this->setClass($class_name);

return array_key_exists($property_name, $this->properties[$class_name]);
}

private function getClassProperty($class_name, $property_name) {

if(!$this->hasClassProperty($class_name, $property_name))
return false;

return $this->properties[$class_name][$property_name];
}

private function hasClassConstructor($class_name) {

if(!$this->hasClassSet($class_name))
$this->setClass($class_name);

return $this->constructors[$class_name] !== false;
}

private function getClassConstructor($class_name) {

if(!$this->hasClassConstructor($class_name))
return false;

return $this->constructors[$class_name];
}

public function fetch_object(array $assoc, $class_name = 'stdClass', array $params = array()) {

$properties = array();

foreach($assoc as $key => $value) {
if($property = $this->getClassProperty($class_name, $key)) {
$properties[$property] = $value;
}
}

$object = unserialize('O:'.strlen($class_name).':"'.$class_name.'"'.substr(serialize($properties), 1));

if($constructor = $this->getClassConstructor($class_name)) {
call_user_func_array(array($object, $constructor), $params);
}

return $object;
}
}

关于php - 制作我自己的(非数据库)fetch_object 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4424530/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com