Home > Mobile >  PHP type hinting from object to my class, not possible?
PHP type hinting from object to my class, not possible?

Time:04-28

I've setup an abstract class that must execute methods from another instanciated class. So I setup an anonymous class that extends my abstract class and in the implemented method, I want to access the methods of that "other instanciated class", but for my IDE to help me to find the correct name of the methods and arguments, I must write somewhere the type.

abstract class blah
{
    protected object $reference;
    public function __construct(object $reference)
    {
        $this->reference = $reference;
        $this->hello();
    }
    abstract public function hello();
}

class world
{
    public function __construct()
    {
        new class($this) extends blah {
            public function hello()
            {
                $this->reference->display();
            }
        };
    }

    public function display()
    {
        echo 'hello world';
    }
}

new world();

I can't change the type from "object" to something else to allow my IDE to show the methods

public function __construct()
    {
        new class($this) extends blah {
            protected world $reference;
            public function hello()
            {
                $this->reference->display();
            }
        };
    }

this throws Fatal error: Type of blah@anonymous::$reference must be object (as in class blah)

I could copy the attribute "reference" to another variable and set a typehint to "world", but that's not the best

public function __construct()
    {
        new class($this) extends blah {
            protected world $reference;
            public function hello()
            {
                /** @var world $hello */
                $hello = $this->reference;
                $hello->display();
            }
        };
    }

what better solution do I have ?

edit: this seems to work, is it the best way ?

new class($this) extends blah {
            /** @var world $reference */
            protected object $reference;
            public function hello()
            {
                $this->reference->display();
            }
        };

CodePudding user response:

If you want it only for IDE, then use documentation block to overwrite type declaration (if IDE supports it):

/**
 * @property world $reference
 */
new class($this) extends blah {
    public function hello()
    {
        $this->reference->display();
    }
};

E.g. PHPStorm, while not supporting that for anonymous class, supports for normal class description:

enter image description here

CodePudding user response:

It's worth understanding why PHP is telling you that you can't change the property type. Since this is a protected property, it can be read and written by either the parent or child class. For instance, the parent class might have a method setReference which accepts any object and assigns it to the parameter, and the child class would inherit this. If the child class was able to re-define the property to only accept world objects, that method would break.

Essentially, by declaring a protected property on the base class, you are setting a contract for all child classes, and PHP is enforcing it for you. Since you don't actually use the property on the base class, this restriction isn't actually needed, in which case one option is simply not to define the property or constructor on the base class.

  • Related