PHP接口。不同的退货类型

时间:2014-03-22 11:10:19

标签: php interface

PHP中的接口是否应该返回相同的类型? 我的朋友告诉我它应该返回相同的类型。(为了良好的做法) 我知道PHP是动态类型语言,它是不可能的。

例如:

    interface idReturn
{
   //Return INT
   public function getById($id);
}

interface arrayReturn
{
    //Return array
    public function getByData($data);
}

这是好的做法吗?

2 个答案:

答案 0 :(得分:5)

这不是界面的事情。为避免在使用者中进行类型检查,方法应仅返回一种类型。由于reduced number of execution pathes through the code,因此更容易理解代码。

例如,这增加了不必要的复杂性:

function get_users()
{
    // some code returning array when users have been found
    // or null when no users have been found
}

$users = get_users();
if (!is_null($users)) {
    foreach ($users as $user) {
        // do something with $user
    }
}

如果get_users()在没有找到用户时只返回一个空数组,则可以简化消费代码只需阅读

foreach (get_users() as $user) {
    // do something with $user
}

此外,凭借Liskov's Substitution Principle,任何超类型子类的类都需要在使用超类型的消费者中互换使用。如果消费者需要一个整数,您可能不会返回一个字符串,因为这可能会破坏消费者。对于实现该接口的接口和使用者的类,例如

,情况也是如此
interface Contract
{
    /** @return array */
    public function fn();
}

现在假设A implements Contract并返回数组,而B implements Contract并返回数组或null。当B返回null时,我的消费者期望数组现在会中断:

function fn(Contract $instance)
{
    // will break when B returns null
    foreach ($instance->fn() as $foo) {
        // do something with $foo
    }
}

由于PHP目前无法强制执行返回类型,因此由开发人员在DocBlock中指示它并确保实现或子类型类符合该返回类型。

话虽如此,如果合同定义了多种可能的退货类型,消费者必须确保它能够处理它们。但是,这又意味着不合需要的类型检查。

答案 1 :(得分:3)

他可能是这个意思:

interface I {
    public function f();
}

class A implements I {
    public function f() {
        return 1; // int
    }
}

class B implements I {
    public function f() {
        return 'a'; // string
    }
}

您是否想要这完全取决于您为I::f定义的合同。合同应该放在单独的文档中,因为PHP缺乏对正式指定它们的支持(这不是特定于PHP的,大多数语言都是这种情况,D和Eiffel都是明显的例外)。