I have such a class hierarchy

class Question extends yii\db\ActiveRecord {/** Implementation **/} class TextQuestion extends Question {/** Implementation **/} class SumQuestion extends Question {/** Implementation **/} 

Is it possible to convert a Question object to TextQuestion or SumQuestion ?

Primitive example

 $question = new Question(); $sum = (SumQuestion)$question; 

The first idea that came to mind is to transfer attributes, but perhaps there is a better solution.

 $question = new Question(); $sum = new SumQuestion(); $sum->setAttributes($question->getAttributes()); 

Thanks in advance for your help!

  • Could you clarify why you need this? - Bookin
  • A secret comes from the client, I don’t know the type of answer. Therefore, the sample goes through the Question model, and then across the field type you need to convert the object into the desired one. - Kison
  • Hm, the clarification confused us even more. - Naumov
  • I will try again), in short - when a client answers a question, then a request is sent to the server with an answer and a kind of secret code that searches for the question in the database. The type of question does not come from the client, so you must first select the data from the database through the Question model using the secret key, and then convert it to the desired type so that the necessary behavior is present, etc. - Kison
  • Guys look at the decision, maybe someone will raise doubts - Kison

1 answer 1

I implemented it in this way, maybe there are some kind of pitfalls, but have not yet identified them.

 class Question extends yii\db\ActiveRecord { public function convert() { // Тут идет получение объекта по типу из фабрики, но для ясности указал явный тип $model = new SumQuestion(); $model->setOldAttributes($this->getOldAttributes()); // Перенимаем атрибуты $model->setAttributes($this->getAttributes(), false); // Вызываем afterFind событие для того чтобы модель думала что ее выбрали из базы $model->afterFind(); return $model; } } $question = Question::find() ->where(['secret' => $secret]) ->one(); $converted = $question->convert();