从发布数据创建对象实例 - PHP

时间:2009-09-16 11:50:44

标签: php oop

从表单传入的值创建和填充Object的最佳方法是什么?

例如,如果我有一个Car类,其中包含Color,Model,Make,Year和Save方法,它将插入或更新记录。

然后我有一个表单,其中包含所有这些值的字段,并且已提交。我想创建一个带有已发布值的类Car的实例,然后调用Save方法。一切都很好。

但是,将过帐值分配给对象内部属性的最佳方法是什么。假设这是一个简化的场景,实际情况会有更多的属性,使得单个Set调用啰嗦。

最好是简单地为每个人调用Set方法吗?或者将数组传递给方法(或构造函数),然后调用Set方法?或者其他一些方式?

赞赏有关最佳做法的任何建议

干杯 斯图尔特

6 个答案:

答案 0 :(得分:6)

你可以使用一点Reflection魔法:

public function loadFromArray($array) {
    $class = new ReflectionClass(get_class($this));
    $props = $class->getProperties();
    foreach($props as $p) {
         if (isset($array[$p->getName()])
              $p->setValue($this, $array[$p->getName]);
    }
}

您可以在基类中实现此方法,并使所有对象继承自该对象,因此您可以在每个对象中使用此功能,而无需在任何类中重复自己。

答案 1 :(得分:4)

如果属性是公开的:

foreach($_POST as $key => $value)
    $obj->$key = $value;

如果他们需要制定者:

foreach($_POST as $key => $value) {
    $set = 'Set' . $key;
    $obj->$set($value);
}

答案 2 :(得分:2)

我会实现魔术函数__set_state() ,因为它仅用于此用例。将实现放入该方法有多种好处:

  1. 它的定义非常明确,这个函数做了什么(它在PHP文档中定义,与您自己的源代码形成对比)
  2. 您可以访问功能
  3. 中的私人会员
  4. 使用此功能将自动重建使用var_export()转储的对象。
  5. 编辑根据评论中的要求:

    class A {
        private $member = 1000;
        public static function test(A $a) {
            echo $a->member;
        }
    }
    echo A::test(new A()); // outputs 1000
    

    编辑从评论中填写另一个请求:

    除非您使用的是php 5.3,否则您无法知道调用静态方法的类,其中引入了所需的功能(late static binding)。您可以通过分析当前堆栈(使用debug_backtrace())来模拟get_called_class()。如果您有一个有效的get_called_class()功能,则可以执行以下操作:

    class BaseClass {
        public static function __set_state($state) {
            $class = get_called_class();
            // Assumption: Constructor can be invoked without parameters!
            $object = new $class();
            foreach (get_class_vars($class) as $member) {
                if (!isset($state[$member])) {
                    // Member was not provided, you can choose to ignore this case
                    throw new Exception("$class::$member was not provided");
                } else {
                    // Set member directly
                    // Assumption: members are all public or protected
                    $object->$member = $state[$member];
                    // Or use the setter-approach given by Chaos.
                    $setter = 'set' . ucfirst($member);
                    $object->setter($state[$member]);
                }
            }
            return $object;
        }
    }
    

答案 3 :(得分:1)

好吧,你可以一步将post数组转换为一个对象......

$mypostobject = (object) $_POST;
echo $mypostobject->Colour;

编辑:添加了指向PHP文档的链接。 http://uk.php.net/manual/en/language.types.object.php

如果你想用你自己的对象类做这个,那么接受post数组和设置你的类的某种构造函数或函数将是有序的。

class MyCar {
  public function __construct($postdata) 
  {
    $this->Colour = $postdata['Colour'];
    // etc
  }
};

$car = new MyCar($_POST);

答案 4 :(得分:1)

如果您发布的对象可能会比以后的平面属性列表更复杂(想想嵌套,数组作为值等),您可以先在客户端创建一个JavaScript对象并发布它作为单个参数内的JSON。然后,您可以简单地将JSON字符串反序列化为PHP对象。 PHP 5+内置了对JSON反序列化的支持。使用JSON可以灵活处理对象的复杂程度。

答案 5 :(得分:0)

创建一个构造函数,它将获取所有属性

class Car {
  // private members …
  public function __construct($color, $type, $model, $make) {
    // assign your values here
  }
  // other methods
};

如果您正在处理关联数组,您还可以使用带数组的构造函数作为参数:

public function __construct($car_properties) {}

然后使用

循环您的属性
foreach($car_properties as $property => $value) {
  if(isset($value)) $this->property = $value
}

请务必事先清理/验证您的输入! (经常不能强调这一点)