致命错误:.. 的声明必须与 .. PHP 兼容

Posted

技术标签:

【中文标题】致命错误:.. 的声明必须与 .. PHP 兼容【英文标题】:Fatal error: Declaration of .. must be compatible with .. PHP 【发布时间】:2012-07-01 15:58:24 【问题描述】:

我收到以下错误:

Fatal error: Declaration of Shoppingcart::addToCart() must be compatible with that of Ishoppingcart::addToCart() in klassen.php on line 118

可能是什么问题?我找不到 脚本:

<?php
// begin
interface Ishoppingcart
    public function addToCart();
    public function printOverzicht();

abstract class Shoppingcart implements Ishoppingcart

    protected $producten = array();

    public function addToCart( Product $product) 
        $this->producten[] = $product;
    

class Myshoppingcart extends Shoppingcart 
    public function printOverzicht()
        echo ("<table border=1>
        <tr>
        <td colspan='7'>Bestellingoverzicht</td>
        </tr>
        <tr>
        <td bgcolor=#cccccc> Product ID</td>
        <td bgcolor=#cccccc> Beschrijving</td>
        <td bgcolor=#cccccc> Merk</td>
        <td bgcolor=#cccccc> Model</td>
        <td bgcolor=#cccccc> Prijs</td>
        <td bgcolor=#cccccc> Aantal</td>
        <td bgcolor=#cccccc> Korting</td>
        </tr>");

        foreach($this->producten as $product)
            $rij = "";
            $rij .= "<tr>";
            $rij .= "<td>".$product->getID()."</td>";
            $rij .= "<td>".$product->getBeschrijving()."</td>";
            $rij .= "<td>".$product->getMerk()."</td>";
            $rij .= "<td>".$product->getModel()."</td>";
            $rij .= "<td>".$product->getPrijs()."</td>";
            $rij .= "<td>".$product->getAantal()."</td>";
            $rij .= "<td>".$product->getKorting()."</td>";
            $rij .= "</tr>";
            echo ($rij);
        
        echo ("</table>");
    

class Product 
    private $id;
    private $beschrijving;
    private $merk;
    private $model;
    private $prijs;
    private $aantal;
    private $korting;

    function __construct($id,
                        $merk,
                        $model,
                        $prijs,
                        $aantal,
                        $korting)
        $this->id = $id;
        $this->beschrijving = $beschrijving;
        $this->merk = $merk;
        $this->model = $model;
        $this->prijs = $prijs;
        $this->aantal = $aantal;
        $this->korting = $korting;
        echo ("<br />Nieuw Product object $beschrijving wordt aangemaakt");
                        
    public function __destruct()
        // voer benodigde acties uit
        echo ("<br />Product object $this->beschrijving wordt verwijderd");
    
    // set function
    public function setId($id)
        $this->id = $id;
    
    public function setBeschrijving($beschrijving)
        $this->beschrijving = $beschrijving;
    
    public function setMerk($merk)
        $this->merk = $merk;
    
    public function setModel($model)
        $this->model = $model;
    
    public function setPrijs($prijs)
        $this->prijs = $prijs;
    
    public function setAantal($aantal)
        $this->aantal = $aantal;
    
    public function setKorting($korting)
        $this->korting = $korting;
    
    // get function
    public function getId()
        return $this->id = $id;
    
    public function getBeschrijving()
        return $this->beschrijving;
    
    public function getMerk()
        return $this->merk;
    
    public function getModel()
        return $this->model;
    
    public function getPrijs()
        return $this->prijs;
    
    public function getAantal()
        return $this->aantal;
    
    public function getKorting()
        return $this->korting;
    

    // printProductInfo
    public function printProductInfo()
    $rij = "<tr><td>$this->id</td>";
    $rij .= "<td>$this->beschrijving</td>";
    $rij .= "<td>$this->merk</td>";
    $rij .= "<td>$this->model</td>";
    $rij .= "<td>$this->prijs</td>";
    $rij .= "<td>$this->aantal</td>";
    $rij .= "<td>$this->korting</td>";  
    echo ($rij);
    

// einde
?>

【问题讨论】:

这个错误出现在哪个版本的 PHP 中。在 PHP7.2 中,它在 php7.4 中警告它的致命错误。 【参考方案1】:

Ishoppingcart::addToCart() 声明该方法不带任何参数,而实现Shoppingcart::addToCart(Product $product) 要求必须将Product 类型的参数传递给该方法。这意味着两个声明不兼容,而实现的接口必须满足 PHP 抛出显示的错误。

解决方案是将Ishoppingcart::addToCart() 更改为Ishoppingcart::addToCart(Product $product),使其需要Product 类型的参数,或者更改Shoppingcart::addToCart(Product $product) 以不允许将任何参数传递给方法:Shoppingcart::addToCart(Product $product = null)

正确的方法取决于你的应用需求。

【讨论】:

@F4LLCON 在我看来,使用默认值 NULL 是一种破坏接口目的的黑客行为。我希望接口具有“这正是此方法的签名”的合同。我觉得要么接口应该有参数,要么两个方法命名不同。 我完全按照书中的说明进行操作。但它没有用。我现在将使用 hack,因为更改某些内容会影响脚本中的其他内容。 @F4LLCON 等等,那是书上的?我会换书。这不是什么大问题,但对于一本经过编辑、出版的书,我不希望作者会犯这样的错误。 我知道,我正在学习的课程有一位老师写了这本书。如果我抱怨某事不起作用,他会说这可能是你(我)做错了。他不会帮忙等等。但是还有一个星期,我已经完成了这所大学的学习,将去学习游戏技术。我会烧掉这本烂书。只有问题,没有任何效果。有趣的是,写这本书的老师说我们只能使用这本书。等我把毕业论文装进口袋里,准备去学校投诉。但无论如何,谢谢你:) 既然你已经完成了课程,也许你想分享这本书作为课程的一部分,或者大学也可以? :)【参考方案2】:

子类中公共函数的声明必须与其父类的声明一致:

public function addToCart();
public function addToCart( Product $product)

您不能在签名中添加参数。

这与Liskov substitution principle密切相关。

【讨论】:

【参考方案3】:

接口 Ishoppingcart 似乎定义了不带参数的 addToShoppingCart,但类 Shoppingcart 定义了相同的函数,以 Product 作为参数。我想接口中的方法也应该将 Product 作为参数。

【讨论】:

【参考方案4】:

我通过升级到最新的 php 版本解决了这个问题

【讨论】:

【参考方案5】:

不适用于此特定问题,但如果有人遇到此问题,请确保包含接口指定的返回值。

具有如下功能的接口:

abstract public function crawled(Something $some): void;

需要实现为:

public function crawled(Something $some): void 

就我而言,我缺少 : void 返回类型。

【讨论】:

以上是关于致命错误:.. 的声明必须与 .. PHP 兼容的主要内容,如果未能解决你的问题,请参考以下文章

致命错误:registerContainerConfiguration 的声明必须与 Kernel::registerContainerConfiguration 的声明兼容

致命错误:' Zend_Pdf_FileParserDatasource_File::__contruct() 的声明必须兼容

Zend Framework 1是否与PHP 7.2兼容?

PHP 8,函数别名兼容性`getdir()`

PHP致命错误:无法重新声明类

升级到 PHP 7.0.8 后出现“致命错误:无法声明类”