Michael Mallett Michael Mallett - 4 months ago 14
PHP Question

PHPStorm object reference error object within object

I have this code, which works fine

use path\to\class\ exampleClass;
class foo {
public function preparePortalService() {
$this->portalService = new exampleClass(array(), $this->getWsdl('portal'));
$portalservice_header = new \SoapHeader($this->getWsdl('portal'), 'SessionHeader', $header);
// Set the Session Header.
$this->portalService->__setSoapHeaders($portalservice_header);
}
}


in another file (which is being autoloaded successfully

namespace path\to\class\exampleClass;

class exampleClass extends \SoapClient {
public function __construct(array $options = array(), $wsdl = 'wsdl/Interface.xml')
}
}


However, I get a 'Field portalService not found in class foo' warning in PHPStorm (Note: not in the error logs, the code works fine).

Why is this, and how can I get it to recognise the object properties and methods?

EDIT: expanded, sorry for the formatting.

To clarify, the class methods and properties autocompletes are accessible through $portalService in phpstorm if I do this:

$portalService = new exampleClass(array(), $this->getWsdl('portal'));


But if I do this,

$this->portalService = $portalService;


then PHPStorm tells me it can't find it when I try this

$this->portalService->__setSoapHeaders($portalservice_header);

Answer

PHPStorm is nagging you because although your code will compile and run, it's not well designed. When you try to assign a new value to $this->portalService, the IDE looks around but cannot find any declaration for class property postalService. In short, you are assigning a value to a property that does not exist.

The code still runs because PHP, unlike some other languages, will infer that you intended to declare a class property and assign a value to it, even though you never actually declared it. The better design is to add a declaration:

class foo {
  private $postalService=null; //now you've formally declared the class property

  public function preparePortalService() {
    $this->portalService = ... // no problem. this property exists.
  }
}

You also mentioned that:

$portalService = new exampleClass... doesn't pose a problem

That's correct. On this line, you're not referring to a class property (eg: $this->postalService, but you are creating and setting a local variable.