PHP中抽象trait方法不允许是静态的吗?

6
这里是我的例子:
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)。

我想知道如何实现更改其静态属性的方法?这是一种好的做法还是有更好的解决方案?它会在某一天变得不合法吗?

谢谢


我在AWS的PHP SDK中看到了abstract public function,但我不明白为什么不直接使用接口和/或抽象类呢? - The Onin
3个回答

12

这在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


3
您不需要使方法静态来强制使用它的类实现该方法。您可以简单地与接口一起使用。
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 [];
    }
}

3
特质中抽象方法的目的是强制特质的使用者实现方法。如果你有一个单独的接口,没有任何保证使用者也会实现该接口(以及特质所需要的方法)。 - user1431317
这对IDE也很有用。当您在trait中使用接口中的静态方法时,基本上trait不知道这个静态方法,IDE会弹出一个错误。相反,如果您将其声明为trait内的抽象静态方法,则IDE将了解该方法。 - gsouf
@SoufianeGhzal,如果你只是想摆脱IDE弹出窗口,你可以使用@mixin注释来声明trait知道接口。 - fragmentedreality
不知道那个“@mixin”注释,谢谢@fragmentedreality提醒。 - gsouf

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接