1

I have to refactor some code from PHP 7 to PHP 8.2. I need to resolve, from a parent static method, the child class that calls it via call_user_func_array. But the syntax of callables has changed in PHP 8.2 and I can't find the correct syntax.

Similar functionality can be resolved with non-static methods via Reflection and invokeArgs, using the related object as argument. But I can't do the same with static methods. Or I can't figure out how to do it. And I can't find any solution on the web either.

The code I used with PHP 7 and my attempts with PHP 8.2.

Does anyone know the correct syntax I have to use?

#########
# 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!'
}
simon.ro
  • 2,984
  • 2
  • 22
  • 36
Jomiquel
  • 45
  • 4

1 Answers1

1

I believe the cleanest solution is to just call the parent method with the spreaded function 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!';
simon.ro
  • 2,984
  • 2
  • 22
  • 36