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.
source to share
Your code example looks fine in PhpStorm 2017.2 (currently at EAP stage), but shows a warning in 2017.1.4.
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).
source to share
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
source to share
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.?
source to share