首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >你能在PHP中动态创建实例属性吗?

你能在PHP中动态创建实例属性吗?
EN

Stack Overflow用户
提问于 2009-05-06 14:17:40
回答 9查看 59.8K关注 0票数 59

有没有办法动态创建所有实例属性?例如,我希望能够在构造函数中生成所有属性,并且在类被实例化后仍然能够访问它们:$object->property。注意,我想单独访问属性,而不是使用数组;下面是我不想要的示例:

代码语言:javascript
复制
class Thing {
    public $properties;
    function __construct(array $props=array()) {
        $this->properties = $props;
    }
}
$foo = new Thing(array('bar' => 'baz');
# I don't want to have to do this:
$foo->properties['bar'];
# I want to do this:
//$foo->bar;

更具体地说,当我处理具有大量属性的类时,我希望能够选择数据库中的所有列(表示属性)并从它们创建实例属性。每个列值都应存储在单独的实例属性中。

EN

回答 9

Stack Overflow用户

发布于 2009-05-06 14:29:18

您可以使用实例变量作为任意值的持有者,然后使用__get魔术方法将它们作为常规属性进行检索:

代码语言:javascript
复制
class My_Class
{
    private $_properties = array();

    public function __construct(Array $hash)
    {
         $this->_properties = $hash;
    }

    public function __get($name)
    {
         if (array_key_exists($name, $this->_properties)) {
             return $this->_properties[$name];
         }
         return null;
    }
}
票数 7
EN

Stack Overflow用户

发布于 2012-06-13 16:13:35

为什么每个例子都这么复杂?

代码语言:javascript
复制
<?php namespace example;

error_reporting(E_ALL | E_STRICT); 

class Foo
{
    // class completely empty
}

$testcase = new Foo();
$testcase->example = 'Dynamic property';
echo $testcase->example;
票数 6
EN

Stack Overflow用户

发布于 2010-06-30 19:40:37

下面是一个简单的函数,用于填充对象成员,而不使类成员成为公共成员。它还将构造函数留给您自己使用,在不调用构造函数的情况下创建新的对象实例!因此,您的域对象不依赖于数据库!

代码语言:javascript
复制
/**
 * Create new instance of a specified class and populate it with given data.
 *
 * @param string $className
 * @param array $data  e.g. array(columnName => value, ..)
 * @param array $mappings  Map column name to class field name, e.g. array(columnName => fieldName)
 * @return object  Populated instance of $className
 */
function createEntity($className, array $data, $mappings = array())
{
    $reflClass = new ReflectionClass($className);
    // Creates a new instance of a given class, without invoking the constructor.
    $entity = unserialize(sprintf('O:%d:"%s":0:{}', strlen($className), $className));
    foreach ($data as $column => $value)
    {
        // translate column name to an entity field name
        $field = isset($mappings[$column]) ? $mappings[$column] : $column;
        if ($reflClass->hasProperty($field))
        {
            $reflProp = $reflClass->getProperty($field);
            $reflProp->setAccessible(true);
            $reflProp->setValue($entity, $value);
        }
    }
    return $entity;
}

/******** And here is example ********/

/**
 * Your domain class without any database specific code!
 */
class Employee
{
    // Class members are not accessible for outside world
    protected $id;
    protected $name;
    protected $email;

    // Constructor will not be called by createEntity, it yours!
    public function  __construct($name, $email)
    {
        $this->name = $name;
        $this->emai = $email;
    }

    public function getId()
    {
        return $this->id;
    }

    public function getName()
    {
        return $this->name;
    }

    public function getEmail()
    {
        return $this->email;
    }
}


$row = array('employee_id' => '1', 'name' => 'John Galt', 'email' => 'john.galt@whoisjohngalt.com');
$mappings = array('employee_id' => 'id'); // Employee has id field, so we add translation for it
$john = createEntity('Employee', $row, $mappings);

print $john->getName(); // John Galt
print $john->getEmail(); // john.galt@whoisjohngalt.com
//...

从对象中检索数据是相似的,例如使用$reflProp>setValue($entity,$value);另外,这个函数很大程度上受到了Doctrine2 ORM的启发,太棒了!

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/829823

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档