Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/264.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 创建我自己的(非数据库)fetch_对象函数_Php_Oop - Fatal编程技术网

Php 创建我自己的(非数据库)fetch_对象函数

Php 创建我自己的(非数据库)fetch_对象函数,php,oop,Php,Oop,在php mysql/mysqli/postgre/etc中。。。有fetch_object函数,您可以在其中为数据行获取对象。默认情况下,它将返回一个对象stdClass,但您也可以为构造函数定义一个类名和一个参数数组 我想用一组简单的值做同样的事情。最好在调用构造函数之前设置对象的属性,这与数据库函数显示的行为相同。然而,这似乎是不可能的 创建属性设置为的对象的唯一方法似乎是。但该示例仍然会创建一个新对象,然后从未序列化的对象设置该对象的属性,以确保调用构造函数。但这意味着在设置属性之前调用

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

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

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

简言之,我希望:

array\u fetch\u对象(array$properties,string$class\u name[,array$params])


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

您可以将数组强制转换为对象,如下所示:

$array = array('a' => 'a', 'b' => 'c');
$object = (object) $array;
或者只是:

$object = (object) array('a' => 'a', 'b' => 'c');

这将为您提供一个具有数组属性的stdClass对象。

好的,我没想到这会起作用,但它确实:

class TestObject {

    public $property;
    public $preset;

    public function __construct($param) {

        $this->property = $param;
    }
}

$object = unserialize('O:10:"TestObject":1:{s:6:"preset";i:1;}');
$object->__construct(1);

print_r($object);
结果:

TestObject Object
(
    [property] => 1
    [preset] => 1
)

我只需要在创建序列化字符串之前检查属性的访问类型,因为私有属性的类名是在前面加上的。然而,调用一个已经构造的对象的构造函数会继续工作吗?

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

课程的核心是以下几行:

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

有什么理由不能直接使用
new
$x=new$class($argument)
在调用构造函数之前不会设置属性,并且无法设置私有属性。这将导致stdClass的对象,该对象没有任何类似于通过传递$class\u名称获取的对象的方法。我想要一个特定类的对象。好的,我的另一个答案是使用各种各样的东西,你甚至不能在PHP中做。很抱歉。我很想看看你有什么想法。你能加入一个自定义类吗?我没有安装PHP,所以我不能尝试。不,你不能。另请参见此处:、此处:和此讨论:。