简体   繁体   English

在PHP中自定义类型提示

[英]Customise the type hinting in PHP

I'm writing a custom extension system for php, which allows for defining a class with new function for an existing class, and add said functions to a class after its defined. 我正在为php创建一个自定义扩展系统,该系统允许为现有类定义具有新功能的类,并在定义该类后将其添加到类中。

As said, extensions are written as a separate class, lets call one MyExtension , and lets say that this extension extends upon to existing classes, MyExtendedClass1 and MyExtendedClass2 . 如上所述,扩展是作为一个单独的类编写的,让我们调用一个MyExtension ,并说此扩展扩展到了现有类MyExtendedClass1MyExtendedClass2 So MyExtension adds some functions to MyExtendedClass1 AND MyExtendedClass2 . 因此, MyExtensionMyExtendedClass1MyExtendedClass2添加了一些功能。

What I want to do is allow users to type hint base on MyExtension. 我想做的是允许用户基于MyExtension键入提示。

// $object is guaranteed to either be an instance of MyExtension
// or be a class that is extended with MyExtension
function someFunction(MyExtension $object) {

}
$post = new MyExtendedClass1(); // Is extended by MyExtension
someFunction($post);

$post = new MyExtendedClass2(); // Is extended by MyExtension
someFunction($post);

What I'm wondering is: 我想知道的是:

Is there any way to "add a type to an object"? 有什么方法可以“向对象添加类型”? Is there any way I can trick the type checking to allow these calls. 有什么办法可以欺骗类型检查以允许这些调用。

It's hard to understand your question because you need custom extension descibed as customly extended object. 这很难,因为你需要自定义扩展 descibed作为customly扩展对象来理解你的问题。

If you need some_function to operate on different types it can't use them directly and type hint can't determine concrete type - use interface . 如果需要some_function对不同类型进行操作,则不能直接使用它们,类型提示不能确定具体的类型使用接口

Your types need to be extended with functionality of common interface that function can depend on - use wrapper objects that implement same inteface, but know (how to communicate) the concrete type. 您的类型需要使用功能可以依赖的通用接口功能进行扩展-使用实现相同接口但知道(如何进行通信)具体类型的包装对象。

interface MyExtensionInteface {
    public function doSoemthingSpecial();
}

function some_function(MyExtensionInterface $myExtension) {
    $myExtension->doSomethingSpecial();
}

class MyExtensionOfExtendedClass1 implements MyExtensionInteface
{
    public function __construct(MyExtendedClass1 $obj) {
        $this->extended = $obj;
    }

    public function doSomethingSpecial() {
        //...with MyExtendedClass1 type
    }
}

class MyExtensionOfExtendedClass2 impements MyExtensionInterface
{
     public function __construct(MyExtendedClass2 $obj) {
         $this->extended = $obj
     }

     public function doSomethingSpecial() {
         //...with MyExtendedClass2 type
     }
}

$a = new MyExtensionOfExtendedClass1(new MyExtendedClass1());
some_function($a);

$b = new MyExtensionOfExtendedClass2(new MyExtendedClass2());
some_function($b);

"Extension" naming is for question context only - it should have real object meaning. “扩展”命名仅用于问题上下文-它应具有真实的对象含义。 For example: DuckSoup(Duck) + ChickenSoup(Chicken) + function:cook(Soup) 例如: DuckSoup(Duck) + ChickenSoup(Chicken) + function:cook(Soup)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM