How to declare a type of an object within an object?

How do I declare an object that is property of another object without reasigning it?

 
/** @var class_whatever $owhatever */
 
$owhatever->    this will work perfectly
 
$this->owhatever->   will not work for code completion
/** @var class_whatever $owhatever2 */ 
$owhatever2 = $this->owhatever;
$owhatever2->  works for code competion

 
Thanks Glenn
 
14 comments
Comment actions Permalink

Hi there,

Generally speaking: you cannot -- such type hinting works for top level only.

If you can edit original file (where that class is defined) you could add proper type-hint there (be it via @var before actual property or via @property in class-level comment)


Considering your example (you have $this which means you are in a class) you may do this:

/**
* @property MyClass $myProperty My Optional Description
*/
class SomeClass {
...


or (if this property is introduced in this class):

class  SomeClass {
    /** @var MyClass */
    protected $myProperty;
...

0
Comment actions Permalink

Thanks Andriy,

I tried your 2 options for code completion and neither seemed to work in the object itself.
Using either of your options in the object if I typed $this->myProperty-> code completion did not work.
Should it?

Glenn

0
Comment actions Permalink

Unless I misunderstood you...

<?php

class MyClass {
    public $prop1;
}


class BaseClass {
    protected $someObject;
}


/**
* @property MyClass $someObject
*/
class SomeClass extends BaseClass {


    protected function doSomething()
    {
        $this->someObject->
    }
}


screen02.png

screen01.png

0
Comment actions Permalink

Another:

<?php

class MyClass {
    public $prop1;
}


class SomeClass {

    /** @var MyClass */
    protected $someObject;


    protected function doSomething()
    {
        $this->someObject->
    }
}


screen01.png

0
Comment actions Permalink

Thanks Andriy,

You explanation is stellar.
I now see I can not use the protected in this case because the objects are unrelated.
For example I have a phone object and a company object and a address object and person object
The company object will have an array of person, phone, and address objects.
A person object will also have an array of phone and address and company objects.
This maybe a case that I have to get better with objects, but until I do...

While I see where your examples will work great for protected and inherited objects is there any way to define unrelated objects?
I am hoping there is a better solution than the one I came up with below.

/** @var class_whatever $owhatever2 */ 
$owhatever2 = $this->owhatever;
$owhatever2->  works for code competion


Glenn

0
Comment actions Permalink

Since I'm not 100% sure on what you have go tthere ... I cannot give you any better advice unless I see some sample code that I can copy-paste and play around (just like I did with my examples).

Can you provide such basic code?

0
Comment actions Permalink
 
Actually, my objects in arrays seem to work fine because foreach forces them to be variables which I can define.
 
It is the ones that are objects of an object that are an issue.
 
I believe this comes back to your first response that it is not possible.
 
class class_phone
{
    public $phone;
    public $type;
}

class class_company{
    public $ophone = "";
    
    function phone_codecompletion_issue()
    {
      /** @var class_phone $... */  // not sure how to define so it can work
       $this->ophone->   code completion does not work here
    }
 
function phone_codecompletion_works()
{
 
// ugly but it works
    /** @var class_phone $ophone2 */  
    $ophone2 = $this->ophone;
    $ophone2->    // code completion works here
}
   
Glenn
  

}

0
Comment actions Permalink

It's the case #2 and it's working:

<?php

class class_phone
{
    public $phone;
    public $type;
}

class class_company
{
    /** @var class_phone */
    public $ophone;

    function phone_codecompletion_issue()
    {
        $this->ophone->    //code completion does not work here
    }

    function phone_codecompletion_works()
    {

        // ugly but it works
        /** @var class_phone $ophone2 */
        $ophone2 = $this->ophone;
        $ophone2->    // code completion works here
    }
}


screen01.png

0
Comment actions Permalink

Actually, my objects in arrays seem to work fine because foreach forces them to be variables which I can define.

Sure .. but if defined properly in first place .. such re-definition in foreach each time may not be necessary.

Can you share a code sample for this as well?

0
Comment actions Permalink

Thanks Andriy,

Very elegant!
That is exactly what I was looking for!

Glenn

0
Comment actions Permalink

Hi Andriy,

The below works, however if there is a better way I am very interested.

 
class class_phone
{
    public $phone;
    public $ptype;
}

class class_company
{
    public $aophone = array();

    function loop_array()
    {
        /** @var class_phone $ophone */
        foreach ($this->aophone as $ophone) {
            $ophone->  // code completion works
        }
    }
}
  
Glenn
0
Comment actions Permalink

Same as before -- just use [] after type (which means it's an array of instances of such type)

screen01.png

P.S.
Have a read in your spare time -- it's still a proposal and not everything is supported, but you will have an idea: https://github.com/phpDocumentor/fig-standards/blob/master/proposed/phpdoc.md

1
Comment actions Permalink

Hi Andriy,

Your the best!
Is what you have answer in the PHPStorm documents?
I will try to take a read of the standards you sent.

Thanks
Glenn

0
Comment actions Permalink

Well .. that's PHPDoc .. and the link I gave you is for possible future "standard"/recommendation (same as PSR-0,1,2,3,4,etc) -- http://www.php-fig.org/faq/#what-does-psr-stand-for

0

Please sign in to leave a comment.