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

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