从表单传入的值创建和填充Object的最佳方法是什么?
例如,如果我有一个Car类,其中包含Color,Model,Make,Year和Save方法,它将插入或更新记录。
然后我有一个表单,其中包含所有这些值的字段,并且已提交。我想创建一个带有已发布值的类Car的实例,然后调用Save方法。一切都很好。
但是,将过帐值分配给对象内部属性的最佳方法是什么。假设这是一个简化的场景,实际情况会有更多的属性,使得单个Set调用啰嗦。
最好是简单地为每个人调用Set方法吗?或者将数组传递给方法(或构造函数),然后调用Set方法?或者其他一些方式?
赞赏有关最佳做法的任何建议
干杯 斯图尔特
答案 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()
,因为它仅用于此用例。将实现放入该方法有多种好处:
var_export()
转储的对象。编辑根据评论中的要求:
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
}
请务必事先清理/验证您的输入! (经常不能强调这一点)