如何在PHP中投射对象

我有一些分享一些属性的clases,我想做一些事情:$ dog =(Dog)$ cat;

这是可行的,还是有任何通用的工作?

它不是一个超类,或者一个接口或者任何相关的。 他们只是2个不同的分类,我想php将猫类的属性映射到狗,给我新的对象。 –

我想我应该指出一点点,因为这似乎是一个毫无意义的事情。

从inheritance父类的inheritanceinheritance树造成一个基于保存方法的inheritance树,也许我从开始不好,但问题是,我有很多实际上是平等的,但与mysql和另一个相互作用的clases与XML文件。 所以我有︰类MySql_SomeEntity扩展SomeMysqlInteract {}和Xml_SomeEntity扩展SomeXmlInteract {}它的一点点深层树,但问题是这样的。 我不能让它们从同一个类inheritance,因为多重inheritance是不允许的,我不能将当前的交互与superclases分开,因此会是一个很大的麻烦。

基本上每个人的属性都是相同的。

因为我有很多这个maching clases我想做一些通用的铸造或类似的东西,可以转换(传递给每个属性的值),但即时通讯设法search最简单的方法,这个clases的每个人。

PHP中没有内置的用户定义对象的types转换方法。 这就是说,这里有几个可能的解决scheme:

1)使用类似下面的函数反序列化对象,修改string,以便在需要反序列化的新对象中包含所需的属性。

 function cast($obj, $to_class) { if(class_exists($to_class)) { $obj_in = serialize($obj); $obj_out = 'O:' . strlen($to_class) . ':"' . $to_class . '":' . substr($obj_in, $obj_in[2] + 7); return unserialize($obj_out); } else return false; } 

2)或者,您可以使用reflection/手动迭代全部或使用get_object_vars()来复制对象的属性。

本文应该对“PHP的黑暗angular落”进行启发,并在用户级别上实现types转换。

你可以使用上面的函数来转换不类似的类对象(PHP> = 5.3)

 /** * Class casting * * @param string|object $destination * @param object $sourceObject * @return object */ function cast($destination, $sourceObject) { if (is_string($destination)) { $destination = new $destination(); } $sourceReflection = new ReflectionObject($sourceObject); $destinationReflection = new ReflectionObject($destination); $sourceProperties = $sourceReflection->getProperties(); foreach ($sourceProperties as $sourceProperty) { $sourceProperty->setAccessible(true); $name = $sourceProperty->getName(); $value = $sourceProperty->getValue($sourceObject); if ($destinationReflection->hasProperty($name)) { $propDest = $destinationReflection->getProperty($name); $propDest->setAccessible(true); $propDest->setValue($destination,$value); } else { $destination->$name = $value; } } return $destination; } 

例:

 class A { private $_x; } class B { public $_x; } $a = new A(); $b = new B(); $x = cast('A',$b); $x = cast('B',$a); 

没有使用inheritance(正如作者所提到的 ),似乎你正在寻找一个解决scheme,可以transform一个类transform为另一个类, 并假设开发者知道并理解了两个类的相似性

目前还没有用于在对象之间转换的解决scheme。 你可以尝试的是:

  • get_object_vars() :将对象转换为数组
  • 强制转换为对象 :将数组转换为对象

这听起来像你真正想要做的是实现一个接口 。

您的接口将指定对象可以处理的方法,并且当您将实现接口的对象传递给需要支持该接口的对象的方法时,只需使用该接口的名称input参数即可。

你不需要铸造。 一切都是dynamic的。

我有一个class的折扣。
我有几个类来扩展这个类:
ProductDiscount
StoreDiscount
ShippingDiscount

在代码的某处我有:

 $pd = new ProductDiscount(); $pd->setDiscount(5, ProductDiscount::PRODUCT_DISCOUNT_PERCENT); $pd->setProductId(1); $this->discounts[] = $pd; ..... $sd = new StoreDiscount(); $sd->setDiscount(5, StoreDiscount::STORE_DISCOUNT_PERCENT); $sd->setStoreId(1); $this->discounts[] = $sd; 

我有一个地方

 foreach ($this->discounts as $discount){ if ($discount->getDiscountType()==Discount::DISCOUNT_TYPE_PRODUCT){ $productDiscount = $discount; // you do not need casting. $amount = $productDiscount->getDiscountAmount($this->getItemTotalPrice()); ... } }// foreach 

getDiscountAmount是ProductDiscount特定函数,getDiscountType是折扣特定函数。

更好的方法:

 class Animal { private $_name = null; public function __construct($name = null) { $this->_name = $name; } /** * casts object * @param Animal $to * @return Animal */ public function cast($to) { if ($to instanceof Animal) { $to->_name = $this->_name; } else { throw(new Exception('cant cast ' . get_class($this) . ' to ' . get_class($to))); return $to; } public function getName() { return $this->_name; } } class Cat extends Animal { private $_preferedKindOfFish = null; public function __construct($name = null, $preferedKindOfFish = null) { parent::__construct($name); $this->_preferedKindOfFish = $preferedKindOfFish; } /** * casts object * @param Animal $to * @return Animal */ public function cast($to) { parent::cast($to); if ($to instanceof Cat) { $to->_preferedKindOfFish = $this->_preferedKindOfFish; } return $to; } public function getPreferedKindOfFish() { return $this->_preferedKindOfFish; } } class Dog extends Animal { private $_preferedKindOfCat = null; public function __construct($name = null, $preferedKindOfCat = null) { parent::__construct($name); $this->_preferedKindOfCat = $preferedKindOfCat; } /** * casts object * @param Animal $to * @return Animal */ public function cast($to) { parent::cast($to); if ($to instanceof Dog) { $to->_preferedKindOfCat = $this->_preferedKindOfCat; } return $to; } public function getPreferedKindOfCat() { return $this->_preferedKindOfCat; } } $dogs = array( new Dog('snoopy', 'vegetarian'), new Dog('coyote', 'any'), ); foreach ($dogs as $dog) { $cat = $dog->cast(new Cat()); echo get_class($cat) . ' - ' . $cat->getName() . "\n"; } 

你可以考虑工厂

 class XyFactory { public function createXyObject ($other) { $new = new XyObject($other->someValue); // Do other things, that let $new look like $other (except the used class) return $new; } } 

否则user250120s的解决scheme是唯一的,这接近类铸造。

 class It { public $a = ''; public function __construct($a) { $this->a = $a; } public function printIt() { ; } } //contains static function to 'convert' instance of parent It to sub-class instance of Thing class Thing extends it { public $b = ''; public function __construct($a, $b) { $this->a = $a; $this->b = $b; } public function printThing() { echo $this->a . $this->b; } //static function housed by target class since trying to create an instance of Thing static function thingFromIt(It $it, $b) { return new Thing($it->a, $b); } } //create an instance of It $it = new It('1'); //create an instance of Thing $thing = Thing::thingFromIt($it, '2'); echo 'Class for $it: ' . get_class($it); echo 'Class for $thing: ' . get_class($thing); 

返回:

 Class for $it: It Class for $thing: Thing 

我认为最好的方法是创build一个新的类的实例,并分配对象。 这是我会做的:

 public function ($someVO) { $someCastVO = new SomeVO(); $someCastVO = $someVO; $someCastVO->SomePropertyInVO = "123"; } 

这样做会使代码在大多数IDE中暗示,并帮助确保使用正确的属性。