【问题标题】:Abstract trait't method not allowed to be static in PHP?抽象特征的方法不允许在 PHP 中是静态的?
【发布时间】:2015-01-13 13:02:45
【问题描述】:

这是我的例子:

trait FileConfig {
    public static function getPathForUploads() {
        $paths = static::getPaths();
        //etc.
    }

    abstract public static function getPaths(); //doesn't work. Error: "Static function SharedDefaultConfig::getPaths() should not be abstract"

    abstract public function getPaths(); //OK
    public static function getPaths() {} //OK
}

类:

class AppConfig {
    use FileConfig;

    public static function getPaths() {
        return array(...);  
    }
}

呼叫:

AppConfig::getPathForUploads();

必须将其设为静态和抽象(强制使用 FileConfig 的类实现 getPaths)。

我想知道如何实现改变它的 static 属性的方法?这是一个好的做法还是有更好的解决方案?有一天会变成非法的吗?

谢谢

【问题讨论】:

  • 我在 AWS 的 PHP SDK 中看到了abstract public function,但我不明白为什么不直接使用接口和/或抽象类?

标签: php oop traits


【解决方案1】:

这在 php 7 中已修复,因此以下代码有效:

<?php

error_reporting(-1);

trait FileConfig {
    public static function getPathForUploads() {
        echo static::getPaths();
    }

    abstract static function getPaths();
}

class AppConfig {
    use FileConfig;

    protected static function getPaths() {
        return "hello world";
    }
}

AppConfig::getPathForUploads();

http://sandbox.onlinephpfunctions.com/code/610f3140b056f3c3e8defb84e6b57ae61fbafbc9

但它实际上并不检查 AppConfig 中的方法是否在编译期间是静态的。当您尝试静态调用非静态方法时,您只会收到警告:http://sandbox.onlinephpfunctions.com/code/1252f81af34f71e901994af2531104d70024a685

【讨论】:

    【解决方案2】:

    您不需要将方法设为静态来强制使用它的类来实现该方法。您可以简单地在旁边使用interfaces

    trait FileUploadConfig {
        public static function getPathForUploads() {
            $paths = static::getPaths();
            //etc.
        }
    }
    

    特征保持原样。我只是把接口的功能拿走了。

    interface PathConfiguration {
        public static function getPaths();
    }
    

    接口强制类实现功能。我将static 留在那里以符合特征的规范。

    class AppConfig implements PathConfiguration {
        use FileUploadConfig;
        public static function getPaths() {
            return [];
        }
    }
    

    【讨论】:

    • traits 中抽象方法的意义在于强制 trait 的用户实现一个方法。如果您有一个单独的接口,则无法保证用户也会实现该接口(以及 trait 所需的方法)。
    • 对 IDE 也很有用。当你从 trait 中的接口使用静态方法时,基本上 trait 不知道这个静态方法,ide 会弹出错误。相反,如果您在 trait 中将其声明为抽象静态方法,那么 IDE 就会知道该方法
    • @SoufianeGhzal,如果您只想摆脱 IDE 弹出窗口,您可以使用 @mixin 注释声明 trait 知道接口
    • 不知道@mixin 注释,谢谢@fragmentedreality
    【解决方案3】:

    要强制使用 FileConfig 的类来实现 getPaths,不必将抽象函数设为静态。静态意味着它属于声明它的类。使其成为受保护的静态,从 trait 添加代码,然后您可以通过从 AppConfig 类继承来更改行为。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-05-27
      • 2013-09-15
      • 1970-01-01
      • 1970-01-01
      • 2012-12-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多