当前位置: 首页 > 知识库问答 >
问题:

php严格错误,包括

陆斌
2023-03-14

如果类位于一个文件中,则看起来不会发生严格的错误,如下所示:

abstract class Food{}

class Meat extends Food{}                    

abstract class Animal{          
    function feed(Food $food){ }
}

class Cat extends Animal{           
    function feed(Meat $meat){
        parent::feed($meat);
    }   
}    

但是,如果您将类定义放在单独的文件中并像这样包含它们:

abstract class Food{}

class Meat extends Food{}                    

require 'Animal.php';
require 'Cat.php';

抛出严格标准错误消息:

严格的标准:Cat::feed()的声明应与c:\path\to\Cat中的动物::feed(Food$Food)兼容。php在线。。。

如果所有内容都在一个文件中,即使这样也可以:

class Dog extends Animal{           
  function feed($qty = 1){ 
    for($i = 0; $i < $qty; $i++){
        $Meat = new Meat();
        parent::feed($Meat);
    }       
  } 
}

这是预期的行为吗?

因为< code >肉是< code >食物,所以一开始就不应该有抱怨,对吗?因此,解决方案是简单明了的:将所有内容放在一个文件中,严格的标准得到满足;)

感谢任何提示

共有2个答案

锺离飞飙
2023-03-14

当涉及到类和命名空间时,这是PHP的许多奇怪行为之一。

标准解决方案是创建一个接口(我们将其命名为FoodInterface')并在基类中实现它。然后使用FoodInterface 作为方法 feed()'的参数类型

interface FoodInterface {}

abstract class Food implements FoodInterface {}

class Meat extends Food {}

abstract class Animal {
    function feed(FoodInterface $food) {}
}

class Cat extends Animal {           
    function feed(FoodInterface $meat) {
        parent::feed($meat);
    }
}

FoodInterface接口可以为空,也可以在其中声明需要在Animal::feed()调用的函数。

这样,您就可以用任何实现< code>FoodInterface的对象< code>feed()您的< code >猫(或任何其他< code >动物),不管它们是否扩展了< code>Food类。只要它们实现了接口,就可以喂给任何< code >动物。

class Toy implements FoodInterface {}

$cat = new Cat();
$cat->feed(new Toy());    // He can't eat it but at least he will have some fun :-)

因为基类是抽象的,所以它可以充当前面提到的接口。忘掉接口,只需使用与Animal::feed()相同的参数类型声明Cat::feet()

然后,在< code>Cat::feed()的实现中,您可以使用< code>instanceof来检查接收到的参数类型是否是您想要的类型(< code>Meat):

abstract class Food {}

class Meat extends Food {}

abstract class Animal {
    function feed(Food $food) {}
}

class Cat extends Animal {           
    function feed(Food $meat) {
        if (! $meat instanceof Meat) {
            throw new InvalidArgumentException("Cats don't eat any Food. Meat is required");
        }

        // Here you are sure the type of $meat is Meat
        // and you can safely invoke any method of class Meat
        parent::feed($meat);
    }
}

第一种方法是正确的方法。第二种方法有其自身的优势,我建议仅在第一种方法因某种原因不可能时使用它。

卫劲
2023-03-14

这是预期的行为吗?

不幸的是,是的。类声明的复杂性使得当它们都出现在同一个脚本中时,严格的规则并不总是适用;每个文件一个类不会出现这个问题。

因为肉是一种食物,首先不应该有抱怨,对吗?

错误的原因有两个:

>

  • 肉是比食物更小的类型,因此只允许后代类中的较小类型违反了LSP;您不能用代替动物

    在PHP中,参数类型在重载方法时是不变的,即接受的类型必须与父类型完全匹配。虽然可以认为逆变类型是有意义的,但由于技术原因,这是不可能做到的。

    因此,解决方案是简单明了的:将所有内容放在一个文件中,严格的标准得到满足;)

    不,你绝对不应该依赖这种行为。

  •  类似资料:
    • 问题内容: 我需要在顶部设置PHP脚本以禁用严格标准的错误报告。 有人可以帮忙吗? 问题答案: 您要禁用错误报告,还是只是阻止用户查看错误报告?即使在生产站点上,记录错误也通常是一个好主意。 它们将被记录到您的标准系统日志中,或者使用伪指令来指定您希望错误出现的确切位置。

    • 问题内容: 我尝试使用multi_query,但我不断弹出严格的Standards消息。 我收到的错误消息是: 严格标准 :mysqli_next_result():没有下一个结果集。请调用mysqli_more_results()/ mysqli :: more_results()检查是否调用此函数/方法 我尝试添加和删除,但没有运气。 问题答案: 虽然pipodesign纠正了$ querys

    • 在从php创建UTC日期时间时,我当前收到以下严格警告。 严格警告:依赖系统的时区设置是不安全的。请使用日期。时区设置、TZ环境变量或date\u default\u timezone\u set()函数。如果您使用了这些方法中的任何一种,但仍收到此警告,则很可能是您拼错了时区标识符。我们选择“UTC”作为“UTC/0.0/no DST” 这是我正在使用的代码行。 奇怪的是,我已经使用UTC作为时

    • 本文向大家介绍PHP严重致命错误处理:php Fatal error: Cannot redeclare class or function,包括了PHP严重致命错误处理:php Fatal error: Cannot redeclare class or function的使用技巧和注意事项,需要的朋友参考一下 1、错误类型:PHP致命错误 Error type: PHP Fatal error

    • 问题内容: 我知道这个问题应该在scipy.optimize手册中处理,但是我不太了解。也许你可以帮忙 我有一个函数(这只是一个示例,不是真正的函数,但是我需要在这个级别上理解它): 编辑(更好的示例): 假设我有一个矩阵 具有目标功能 现在,我想假设t [i]是实数,并且类似 问题答案: 这个约束 将是等式()约束,其中您必须创建一个必须等​​于零的函数: 然后,您对约束进行了定义(字典列表(如

    • 除了正常的运行模式,JavaScript 还有第二种运行模式:严格模式(strict mode)。顾名思义,这种模式采用更加严格的 JavaScript 语法。 同样的代码,在正常模式和严格模式中,可能会有不一样的运行结果。一些在正常模式下可以运行的语句,在严格模式下将不能运行。 设计目的 早期的 JavaScript 语言有很多设计不合理的地方,但是为了兼容以前的代码,又不能改变老的语法,只能不