PHPDoc 包装器对象属性

问题描述

遇到卡住的情况,会产生不必要的 IDE 警告,并可能导致清理使用过的代码

我认为最好的解决方案是在正确的位置添加一些 PHPDoc,但由于一些限制,还没有找到正确的位置,如下面的示例所述。

IDE:PHPStorm

结果:

<?PHP

/*
 * Generic result class,widely used,so can't touch it ¯\_(ツ)_/¯
 */
class Result {
  public $data;

  public function __construct() {
    return $this;
  }

  public function setData($data) {
    $this->data = $data;
    return $this;
  }
}

客户:

<?PHP

class Customer {
  public string $name  = '';
  public string $email = '';

  public function __construct() {
    $this->name = 'John Smith';
    $this->email = 'test@example.com';
  }

  public function getCustomer(): Result {
    return (new Result())->setData(new self());
  }

  public function reverseName(): string { // ❌ Unused element: 'reverseName'
    $parts = explode(' ',$this->name);
    return implode(' ',array_reverse($parts));
  }
}

控制器:

<?PHP

require_once 'vendor/autoload.PHP';

$john = (new Customer())->getCustomer();
// ℹ️ $john->data is an instance of the Customer class.
// How should I tell to the IDE this ^ ❓
$reversedname = $john->data->reverseName(); // ❌ Cannot find declaration to go when trying to navigate to the method
exit($reversedname);

尝试了很多选项,但唯一有效的方法是将 PHPDoc 添加Result$data 属性。不能碰它,因为它在项目中广泛使用...

LE:Customer 类有很多类似于 reverseName()方法,因此将 data 属性分配给新变量也很难写:/** @var Customer $john */ $john = (new Customer())->getCustomer()->data;

解决方法

您可以尝试使用另一个名为 advanced metadata 的 PhpStorm 功能。

首先你需要在接下来的方式中配置元数据

namespace PHPSTORM_META {
    override(\App\Result::getData(0),map(['' => '@']));
}

然后将 getter 添加到您的 Result

public function getData()
{
    return $this->data;
}

并在接下来的方式中使用这个 getter

$john->getData(Customer::class)->reverseName();

主要思想是使用类名作为 getter 方法的参数,PhpStorm 会知道这个 getter 将返回什么类对象。