【问题标题】:Resolve calling class from static parent method从静态父方法解析调用类
【发布时间】:2023-01-30 21:55:23
【问题描述】:

我必须将一些代码从 PHP 7 重构到 PHP 8.2。我需要从父静态方法解析通过 call_user_func_array 调用它的子类。但是 callables 的语法在 PHP 8.2 中发生了变化,我找不到正确的语法。

类似的功能可以通过 Reflection 和 invokeArgs 使用相关对象作为参数使用非静态方法来解决。但是我不能对静态方法做同样的事情。或者我不知道该怎么做。而且我在网上也找不到任何解决方案。

我在 PHP 7 中使用的代码以及在 PHP 8.2 中的尝试。

有谁知道我必须使用的正确语法?

#########
# PHP 7
#########

if (preg_match('#^7#', phpversion()))
{
    class A {
        public static function getClassName() {
            return get_called_class() . ' '. implode(' ', func_get_args());
        }
    }

    class B extends A {
        public static function getClassName() {

            # do anything else

            return call_user_func_array([ 'parent', 'getClassName' ], func_get_args());
        }
    }

    echo B::getClassName('-', 'Hello!') . "\n"; # I wish it returns 'B - Hello!'
}

#########
# PHP 8
#########

if (preg_match('#^8#', phpversion()))
{
    class A {
        public static function getClassName() {
            return get_called_class() . ' ' . implode(' ', func_get_args());
        }
    }

    class B extends A {
        public static function getClassName() {

            # do anything else

            return call_user_func_array([ static::class, 'parent::getClassName' ], func_get_args()); # Deprecated. Returns 'B - Hello!'

            return (new \ReflectionMethod(parent::class, 'getClassName'))->invokeArgs(null, func_get_args()); # Returns 'A - Hello!'. KO

            return (new \ReflectionMethod(static::class, 'getClassName'))->invokeArgs(null, func_get_args()); # segmentation fault, infinite loop. Obvious.

            return call_user_func_array([ parent::class, 'getClassName' ], func_get_args()); # Returns 'A - Hello!'. KO

            return call_user_func_array([ 'parent', 'getClassName' ], func_get_args()); # Deprecated. Returns 'B - Hello!'
        }
    }

    echo B::getClassName('-', 'Hello!') . "\n"; # I wish it returns 'B - Hello!'
}

【问题讨论】:

    标签: php php-8.2


    【解决方案1】:

    我相信最干净的解决方案是使用扩展函数 args parent::getClassName(...func_get_args()) 调用父方法

    class A {
        public static function getClassName() {
            return get_called_class() . ' ' . implode(' ', func_get_args());
        }
    }
    
    class B extends A {
        public static function getClassName() {
    
            # do anything else
    
            return parent::getClassName(...func_get_args());
        }
    }
    
    echo B::getClassName('Hello!'); //'B - Hello!';
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-10-04
      • 1970-01-01
      • 2015-10-25
      • 2012-05-24
      • 1970-01-01
      • 2018-01-27
      • 2017-09-14
      相关资源
      最近更新 更多