PHPdoc - defining object properties for an object of stdClass

13,343

Solution 1

Here it is 4 years later, and there still does not appear to be a way to annotate the properties of a stdClass object as originally described in your question.

Collections had been proposed in PSR-5, but that appears to have been shot down: https://github.com/php-fig/fig-standards/blob/211063eed7f4d9b4514b728d7b1810d9b3379dd1/proposed/phpdoc.md#collections

It seems there are only two options available:

Option 1:

Create a normal class representing your data object and annotate the properties.

class MyData
{
    /**
     * This is the name attribute.
     * @var string
     */
    public $name;

    /**
     * This is the age attribute.
     * @var integer
     */
    public $age;
}

Option 2:

Create a generic Struct type class as suggested by Gordon and extend it as your data object, using the @property annotation to define what generic values are possible to access with __get and __set.

class Struct
{
    /**
     * Private internal struct attributes
     * @var array
     */
    private $attributes = [];

    /**
     * Set a value
     * @param string $key
     * @param mixed $value
     */
    public function __set($key, $value)
    {
        $this->attributes[$key] = $value;
    }

    /**
     * Get a value
     * @param string $key
     * @return mixed
     */
    public function __get($key)
    {
        return isset($this->attributes[$key]) ? $this->attributes[$key] : null;
    }

    /**
     * Check if a key is set
     * @param string $key
     * @return boolean
     */
    public function __isset($key)
    {
        return isset($this->attributes[$key]) ? true : false;
    }
}

/**
 * @property string $name
 * @property integer $age
 */
class MyData extends Struct
{
    // Can optionally add data mutators or utility methods here
}

Solution 2

You have only two way to document the structure of the result class.

1.One can describe the structure in a comment text. For example:

class SomeClass 
{
    /**
     * Getting staff detail.
     * Result object has following structure:
     * <code>
     * $type - person type
     * $name - person name
     * $age - person age
     * </code>
     * @param string $id staff id number
     *
     * @return stdClass
     *
     */
    public function staffDetails($id){
        $object = new stdClass();
        $object->type = "person";
        $object->name = "dave";
        $object->age = "46";
        return $object;
    }
}

2.One can create a data type that will inheritance stdClass and it will have an annotation of a result object. For example:

/**
 * @property string $type Person type
 * @property string $name Person name
 * @property integer $age Person age
 */
class DTO extends stdClass
{}

And use it in your other classes

class SomeClass {

    /**
     * Getting staff detail.
     *
     * @param string $id staff id number
     *
     * @return DTO
     *
     */
    public function staffDetails($id){

        $object = new DTO();
        $object->type = "person";
        $object->name = "dave";
        $object->age = "46";

        return $object;
    }
}

In my opinion, this way is better than a description in the text comment because it makes the code more obvious

Solution 3

If you are using PHP 7, you can define anonymous class.

class SomeClass {
    public function staffDetails($id){
        $object = (new class() extends stdClass {
                public /** @var string  */ $type;
                public /** @var string  */ $name;
                public /** @var int     */ $age;
            });

        $object->type = "person";
        $object->name = "dave";
        $object->age  = 46;        

        return $object;
    }
}

It is working for my IDE (tested in NetBeans)

Share:
13,343
someuser
Author by

someuser

Updated on June 14, 2022

Comments

  • someuser
    someuser about 2 years

    I am trying to figure out if it is possible to use PHPdoc to define the object properties being returned by a function or a object method.

    Say I have the following class:

    class SomeClass {
        public function staffDetails($id){
    
            $object = new stdClass();
            $object->type = "person";
            $object->name = "dave";
            $object->age = "46";        
    
            return $object;
        }
    }
    

    Now, it is easy enough to define input parameters.

     /**
     * Get Staff Member Details
     * 
     * @param   string  $id    staff id number
     * 
     * @return  object
     */
    
    class SomeClass {
        public function staffDetails($id){
            $object = new stdClass();
            $object->type = "person";
            $object->name = "dave";
            $object->age = "46";        
    
            return $object;
        }
    }
    

    The question is is there a similar thing for defining properties of the output object (of a stdClass) returned by the method in question. So that another programmer does not have to open this class and manually look into the method to see what the return object is returning?