首页 > php > php中Warning: Declaration of … should be compatible with …
2021
04-14

php中Warning: Declaration of … should be compatible with …

背景

今天sentry收到报警:Declaration of (类方法1) should be compatible with (类方法2); 详情如下:

Declaration of App\Services\MemcacheAgp::get($key) should be compatible with Memcached::get($key, $cache_cb = NULL, $get_flags = NULL)

字面上理解是:类方法1的声明应该符合类方法2,搜索引擎貌似给了个专业的说法:“方法重写,参数不同”。


分析

代码如下:

<?php

namespace App\Services;

class MemcacheAgp extends \Memcached
{
    private $agp_cache_pre = '';

    public function __construct($persistent_id = '', $on_new_object_cb = null)
    {
        global $CommonConfig;
        $this->agp_cache_pre = $cache_pre;
        parent::__construct($persistent_id, $on_new_object_cb);
    }

    public function set($key, $val, $time = 0, $udf_flags = 0)
    {
        global $CommonConfig;
        $key = $this->agp_cache_pre . $key;
        return parent::set($key, $val, $time);
    }

    public function get($key)
    {
        $key = $this->agp_cache_pre . $key;
        $return = parent::get($key);
        return $return;
    }

}


解决方案

结合搜索到的信息给出我的理解:

其实警告中已经给出了解决办法,由于代码中使用了 class ... extends ... 类继承,报错警告就是告诉你:重写方法的参数不对,你既然继承了这个基类方法,那么重写方法的参数也要按着原样来。

基类中get有三个参数,定义如下:

public function get ($key, callable $cache_cb = null, $flags = 0) {}

我的代码中只有1个参数,并且没有默认值,同时还少了一个2个参数

于是在新版的PHP中就报错,把我重写的方法参数照着基类改一下就解决问题了:

<?php

namespace App\Services;

class MemcacheAgp extends \Memcached
{
    private $agp_cache_pre = '';

    public function __construct($persistent_id = '', $on_new_object_cb = null)
    {
        global $CommonConfig;
        $this->agp_cache_pre = $cache_pre;
        parent::__construct($persistent_id, $on_new_object_cb);
    }

    public function set($key, $val, $time = 0, $udf_flags = 0)
    {
        global $CommonConfig;
        $key = $this->agp_cache_pre . $key;
        return parent::set($key, $val, $time);
    }

    public function get($key, $cache_cb = null, $flags = 0)
    {
        $key = $this->agp_cache_pre . $key;
        $return = parent::get($key);
        return $return;
    }

}


注意事项

基类中第二个参数是有定义类型的,但是我们重写的方法是不能定义类型的,否则会报错

public function get($key,  callable $cache_cb = null, $flags = 0)

我们只能定义成如下形式:

public function get($key, $cache_cb = null, $flags = 0)

其实如果子类重写方法的参数和基类不一样,只要给参数个默认值,使得编译器认为参数可以为空,保持重写方法与基类方法的函数签名相同就可以了。

本文》有 0 条评论

留下一个回复