我有一个扩展的课程
Eloquent\Model
。
我想定义一个向类添加静态属性和静态方法的特征。
trait Searchable
{
protected static array $searchable;
public static function formatSearchQuery($value)
{
$queryArray = array();
$paramArray = array();
foreach (self::$searchable as $field) {
$queryArray[] = "{$field} LIKE ?";
$paramArray[] = $value . '%';
}
return ['query' => join(" OR ", $queryArray), 'params' => $paramArray];
}
}
目的是定义可在文本搜索查询中使用的字段。
我遇到的问题是当我这样定义我的类时:
class Benefit extends NAFModel
{
use Searchable;
/**
* Name for table without prefix
*
* @var string
*/
protected $table = 'naf_agenda_benefits';
protected static array $searchable =
[
'name',
'description',
];
}
我收到以下错误:
PHP Fatal error: NafAgenda\Eloquent\Client and NafAgenda\Traits\Searchable define the same property ($searchable) in the composition of NafAgenda\Eloquent\Client. However, the definition differs and is considered incompatible. Class was composed in /var/www/html/wp-content/plugins/naf-agenda-react/includes/Eloquent/Client.php on line 9
如果一个特征定义了一个属性,那么类不能定义具有相同名称的属性,除非它是兼容的(相同的可见性、类型、只读修饰符和初始值),否则会发出致命错误。
但是,您可以在 Trait 中创建
setSearchable
函数来设置数组并访问它,如下例所示。
<?php
trait Searchable
{
protected static array $searchable;
// Set Searchable
public static function setSearchable(array $args)
{
static::$searchable = $args;
}
public static function formatSearchQuery($value)
{
$queryArray = array();
$paramArray = array();
foreach (self::$searchable as $field) {
$queryArray[] = "{$field} LIKE ?";
$paramArray[] = $value . '%';
}
return ['query' => join(" OR ", $queryArray), 'params' => $paramArray];
}
}
class Benefit extends NAFModel
{
use Searchable;
/**
* Name for table without prefix
*
* @var string
*/
protected $table = 'naf_agenda_benefits';
}
Benefit::setSearchable(['name', 'description']);
Benefit::formatSearchQuery('Something');
如果您正在寻找参考,这直接来自与您的问题相关的 PHP 手册:
如果一个特征定义了一个属性,那么类不能定义具有相同名称的属性,除非它是兼容的(相同的可见性和类型、只读修饰符和初始值),否则会发出致命错误。
这对您来说是个坏消息,因为这意味着您通过违反这些规则编写了无法工作的代码,在您的情况下,特别是初始值:
trait Searchable
{
protected static array $searchable;
与
class Benefit extends NAFModel
{
protected static array $searchable =
[
'name',
'description',
];
因此,您需要解决这样的限制(不可能解决冲突,例如,对于方法,请参见“与其他特征方法的冲突”)。
我想定义一个向类添加静态属性和静态方法的特征。
如上所述,这两个属性需要兼容,因此解决方案是使它们兼容。
使用别名方法,定义 formatSearchQuery,然后在调用时初始化您要覆盖的属性值,然后委托给别名。
如果您还想有一个初始值,请为其添加一个新的静态属性,并在您定义的 formatSearchQuery 中使用它来复制该值。
但是您还没有分享您想要实现的目标,因此几乎没有什么建议可以提供。不使其静态并不能解决 Traits 级别的类组成问题。您可能遇到初始化问题,并且尝试通过静态解决它,也许您正在寻找静态工厂方法,然后让系统处理每个实例的详细信息。
尝试首先仅使用抽象超类构建类层次结构,然后仅为不与现有名称交叉的其他混合添加特征。
众所周知,组合应该比继承更受青睐,并且特征可能属于后一类而不是第一类。 YMMV.