如何在PHP中强制实现类型提示接口的契约

Zam*_*ara 8 php interface type-hinting

让我们想象一下,我们有以下接口声明.

<?php 
namespace App\Sample;

interface A
{
    public function doSomething();
}
Run Code Online (Sandbox Code Playgroud)

B实现接口的类A.

<?php
namespace App\Sample;

class B implements A
{
    public function doSomething()
    {
        //do something
    }

    public function doBOnlyThing()
    {
        //do thing that specific to B
    }  
}
Run Code Online (Sandbox Code Playgroud)

C将取决于接口A.

<?php
namespace App\Sample;

class C
{
    private $a;

    public function __construct(A $a)
    {
        $this->a = $a;
    }

    public function doManyThing()
    {
        //this call is OK
        $this->a->doSomething();

        //if $this->a is instance of B, 
        //PHP does allow following call
        //how to prevent this?
        $this->a->doBOnlyThing();            
    }  
}

...
(new C(new B()))->doManyThing();
Run Code Online (Sandbox Code Playgroud)

如果B传递实例类C,PHP确实允许调用B的任何公共方法,即使我们只输入构造函数来接受A接口.

如何在PHP的帮助下防止这种情况,而不是依赖任何团队成员来遵守接口规范?

更新:我们假设我不能将doBOnlyThing()方法设为私有,因为它在其他地方是必需的,或者它是我无法更改的第三方库的一部分.

Dan*_*ack 9

您无法在PHP中执行此操作,因为它不会阻止此类方法调用.

您可以通过使用PHPStan等工具来检测对不保证存在的参数的方法调用.

在几乎任何语言中,语言中都有可以使用的功能,但是程序员团队的负责人选择不允许这些功能成为团队编写代码的方式.

使用静态分析工具和其他代码质量工具通常是实施这些规则的最佳方式.最好在预提交钩子上,如果你可以设置它们,否则在提交完成后的自动构建工具中.