Return type "self" in PHP abstract class

PHP 7.1

I am currently trying to create an abstract class to provide and define and partially implement the functionality of my "child classes".

Here I am using the following construction:

abstract class Parent {

    public static function fromDB(string $name = '') {
        $instance = new static();
        if (!empty($name)) {
            $instance->setName($name)->read();
        }
        return $instance;
    }

    public abstract function read();

    public abstract function setName(string $name): self;

}

      

Here PHP seems to understand that it is setName($name)

returning an object with a type Parent

, but PhpStorm indicates that read()

it cannot be called as a result, which would be the expected result.

Error message: Reference method not found in the topic class.

I'm not sure if this is a bug in PHP or PhpStorm, or more likely, I don't understand what I am doing ...

I read about late static binding and the following questions that partially discuss this issue, but I couldn't figure out how to fix it:

Thanks for your time and help.


EDIT: As shown below, I am trying to implement in child classes, for example:

public function setName(string $name = null): user {...}

      

which obviously doesn't work with return self

, but (IMO should) with static

, which is prohibited.

+3


source to share


3 answers


Your code example looks fine in PhpStorm 2017.2 (currently at EAP stage), but shows a warning in 2017.1.4.

enter image description here

This may have been fixed with WI-33991 or one of the related tickets.




You can get and try EAP 2017.2 build anytime from here: http://confluence.jetbrains.com/display/PhpStorm/PhpStorm+Early+Access+Program

It comes with its own 30-day license and can run in parallel with the current version (general IDE settings are stored in separate folders).

+4


source


self

will always reference the class containing it, never child classes . So when it Parent

says it returns :self

, it expects you to create a function that returns an instance Parent

. You need to have your child class declare that it does this directly. Instead of declaring a child element to setName

be returned :self

(which is an instance Child

), we declare that we are going to return our class Parent

directly. PHP considers this to be perfectly correct ( Child

is an instance Parent

)

We cannot use it :static

here because it static

is a reserved word in class definitions



abstract class ParentTest {

    public static function fromDB(string $name = '') {
        $instance = new static();
        if (!empty($name)) {
            $instance->setName($name)->read();
        }
        return $instance;
    }

    public abstract function read();

    public abstract function setName(string $name): self;

}

class Child extends ParentTest {
    public function read() {

    }

    public function setName(string $name) :ParentTest {
        return $this;
    }
}

$child = new Child();

      

The above code works without error

+1


source


Try changing static , static should indicate that you are returning an extending class that can remove the error.

It's a guess, but it's worth it.

public abstract function setName(string $name): static;

      

EDIT: Ok, I don't think it will do it, can you provide more information on this? What is the purpose of reading? fromDb? etc.?

-1


source







All Articles