Resolve "Undefined method"

Hi everyone,

I am used to R# for C# development and just love the Global error analysis. Now, when I do PHP, all my files are filled with red squiggly lines because PhpStorm is unable to infer types and so points out undefined methods and fields all over the code. I would really like to use this for me and help PhPStorm to infer correct types. I have not found a way to annotate code with the correct types, though.

Consider this code:

class A {
  function getChildren() {
    return %some array of class B%
  }
}

function calculateSomething(A a) {
  foreach(a->getChildren() as $b) {
     $b->DoSomething();
  }
}

$b->DoSomething is marked as undefined method. How do I tell PhPStorm that $b is of type B?

Thanks,
Alexander

12 comments
Comment actions Permalink

Hi Alexander,

This will do:

function calculateSomething(A a) {
  foreach(a->getChildren() as $b) {
     /** @var $b B */

     $b->DoSomething();
  }
}

as well as this (the only difference is the possition of PHPDoc comment):

function calculateSomething(A a) {
  /** @var $b B */

  foreach(a->getChildren() as $b) {

     $b->DoSomething();

  }
}


You may also want to add PHPDoc comment for getChildren() function (although I not 100% sure that this will solve foreach without extra local PHPDoc block (which we did above) -- at least in current PhpStorm builds):

  /**
   * @return B[]

   */

  function getChildren() {
    return %some array of class B%
  }

0
Comment actions Permalink

I will try this and report back

0
Comment actions Permalink

@return B[]
is most proper way and will work with foreach.

0
Comment actions Permalink

I must be getting it wrong:

class A {
  //@var $b B
  private $b;

  //@return B
  function getB() {
    return $this->b;
  }
}

class B {
  function foo() {
    //Whatever
  }
}

$a = new A();
$a->getB()->foo();


foo() in the last line is undefined. I even added the //@return B comment for the function getB(), which should not be necessary. PhPStorm 2.0.1.

Also, when I add the //@var $b B and there is no class B, there is no error shown, but should show.
0
Comment actions Permalink

What are these //@var $b B and  //@return B ?

These are just normal comments. You need PHPDoc comments:
/** @var $b B */ and /** @return B */ respectively.

0
Comment actions Permalink

OK, now that works, at least on my test file. I have to see why it is not working on my production code.

And still, I can state that getB returns B, even if there is no class B without an error message. Or even better a quickfix that allows you to quickly create a class B.

Or yet even better, fills the class with all the code that I want to put in it, so I can go home by 9:01 am and have my days work done ;-)

Thanks a lot

0
Comment actions Permalink

Ah, this is so beautiful, no I can get rid of all that squiggly lines, except for those from database statement: $row->someFieldFromTheDB - I guess I will just turn the undefined field feature off, I can't see a way to solve this in a nice way.

Is there a shortcut for creating the PHPDOC comments easier than typing them by hand?

0
Comment actions Permalink
Is there a shortcut for creating the PHPDOC comments easier than typing them by hand?

For function/method: type /** on the line above function declaration and press Enter (for multi-line comment)

/**<ENTER>
public function doSomething($someParam = 123)
{
...
}

+ the latest EAP build has "Generate PHPDoc" action (have not tested it myself yet).

For fields/variables: type /** and press Space (for single-line comment).

Regardless of situation PhpStorm will fill as much details as it can.

except for those from database statement: $row->someFieldFromTheDB

If you can -- fetch result row as an array instead of object: $row['someFieldFromTheDB'].

When this ticket will be implemented we may try and treat $row as stdClass (PhpStorm *should* ignore all unknown fields for such class).

0
Comment actions Permalink

Perfect. Now I am satisfied - you guys at JetBrains are doing a tremendous job! Thanks a bunch!

0
Comment actions Permalink

I'm not part of JetBrains - but Alexey is (see the JB overlay icon over avatar :) )

0
Comment actions Permalink

Ah, sorry - I just saw a slavik name and presumed. Note to self: Not everybody with a russion-sounding name works at Jetbrains.;)

Thanks anyway, Andriy.

The praise to Jetbrains remains, though.

0
Comment actions Permalink

And we very grateful you for your kind assistance, Andriy :)

0

Please sign in to leave a comment.