Return 在摘要中输入 "self" PHP class
Return type "self" in abstract PHP class
PHP 7.1
我目前正在尝试制作一个抽象 class 来提供和定义并部分实现其子 classes 的功能。
这里我使用了以下结构:
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;
}
这里PHP好像理解setName($name)
return是一个Parent
类型的Object,但是PhpStorm提示read()
不能在结果,这本来是预期的结果。
Error Message: Referenced Method is not found in subject class.
我不确定这是 PHP 还是 PhpStorm 中的错误,或者更可能的是,我不明白我在做什么...
我已经阅读了 Late static binding 和以下部分讨论这个问题的问题,但我不知道如何解决它:
- Question 2
- Late Static Binding Doc
感谢您的宝贵时间和帮助。
编辑: 如下所示,我正在尝试在子 classes 中实现,例如:
public function setName(string $name = null): user {...}
这显然不适用于 self
return 但(IMO 应该)与 static
一起使用,这是被禁止的。
尝试更改为 return static,static 应该表明您正在 return 扩展 class,这可能会消除错误。
这是猜测,但值得一试。
public abstract function setName(string $name): static;
编辑:好的,我认为这不行,您能否提供有关该问题的更多信息?读书的目的是什么?来自数据库?等等?
self
将总是引用class它的,从不children class es。因此,当 Parent
对 return :self
说时,它期望您创建一个 return 是 Parent
实例的函数。您需要做的是让您的 child class 声明它直接这样做。我们没有声明 child 的 setName
将 return :self
(这是 Child
的一个实例),而是声明我们将要 return 我们的 Parent
class 直接。 PHP 认为这是完全有效的(Child
毕竟是 Parent
的一个实例)
我们不能在这里使用 :static
因为 static
是 class 定义中的保留字
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();
您的代码示例在 PhpStorm 2017.2(目前处于 EAP 阶段)中看起来不错,但在 2017.1.4 中显示警告。
很可能它已被 WI-33991 或其中一张相关票证修复。
您可以随时从此处获取并试用 2017.2 EAP 版本:http://confluence.jetbrains.com/display/PhpStorm/PhpStorm+Early+Access+Program
它带有自己的 30 天许可证,可以 运行 与您当前的版本并行(IDE-wide 设置存储在单独的文件夹中)。
恕我直言,有一种智能且可靠的接口使用方法。
对于应该由第 3 方使用的库来说甚至是必需的。
所以,我们只是将接口名称设置为一个类型,而不是所有父 类 中的 'self',并继续为子 'self' 使用
<?php
interface EntityInterface
{
public function setName(string $name): EntityInterface;
}
abstract class ParentTest implements EntityInterface
{
public abstract function read();
public abstract function setName(string $name): EntityInterface;
}
class Child extends ParentTest
{
private string $name = '';
public function read(): string
{
return $this->name;
}
public function setName(string $name): self
{
$this->name = $name;
return $this;
}
}
$child = new Child();
echo $child->setName('hello')->read();
PHP 7.1
我目前正在尝试制作一个抽象 class 来提供和定义并部分实现其子 classes 的功能。
这里我使用了以下结构:
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;
}
这里PHP好像理解setName($name)
return是一个Parent
类型的Object,但是PhpStorm提示read()
不能在结果,这本来是预期的结果。
Error Message: Referenced Method is not found in subject class.
我不确定这是 PHP 还是 PhpStorm 中的错误,或者更可能的是,我不明白我在做什么...
我已经阅读了 Late static binding 和以下部分讨论这个问题的问题,但我不知道如何解决它:
- Question 2
- Late Static Binding Doc
感谢您的宝贵时间和帮助。
编辑: 如下所示,我正在尝试在子 classes 中实现,例如:
public function setName(string $name = null): user {...}
这显然不适用于 self
return 但(IMO 应该)与 static
一起使用,这是被禁止的。
尝试更改为 return static,static 应该表明您正在 return 扩展 class,这可能会消除错误。
这是猜测,但值得一试。
public abstract function setName(string $name): static;
编辑:好的,我认为这不行,您能否提供有关该问题的更多信息?读书的目的是什么?来自数据库?等等?
self
将总是引用class它的,从不children class es。因此,当 Parent
对 return :self
说时,它期望您创建一个 return 是 Parent
实例的函数。您需要做的是让您的 child class 声明它直接这样做。我们没有声明 child 的 setName
将 return :self
(这是 Child
的一个实例),而是声明我们将要 return 我们的 Parent
class 直接。 PHP 认为这是完全有效的(Child
毕竟是 Parent
的一个实例)
我们不能在这里使用 :static
因为 static
是 class 定义中的保留字
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();
您的代码示例在 PhpStorm 2017.2(目前处于 EAP 阶段)中看起来不错,但在 2017.1.4 中显示警告。
很可能它已被 WI-33991 或其中一张相关票证修复。
您可以随时从此处获取并试用 2017.2 EAP 版本:http://confluence.jetbrains.com/display/PhpStorm/PhpStorm+Early+Access+Program
它带有自己的 30 天许可证,可以 运行 与您当前的版本并行(IDE-wide 设置存储在单独的文件夹中)。
恕我直言,有一种智能且可靠的接口使用方法。 对于应该由第 3 方使用的库来说甚至是必需的。
所以,我们只是将接口名称设置为一个类型,而不是所有父 类 中的 'self',并继续为子 'self' 使用
<?php
interface EntityInterface
{
public function setName(string $name): EntityInterface;
}
abstract class ParentTest implements EntityInterface
{
public abstract function read();
public abstract function setName(string $name): EntityInterface;
}
class Child extends ParentTest
{
private string $name = '';
public function read(): string
{
return $this->name;
}
public function setName(string $name): self
{
$this->name = $name;
return $this;
}
}
$child = new Child();
echo $child->setName('hello')->read();