3

I have the following code in an application powered by Silex:

$uknownObj->unkownRef

$uknownObj being a dependency injection container.

I know that unkownRef is of instance MyCoolObj.

Now how can I tell IntelliJ / PhpStorm to actually help me with autocomplete of this said object?

Álvaro González
  • 142,137
  • 41
  • 261
  • 360
Toskan
  • 13,911
  • 14
  • 95
  • 185
  • 3
    possible workaround: assign unknownRef to a local variable and annotate it with /** @var MyCoolObj */ – xmoex Jan 26 '16 at 09:34
  • Hmm...if you don't know what `$uknownObj` is, how can you be sure what `unknownRef` is? That is more of a code smell than a UI problem, IMNSHO. – Piskvor left the building Jan 26 '16 at 09:36
  • 1
    how do you create the `$unknownObj`? – Michael Kunst Jan 26 '16 at 09:37
  • `$unkownObj` is created through the slim dependency injection, it's the injection object itself. – Toskan Jan 26 '16 at 09:39
  • @Piskvor well a code smell you say. You never know what you get anyways, php returns say an intval on success and an error object on error. You basically never know what you have, you always have to check. Thats the whole fun of dyn. typing if i am not wrong – Toskan Jan 26 '16 at 09:40
  • Don't get all offended, "smell" does not necessarily mean "wrong" - just "needs a closer look." All I'm saying is you are expecting $uknownObj to be some class, or at least a child of some abstract class - not "eh well, could be anything at all, even an int - but let's pretend we can reference an int's property, because that's a Totally Sane Thing To Do". In other words, there **is** an expectation what *might* be the object's class. – Piskvor left the building Jan 26 '16 at 09:46
  • 1
    @Piskvor, all DI containers suffer from this smell. Lack of hinting is the most annoying thing in Silex applications. – Alex Blex Jan 26 '16 at 09:51
  • 1
    @Álvaro González: This is **not** a duplicate of that. That is typehinting on variables, this is typehinting on *member* variables (where the object's class is not simply inferred by static analysis). – Piskvor left the building Jan 26 '16 at 09:54
  • @Piskvor You're right, of course. It's a fundamental detail I totally overlooked. – Álvaro González Jan 26 '16 at 10:00
  • So, the actual problem is "DI gets me some statically-unresolved object"? I have no knowledge of Silex, but had something similar with Zend: http://stackoverflow.com/questions/34317265/typehinting-through-zend-registryget-how-to-make-navigation-to-declaration – Piskvor left the building Jan 26 '16 at 10:00
  • 1
    Can you please edit the question and reflect the actual information about Silex dependency container. That's a fundamental piece of info! General purpose solutions are useless if you need to patch your frameworks core or something similar. – Álvaro González Jan 26 '16 at 10:02
  • **1)** Since that DIC is from Silex .. try installing **Silex plugin** **2)** The generic solution *could be* like this: declare your own class that extends that DIC (e.g. `class MySilexDIC extends SilexDIC`) now you can use PHPDoc to declare your custom methods/fields using `@method` or `@property`. Obviously, `$uknownObj` should be an instance of `MySilexDIC` in such case. – LazyOne Jan 26 '16 at 12:24

4 Answers4

4

Simply assign unkownRef to a variable and provide annotation like this.

/** @var MyCoolObj $obj */
$obj = $uknownObj->unkownRef;
mansoor.khan
  • 2,309
  • 26
  • 39
  • How does this answer qualify for a negative vote? Kindly explain. – mansoor.khan Jan 26 '16 at 11:54
  • 1
    Most likely reason for -1 is the fact that you need to use intermediate variable just for that. It's OK if it will be used more than once in this scope .. but pretty annoying for one time usages (unnecessary code just to satisfy an IDE). – LazyOne Jan 26 '16 at 12:28
  • @LazyOne your reason makes sense but the question did not specify the scope. – mansoor.khan Jan 26 '16 at 12:34
1

You can either use phpdoc comments as suggested by xmoex, or assert type with instanceof:

enter image description here

Alex Blex
  • 34,704
  • 7
  • 48
  • 75
  • wonder why someone would downvote it, if it works, it works. I personally like it even better than annotations in the doc, because, if we bet/know the object is certain instance, we can actually run the check, why not. – Toskan Jan 26 '16 at 10:41
  • Yep, would be nice to know. I use it quite often throwing `InvalidArgumentException`. – Alex Blex Jan 26 '16 at 11:16
1

You can use phpdoc in container class, this is what i use with Slim framework :

/**
* @property-read \Monolog\Logger logger
* @property-read \Slim\Views\Twig view
* @property-read \PDO db
*/
class Container extends PimpleContainer implements ContainerInterface
{
}
Yoann Kergall
  • 2,993
  • 5
  • 22
  • 23
0

I just solved this by creating just _ide_autocomplete.php file in the project root where I just created a dummy class with all the slim container key as property. Then in my routes, in the beginning I just put a phpblock like this

/** @var Dummy $this */

My source codes are articles are in https://blog.shaharia.com/slim-php-framework-phpstorm-ide-autocompletion-solution/

Shaharia Azam
  • 1,948
  • 19
  • 25