php – Force declaration of properties

Question:

I'm implementing a filter functionality in some classes of my application through traits .

The trait function will resort to class variables through some properties defined in the class:

<?php

trait FilterTrait {    
    public function scopeApplyFilters($filters) {
        foreach (self::$allowedFilters as $filter) {
             // Executa método
        }
     }
}

class EstoqueMeta extends Eloquent {
    use FilterTrait;
    static public $allowedFilters = array('foo','bar');
}

I would like to force from the trait that the property be defined in the class. I thought to implement this functionality from inheritance, but I would lose the flexibility of using the trait in other parts of my application.

Is there any way to "force" the declaration of properties from the trait ? If not, are there any alternatives without involving inheritance?


My problem is not declaring the property on trait , this was my first attempt, but if the class has the same property, there will be a collision error with the name of the properties.

trait FilterTrait {    
    public $allowedFilters = array();    
    public function scopeApplyFilters($filters) {
        foreach (self::$allowedFilters as $filter) {
             // Executa método
        }
     }
}

class EstoqueMeta {
    use FilterTrait;    
    public $allowedFilters = array('foo', 'bar');
}

Fatal error: EstoqueMeta and FilterTrait defines the same property ($allowedFilters) in the composition of EstoqueMeta. However, the definition differs and is considered incompatible. Class was composed in […][…] on line 23

Example

Answer:

I believe it is not possible to do what you want, properties are at best inherited as far as I know. But it's possible to solve this without needing to set a property, you can leave a method for your class to implement, you can use an interface or leave an abstract method on your trait to do that

Example:

    trait FilterTrait
    {

        abstract public function getAllowedFilters();

        public function scopeApplyFilters(array $filters)
        {
            foreach ($filters as $filter) {
                if (false === \in_array($filter, $this->getAllowedFilters())) {

                }
            }
        }

    }

    class EstoqueMeta
    {

        use FilterTrait;

        public function getAllowedFilters()
        {
            return array('foo', 'bar');
        }

    }

    $estoque = new EstoqueMeta();

    $estoque->scopeApplyFilters(array('foo'));
Scroll to Top