1

Consider the following class structures:

trait MyTrait {
    public function definedFunction() {

    }
}

interface MyInterface {

}

class A {
     public function test() {
         if ($this instanceof MyInterface) {
              // my intelisense tells me that the definedFunction() is not defined
              $this->definedFunction();
         }
     }
}

class B extends A implements MyInterface {
     use MyTrait;
}

Could I tell somehow to my intellisense (with doc blocks or anything), that in that specific situation, definedFunction is indeed defined? The above code works, despite intelephense complaining about it, could I disable that complaint with a docblock or something?

On the other hand, is there any other way to restructure my code for intellisense to know about this method? Basically, am I doing something wrong here with this structure?

What I want to achieve is, the following: class A is a template class, which is extended by a bunch of other classes. Some of these other classes, should be able to use some common methods, but not all of them. Because I can not extend multiple classes in PHP, I tried resolving this with traits. If I happen upon one of this kind of classes, I implement an interface with it (to group it somehow for later accessibility), and tell it to use the defined trait, to get all the added functionalities. The function that I call test in the above example, is a function that ALL of the classes that extend class A must be able to access, but when a class implements MyInterface, that function should get some added functionalities. This is why I didn't put that into the trait I am defining.

Adam Baranyai
  • 3,635
  • 3
  • 29
  • 68
  • 1
    You should add [class_uses](https://stackoverflow.com/questions/46218000/how-to-check-if-a-class-uses-a-trait-in-php) check just to be completely safe as there's no guarantee that inheriting from MyInterface will get you access to definedFunction. Yes, it's a limitation of a language, but nevertheless. – Daniel Protopopov Feb 13 '20 at 09:00
  • @DanielProtopopov that still won't solve unfortunately my intelephense problem, but you are indeed right that it will make the code more secure. Any idea on how to codeblock that a function exists in php intelephense? – Adam Baranyai Feb 13 '20 at 09:18
  • I'm afraid not, as I'm using PHPStorm and haven't used intelephense at all, @Adam – Daniel Protopopov Feb 13 '20 at 09:41

1 Answers1

0

Based on the comments to the initial question, I've solved this by telling Intelephense (a PHP language server) that $this is definitely a class instance that implements the trait within the scope of the if statement. Note that I did have to also provide a namespace for this to work properly locally:

<?php

namespace Test;

trait MyTrait {
    public function definedFunction() {}
}

interface MyInterface {}

class A {
    public function test() {
        if ($this instanceof MyInterface) {
            /** @var MyTrait $this */
            $this->definedFunction();
        }
    }
}

class B extends A implements MyInterface {
    use MyTrait;
}
ahamilton9
  • 134
  • 10