PHP中类似C#的扩展方法?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (17)

我喜欢C#中的编写扩展方法的方式,然后执行如下操作:

string ourString = "hello";
ourString.MyExtension("another");

甚至

"hello".MyExtention("another");

有没有办法在PHP中有类似的行为?

提问于
用户回答回答于

如果将所有字符串重新实现为对象,则可以。

class MyString {
    ...
    function foo () { ... }
}

$str = new MyString('Bar');
$str->foo('baz');

但你真的不想这样做。PHP根本不是面向对象的语言,字符串只是原始类型,没有方法。

'Bar'->foo('baz')语法是不可能的PHP实现无需扩展核心引擎(这是不是你想进入任何东西,至少不是为了这个目的:))。

关于扩展一个对象的功能也没有什么可比它简单地写一个接受一个原语的新函数更好。换句话说,PHP相当于

"hello".MyExtention("another");

my_extension("hello", "another");

对于所有的意图和目的,它具有相同的功能,只是不同的语法。

用户回答回答于

给定一个接口和实现:

interface FooInterface { 
    function sayHello();
    function sayWorld();
}

class Foo implements FooInterface { 
    public function sayHello() { 
        echo 'Hello';
    }
    public function sayWorld() {
        echo 'World';
    }
}

只要依赖关系Foo实际上依赖于接口FooInterface,你可以实现FooInterface自己作为一个包装器FooFoo在必要时转发调用,并根据需要添加其他方法:

class DecoratedFoo implements FooInterface { 
    private $foo;
    public function __construct(FooInterface $foo) {
        $this->foo = $foo;
    }
    public function sayHello() {
        $this->foo->sayHello();
    }
    public function sayWorld() {
        $this->foo->sayWorld();
    }
    public function sayDanke() {
        echo 'Danke';
    }
    public function sayShoen() {
        echo 'Shoen';
    }
}

方法sayHello()并被sayWorld()修补到包含的Foo对象,但是我们已经添加sayDanke()sayShoen()

下列:

function acceptsFooInterface(FooInterface $foo) {
    $foo->sayHello();
    $foo->sayWorld();
}

$foo = new Foo();
acceptsFooInterface($foo);

按预期工作,HelloWorld; 但是这样做:

$decoratedFoo = new DecoratedFoo($foo);
acceptsFooInterface($decoratedFoo);

$decoratedFoo->sayDanke();
$decoratedFoo->sayShoen();

HelloWorldDankeShoen

扫码关注云+社区