【问题标题】:Can I call a static function from a trait outside of a class?我可以从类外部的特征调用静态函数吗?
【发布时间】:2017-06-22 14:19:19
【问题描述】:

考虑这样一种情况:有多个类都需要访问配置存储机制,但由于框架的架构,不能从基类扩展。 除此之外,我想保持存储机制的灵活性(以后能够切换存储后端)。

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

trait MyTrait {

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

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

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

}

这在课堂上效果很好。然而,还有一个文件不是类,而只是普通的 PHP,我还需要知道是否启用了该设置。

我尝试将函数声明为static

trait MyTrait {

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

  ...
}

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

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

然而感觉并不完全正确。另一方面,创建一个使用 trait 的新空类并实例化它来获取值似乎有很多开销。

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

【问题讨论】:

    标签: php class standards traits


    【解决方案1】:

    PHP 不允许在没有某个类的情况下调用 trait 的方法(无论是否static)。

    一个简单的解决方法是使用匿名类

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

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

    【讨论】:

    • 不错的解决方案!!
    • 显然从特征调用静态方法有效:3v4l.org/uQfuK 尽管它在 8.1 中已被弃用(这是正确的)
    【解决方案2】:

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

    如果你在 trait 中有一个静态函数,那么为什么你不能在你实现了 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
    }
    

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

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

    【讨论】:

    • 它在课堂上效果很好。而且我确实可以实例化一个使用该特征的类。实际的问题是是否允许我在课堂外使用MyTrait::setting_enabled()。它可以工作,但我找不到任何关于这是错误还是功能的文档。
    • 我认为这不是错误。 php.net 上的定义听起来像“一个 Trait 类似于一个类,但只是旨在以细粒度和一致的方式对功能进行分组。”您不能实例化特征,但由于它在所有其他功能中类似于类,因此特征应该在其自身上处理所有其他操作。再一次,角落的想法,如果你可以将代码从一个类复制并粘贴到另一个类,那么你就有了一个候选特征。
    • 谢谢,我想它可以保存使用。
    猜你喜欢
    • 2021-04-21
    • 2017-01-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-09
    • 1970-01-01
    • 2022-07-27
    相关资源
    最近更新 更多