代码之家  ›  专栏  ›  技术社区  ›  Linesofcode

PhpStorm智能感知在方法链+多个类的情况下无法正常工作

  •  0
  • Linesofcode  · 技术社区  · 3 月前

    在处理多个类时,我在PhpStorm智能感知方面遇到了一些问题。这是我正在处理的结构:

    trait ContextTrait
    {
        public Subscriptions $subscription;
        
        public function setSubscription(Subscriptions $value): self 
        {
            $this->subscription = $value;
            
            return $this;
        }
    }
    
    abstract class Transaction
    {
        use ContextTrait;
        
        protected ?int $paymentMethodId = null;
        
        public function setPaymentMethodId(?int $value): self 
        {
            $this->paymentMethodId = $value;
    
            return $this;
        }
    }
    
    class Invoice extends Transaction
    {
        protected ?string $dueDate = null;
        
        public function setDueDate(?string $value): self
        {
            $this->dueDate = $value;
            
            return $this;
        }
    }
    

    这样初始化类时:

    $invoice = (new Invoice)
        ->setSubscription(...)
        ->setPaymentMethodId(...)
        ->setDueDate(...);
    

    我有以下问题:

    1. 智能感知(打字时)仅适用于函数 ->setSubscription ->setPaymentMethodId ,它不起作用 ->setDueDate .
    2. 紧迫的 F12 ->setDueDate 不起作用,它返回错误“找不到要转到的声明”。
    3. 功能 setDueDate 在类中显示为灰色,表示该函数从未在任何地方使用过。

    如果我使用不同的实例化方法(没有链接):

    $invoice = new Invoice;
    $invoice->setSubscription(...);
    $invoice->setPaymentMethodId(...);
    $invoice->setDueDate(...);
    

    一切都很完美。有什么办法可以解决这个问题吗?


    编辑 :

    PhpStorm向我展示了一个例子:

    1. 使用链式方法 :它没有显示 ->setDueDate 功能。

    enter image description here

    1. 不使用链式方法 :它显示了 ->setDueDate 功能。

    enter image description here

    1 回复  |  直到 3 月前
        1
  •  1
  •   hakre    3 月前

    与此同时,我试着 static [而不是 : self ]它确实有效,为什么?

    这可以用PHP语言来概括(PhpStorm的IntelliSense更好 代码完成 试图模仿它):

    self 是类本身,总是这样 混凝土 :

    abstract class Transaction
    {
        ...
        public function setPaymentMethodId(?int $value): self 
        {
            ...
            return $this;
        }
    }
    

    什么时候? 链式 ,代码完成解决 自己 Transaction :

    $invoice = (new Invoice)
        ->setSubscription(...)
        ->setPaymentMethodId(...) # resolves to Transaction
        ->setDueDate(...); # Transaction has no such method
    

    现在与 静止的 这变成了所谓的 Late Static Bindings .

    迟到意味着迟到(当它发生时),绑定意味着将 混凝土 类。由于抽象类不能被实例化,因此该类实际上从来不是纯粹的 自己 但这是从它延伸出来的,而且不是抽象的:

    class Invoice extends Transaction
    {
        ...
        public function setDueDate(?string $value): self
        {
            ...
        }
    }
    

    再次与 链式 : static setPaymentMethodId() ,the 混凝土 发票联 正在解决代码完成问题:

    $invoice = (new Invoice)
        ->setSubscription(...)
        ->setPaymentMethodId(...) # resolves to Invoice
        ->setDueDate(...); # Invoice has such a method
    

    到目前为止,这只是 静止的 vs。 自己 对于 晚期静态绑定 在PHP中。

    现在,IDE在链接过程中需要做什么(与单个链接相比 $object->方法() 调用)是在链中一个接一个地解决它。这增加了复杂性,我有根据的猜测是,分析器具有一定的解析深度,如果它看到 自己 它正在减少开销,以获得最佳的快速结果。

    特殊类上还有其他猜测机制,因为它们的工作方式类似于装饰器(例如可遍历的Iterator Iterator),如果你提示泛型(或如注释中指出的那样) 特点 ).

    一般来说,您还可以从使用接口中受益,因为它们很容易在IDE和PHP中查找。您还可以远离各种抽象或非抽象实现(通过使它们成为纯抽象类,在PHP中称为接口)。