PHP Trait 静态属性

问题描述 投票:0回答:2

我有一个扩展的课程

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

php static traits
2个回答
0
投票

如果一个特征定义了一个属性,那么类不能定义具有相同名称的属性,除非它是兼容的(相同的可见性、类型、只读修饰符和初始值),否则会发出致命错误。

但是,您可以在 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');

0
投票

如果您正在寻找参考,这直接来自与您的问题相关的 PHP 手册

如果一个特征定义了一个属性,那么类不能定义具有相同名称的属性,除非它是兼容的(相同的可见性和类型、只读修饰符和初始值),否则会发出致命错误。

这对您来说是个坏消息,因为这意味着您通过违反这些规则编写了无法工作的代码,在您的情况下,特别是初始值:

trait Searchable
{
  protected static array $searchable;

class Benefit extends NAFModel
{
  protected static array $searchable =
  [
    'name',
    'description',
  ];

因此,您需要解决这样的限制(不可能解决冲突,例如,对于方法,请参见“与其他特征方法的冲突”)。


我想定义一个向类添加静态属性和静态方法的特征。

如上所述,这两个属性需要兼容,因此解决方案是使它们兼容。

使用别名方法,定义 formatSearchQuery,然后在调用时初始化您要覆盖的属性值,然后委托给别名。

如果您还想有一个初始值,请为其添加一个新的静态属性,并在您定义的 formatSearchQuery 中使用它来复制该值。


但是您还没有分享您想要实现的目标,因此几乎没有什么建议可以提供。不使其静态并不能解决 Traits 级别的类组成问题。您可能遇到初始化问题,并且尝试通过静态解决它,也许您正在寻找静态工厂方法,然后让系统处理每个实例的详细信息。

尝试首先仅使用抽象超类构建类层次结构,然后仅为不与现有名称交叉的其他混合添加特征。

众所周知,组合应该比继承更受青睐,并且特征可能属于后一类而不是第一类。 YMMV.

© www.soinside.com 2019 - 2024. All rights reserved.