我可以从 class 之外的特征调用静态函数吗?

Can I call a static function from a trait outside of a class?

考虑这样一种情况,其中有多个 class 都需要访问配置存储机制,但由于框架的架构,无法从基础 class 进行扩展。 除此之外,我还想保持存储机制的灵活性(稍后能够切换存储后端)。

我觉得创建一个特性来进行实际保存并在所有 classes 中使用这些函数是有意义的(例如,我使用 $_SESSION 作为存储系统):

trait MyTrait {

  function setting_enabled() {
    return !empty($_SESSION['setting']) ? TRUE : FALSE;
  }

  function enable_setting() {
    $_SESSION['setting'] = TRUE;
  }

  function disable_setting() {
    $_SESSION['setting'] = FALSE;
  }

}

这在 classes 中非常有效。然而,还有一个文件不是 class,而是普通的 PHP,我还需要知道该设置是否已启用。

我尝试将函数声明为 static:

trait MyTrait {

  static function setting_enabled() { // Declared as static function
    return !empty($_SESSION['setting']) ? TRUE : FALSE;
  }

  ...
}

然后从 trait 调用静态函数,效果很好。

if (MyTrait::setting_enabled()) {
  ...
}

不过感觉不太对。另一方面,创建一个使用特征的新空 class 并实例化它以获取值似乎有很多开销。

我可以这样做吗(从 PHP 5.6 开始,但也要考虑 PHP 7.x 的未来)?

如果你有一个特征,那么你决定进行一次多重继承,也许是多个 classes。否则,这是多余的声明,您必须使用 class。事实上,特征的存在意味着它的使用。

如果您在 trait 中有一个静态函数,那么为什么您不能在 class 中使用它来实现 trait?

trait MyTrait {
 static myFunc() {}
}

class ThatUsingMyTrait {
 use MyTrait;
}

// pretend below a code where you want to use the trait.
if(ThatUsingMyTrait::myFunc()) {
 // do something
}

该代码也可能是 class 你想直接实现的代码。

希望我能理解地描述这个想法。

PHP 不允许在没有某些 class 的情况下调用特征的方法(无论是否 static)。

一个简单的解决方法是中间使用匿名class


...

(new class { use MyTrait; })::myMethod();

...

我更喜欢这种方式,因为我们不会创建不必要的 class 名称。

不确定是否导入您的特征正在尝试解决它: 在 non-static 方法的情况下

(new class { use MyTrait; })->myMethod();

但它似乎已在 php 8

上弃用