How can I call a non-static function from an abstract class in PHP 8?

92 Views Asked by At

I want to update our current project that runs on PHP 7.2 but I got an issue that I cant resolve easily.

public function getCategories($type){...}

//In another file that dosent implements Category
$categories = Category::getCategories('xxx');

The issue I have is, that in PHP 8 you cant call non-static functions anymore staticly, but I also can't rewrite it to $categories = (new Category)->getCategories('xxx'); because its an abstract class.

As a temporary solution, I've considered converting getCategories into a static method. However, I'm concerned about potential side effects this change might have on the project.

Does anyone have a suggestion for handling this situation in PHP 8? Ideally, I'm looking for a solution that avoids modifying the method's static/non-static status while still complying with PHP 8's stricter standards.

2

There are 2 best solutions below

0
Álvaro González On

I can't think of any side effect you aren't already hitting in PHP/7. The method is already being called statically, so if it happens to try to access a class instance, it would be already crashing:

abstract class Category
{
    public $foo = [1, 2, 3];

    public function getCategories($type)
    {
        return $this->foo;
    }
}

class ChildCategory extends Category
{
}

// This works fine
$categories = (new ChildCategory())->getCategories('xxx');
var_dump($categories);

// Fatal error: Uncaught Error: Using $this when not in object context
$categories = Category::getCategories('xxx');
var_dump($categories);

Demo

If it isn't crashing, that proves it's static at its core, so you can just make it official:

abstract class Category
{
    public static function getCategories($type)
    {
        return [1, 2, 3];
    }
}

class ChildCategory extends Category
{
}

$categories = (new ChildCategory())->getCategories('xxx');
var_dump($categories);

$categories = Category::getCategories('xxx');
var_dump($categories);

Demo

Note that is perfectly fine to invoke a static method from a class instance.

0
Benilson On

You can call a non-static function from an abstract class in PHP 8 using anonymous classes extending the abstract class.

<?php
 
class Category {
    public function getCategories($type){
        $array = [
            'xxx' => 'foo',
            'yyy' => 'bar'
        ];
 
        return ($array[$type] ?? 'foo bar');
    }
}
 
echo (new class() extends Category {})->getCategories('xxx');

Demo