【问题标题】:Customise the type hinting in PHP在 PHP 中自定义类型提示
【发布时间】:2016-02-23 10:19:35
【问题描述】:

我正在为 php 编写一个 custom 扩展系统,它允许为现有类定义具有新函数的类,并在定义后将所述函数添加到类中。

如前所述,扩展是作为一个单独的类编写的,让我们调用一个MyExtension,并且可以说这个扩展扩展到现有的类MyExtendedClass1MyExtendedClass2。所以MyExtensionMyExtendedClass1MyExtendedClass2添加了一些函数。

我想要做的是允许用户基于 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);

我想知道的是:

有没有办法“向对象添加类型”?有什么办法可以欺骗类型检查以允许这些调用。

【问题讨论】:

  • 这对你还没有用吗? This is already supported behavior
  • 您可以使用MyExtendedClass 作为类型提示,因为所有MyExtension 类都将扩展MyExtendedClass。或者更好的是,您可以创建一个应该实现所有扩展类的接口并将该接口用于类型提示。
  • 在 PHP 中这称为 类型提示。更多信息可以在 PHP 网站上找到:Type declarations
  • @castis 我不是在谈论 php 的 OOP extends 功能,而是一个自定义扩展系统,可以在定义后向类添加功能
  • @akDeveloper 我已编辑问题以使用不适用的示例

标签: php types type-conversion strong-typing


【解决方案1】:

很难理解您的问题,因为您需要将自定义扩展描述为自定义扩展对象。

如果您需要 some_function 对不同类型进行操作,它不能直接使用它们并且类型提示无法确定具体类型 - 使用 interface

您的类型需要使用函数可以依赖的通用接口的功能进行扩展 - 使用实现相同接口但知道(如何通信)具体类型的包装器对象。

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);

“扩展”命名仅用于问题上下文 - 它应该具有真实的对象含义。例如:DuckSoup(Duck) + ChickenSoup(Chicken) + function:cook(Soup)

【讨论】:

    猜你喜欢
    • 2020-11-23
    • 1970-01-01
    • 2017-06-18
    • 2021-09-08
    • 2021-11-16
    • 2015-05-01
    • 1970-01-01
    • 2022-08-18
    • 1970-01-01
    相关资源
    最近更新 更多