从发布的数据创建对象实例-PHP
从表单传入的值创建和填充对象的最佳方法是什么 例如,如果我有一辆带有属性颜色、型号、品牌、年份和方法保存的class Car,它将插入或更新记录 然后,我有一个表单,其中包含所有这些值的字段,并将其提交。我想用发布的值创建一个类Car的实例,然后调用Save方法。一切都很好 但是,将发布的值指定给对象内部属性的最佳方式是什么。假设这是一个简化的场景,而实际情况会有更多的属性,使得单个集合调用变得冗长 是否最好只为每个方法调用Set方法?或者将数组传递给方法(或构造函数),然后该方法调用Set方法?还是其他方式 任何关于最佳实践的建议都将不胜感激 干杯从发布的数据创建对象实例-PHP,php,oop,Php,Oop,从表单传入的值创建和填充对象的最佳方法是什么 例如,如果我有一辆带有属性颜色、型号、品牌、年份和方法保存的class Car,它将插入或更新记录 然后,我有一个表单,其中包含所有这些值的字段,并将其提交。我想用发布的值创建一个类Car的实例,然后调用Save方法。一切都很好 但是,将发布的值指定给对象内部属性的最佳方式是什么。假设这是一个简化的场景,而实际情况会有更多的属性,使得单个集合调用变得冗长 是否最好只为每个方法调用Set方法?或者将数组传递给方法(或构造函数),然后该方法调用Set方法
斯图尔特我将实现这个神奇的功能,因为它正是为这个用例而设计的。将实现应用到该方法中有多种好处:
class A {
private $member = 1000;
public static function test(A $a) {
echo $a->member;
}
}
echo A::test(new A()); // outputs 1000
编辑满足评论中的另一个请求:
class A {
private $member = 1000;
public static function test(A $a) {
echo $a->member;
}
}
echo A::test(new A()); // outputs 1000
除非您使用的是PHP5.3,其中引入了必需的特性(),否则您无法知道在哪个类上调用了静态方法。您可以通过分析当前堆栈(使用)来模拟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;
}
}
如果属性是公共的:
foreach($_POST as $key => $value)
$obj->$key = $value;
如果需要设置器:
foreach($_POST as $key => $value) {
$set = 'Set' . $key;
$obj->$set($value);
}
好吧,你可以一步把post数组转换成一个对象
$mypostobject = (object) $_POST;
echo $mypostobject->Colour;
编辑:添加了到PHP文档的链接
如果您想对自己的对象类执行此操作,那么需要某种构造函数或函数来获取post数组并设置您的类
class MyCar {
public function __construct($postdata)
{
$this->Colour = $postdata['Colour'];
// etc
}
};
$car = new MyCar($_POST);
创建一个将接受所有属性的构造函数
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
}
请务必事先对您的输入进行消毒/验证!(不能经常强调这一点)你可以使用一些魔法:
您可以在基类中实现此方法,并使所有yout对象继承自该基类,这样您就可以在每个对象中使用此功能,而无需在任何类中重复自己的操作。如果您发布的对象将来可能变得比单一属性列表更复杂(将嵌套、数组视为值等),您可以首先在客户端创建一个JavaScript对象,并将其作为JSON发布到单个参数中。然后,您可以简单地将JSON字符串反序列化为PHP对象。PHP5+内置了对JSON反序列化的支持。使用JSON可以让您灵活地了解对象的复杂程度。我认为此方法的实现将与上面Chaos的建议(接近)完全相同吗?是的,实现将是相同的。扩展的答案解释了我为什么建议这种方法。你确定你可以访问私人成员吗__set_state应该是静态函数,$这里没有定义,而是创建一个新的对象实例,然后给它分配变量。因此,请解释如何从函数中访问私有变量?
private
成员可以从定义它们的类中的任何地方访问,如果需要,您可以编写一些测试代码。您无法访问的唯一私有成员是继承的成员。不能从静态uuu set_state函数访问私有成员,因为$this不存在于静态方法中。我敢说你要写一些测试代码来证明我是错的。我曾经考虑过这种方法,但是当你(潜在地)处理很多属性时,这会变得非常混乱。