How to Emulate type return from interface in PHP?

0

I have to get some information from the database models. The problem is that all the models (that describe the tables) are different. The information of the models must be shown in a calendar, therefore I need the same structure [title, date from, date until, type of event, etc] for all the models.

So my idea is to create an interface that forces the models to have certain characteristics. An example model is this:

Model that represents a table in the database

class EventsType1 extends Model {
    // metodos y atributos del modelo 1
}

class EventsType2 extends Model {
    // metodos y atributos del modelo 2
}

Interface that I want the models to implement:

interface IScheludable {
    // permite obtener los eventos en el formato que la agenda necesita
    public function getEvents(fromDate, toDate);
}

Now I can get the models to have the functions that I need to implement regardless of the type of event, in a way similar to this:

class EventsType2 extends Model implements IScheludable {
    // metodos y atributos del modelo 2
    public function getEvents(fromDate, toDate){
        // return eventos desde el modelo
    }
}

BUT, I can not make the interface also force the model to deliver a specific data structure for the agenda. This is an example of the structure that I need (and that the agenda returns to the web client):

class Event {
    public $title;
    public $dateFrom;
    public $dateTo;
    public $eventColor;

    function __construct($title, $date, $someArgs) {
        // set params
    }
    //etc
}

I understand that in PHP 7 you can define the type of return, but I do not use PHP 7 in this project. So I need the interface to force the classes that implement it to return some specified structure, otherwise the interface does not make much sense. Consider the following:

class EventsType2 extends Model implements IScheludable {
    // metodos y atributos del modelo 2
    public function getEvents(fromDate, toDate){
        // Operaciones
        return new Event('Evento1', '1-2-2015', $otherArgs);
    }
}

This is also valid:

class EventsType2 extends Model implements IScheludable {
    // metodos y atributos del modelo 2
    public function getEvents(fromDate, toDate){
        // Operaciones
        return new AnyClass(); // <- Justamente esto quiero que no ocurra
    }
}

Another example in Php Sandbox

    
asked by UselesssCat 14.03.2017 в 16:13
source

2 answers

1

Suppose that all the ORM models, which represent different tables, have in some way the equivalent of $dateFrom and $dateTo (I am simplifying your example to simplify my life). You need all models to be able to return an instance of the Evento class that has predefined fields.

class Event {
    public $dateFrom;
    public $dateTo;
}

Let EventType1 and EventsType2 be two different models that represent two different tables, with attributes:

class EventsType1 extends Model {
    public $time_ini;
    public $time_fin;
}

class EventsType2 extends Model {
    public $desde;
    public $hasta;
}

It would be a matter of adding to each model a method getEvent that using its properties would return a valid instance of Event. And this implies customizing the method in each entity.

class EventsType1 extends Model {
    public $time_ini;
    public $time_fin;

    public function getEvent() {
       return new Event($this->time_ini, $this->time_fin);
    }
}

class EventsType2 extends Model {
    public $desde;
    public $hasta;

    public function getEvent() {
       return new Event($this->desde, $this->hasta);
    }
}

With that each entit, no matter what their properties are called, is able to export an event in the expected format.

    
answered by 14.03.2017 в 16:55
0

To do this kind of problem, you could use Traits .

It would be enough if you implemented a Trait that would implement this logic of returning an event:

trait EventTrait {
  public function getEvents($from, $to) {
    return new Event (...);
  } 
}

and then on your models:

class EventsType1 extends Model {
  // metodos y atributos del modelo 1
  use EventTrait;
}

class EventsType2 extends Model {
  // metodos y atributos del modelo 2
  use EventTrait;
}

In general, the traits (features in English) serve to reuse code where the inheritance of the language is simple (non-multiherence). Thanks to this, you can externally define common functionality for several classes and then have new classes use these 'features'.

I hope I have helped

greetings

    
answered by 14.03.2017 в 17:59