Intereting Posts
Инструмент проверки правописания PHP Тестирование фасадов Laravel с издевательством всегда проходит, даже если это не удается Массивы в файлах cookie PHP Как узнать, подключен ли пользователь к веб-сайту с помощью баз данных, базирующихся на php и mysql? Можно ли проверить, является ли объект видом определенного класса, в PHP? Действие контроллера называется дважды Регулярное выражение для анализа ytube yid Запуск скрипта оболочки из PHP как другого (не root) пользователя Пытаться отобразить адрес сущности из базы данных с веточкой определить статус http, который будет отправлен в php PostgreSql 'PDOException' с сообщением 'не смог найти драйвер' Вызов программы через shell_exec с использованием ввода текста utf-8 Как получить комментарий на livefyre? MySQL возвращает false, когда несколько строк соответствуют предложению WHERE FatalErrorException в строке route.php 22: Class 'Painting' not found

Как создавать объекты в PHP

Ive некоторые кланы, которые имеют некоторые атрибуты, и я хотел бы сделать что-то вроде: $ dog = (Dog) $ cat;

возможно ли это или существует какая-то общая работа?

Это не суперкласс, ни интерфейс, ни связанные с ним. Они всего лишь две разные кланы, я хотел бы, чтобы php сопоставлял атрибуты от класса кошки собаке и давал мне новый объект. –

я предполагаю, что я должен указать немного больше причин, кажущихся бессмысленными.

ive clases, которые наследуются от разных родительских кланов, вызывают, что ive создало дерево наследования, основанное на методе сохранения, возможно, мое плохое с самого начала, но проблема в том, что у меня есть много кланов, которые практически равны, но взаимодействуют с mysql и другим с файлами xml. поэтому у меня есть: класс MySql_SomeEntity extends SomeMysqlInteract {} и Xml_SomeEntity расширяет SomeXmlInteract {} его немного более глубокое дерево, но проблема его в этом. я не могу заставить их наследовать от одного и того же класса, потому что многоуровневое наследование не оговорено, и я не могу разделить текущее взаимодействие с суперклассами, потому что это будет большой проблемой.

В принципе, атрибуты в каждом из них практичны одинаково.

так как у меня много таких махинаций, я бы хотел сделать какое-то общее литье или что-то подобное, которое может конвертировать (передать значения каждому атрибуту), но я пытаюсь найти самый простой способ для всех этих кланов.

В PHP нет встроенного метода для персонализации типов объектов, определенных пользователем. Тем не менее, есть несколько возможных решений:

1) Используйте функцию, подобную приведенной ниже, чтобы десериализовать объект, измените строку так, чтобы нужные вам свойства были включены в новый объект после десериализации.

 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) В качестве альтернативы вы можете скопировать свойства объекта, используя отражение / ручную итерацию через них всех или используя get_object_vars ().

Эта статья должна просветить вас на «темных углах PHP» и реализовать типизацию на уровне пользователя.

Вы можете использовать вышеприведенную функцию для отливки не похожих объектов класса (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); 

Без использования наследования (как упоминалось автором ) кажется, что вы ищете решение, которое может transform один класс в другой, при условии, что разработчик знает и понимает сходство двух классов .

Нет никакого существующего решения для преобразования между объектами. Что вы можете попробовать:

  • get_object_vars () : преобразовать объект в массив
  • Вставить в объект : преобразовать массив в объект

Похоже, что вы действительно хотите реализовать интерфейс .

В вашем интерфейсе будут указаны методы, которые может обрабатывать объект, и когда вы передаете объект, реализующий интерфейс, методу, который хочет объект, поддерживающий интерфейс, просто введите аргумент с именем интерфейса.

Вам не нужно кастинг. Все динамично.

У меня есть скидка класса.
У меня есть несколько классов, которые расширяют этот класс:
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 – специальная функция скидок.

лучший aproach:

 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 является единственным, что близко к классу.

 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 

Я считаю, что лучший подход – просто создать новый экземпляр класса и назначить объект. Вот что я сделал бы:

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

Выполнение этого даст вам подсказку кода в большинстве IDE и поможет убедиться, что вы используете правильные свойства.