Asked  7 Months ago    Answers:  5   Viewed   70 times

So, in PHPDoc one can specify @var above the member variable declaration to hint at its type. Then an IDE, for ex. PHPEd, will know what type of object it's working with and will be able to provide a code insight for that variable.

<?php
  class Test
  {
    /** @var SomeObj */
    private $someObjInstance;
  }
?>

This works great until I need to do the same to an array of objects to be able to get a proper hint when I iterate through those objects later on.

So, is there a way to declare a PHPDoc tag to specify that the member variable is an array of SomeObjs? @var array is not enough, and @var array(SomeObj) doesn't seem to be valid, for example.

 Answers

74

Use:

/* @var $objs Test[] */
foreach ($objs as $obj) {
    // Typehinting will occur after typing $obj->
}

when typehinting inline variables, and

class A {
    /** @var Test[] */
    private $items;
}

for class properties.

Previous answer from '09 when PHPDoc (and IDEs like Zend Studio and Netbeans) didn't have that option:

The best you can do is say,

foreach ($Objs as $Obj)
{
    /* @var $Obj Test */
    // You should be able to get hinting after the preceding line if you type $Obj->
}

I do that a lot in Zend Studio. Don't know about other editors, but it ought to work.

Wednesday, March 31, 2021
 
Bharanikumar
answered 7 Months ago
40

A single line is all you need:

/* @var $varName Type_Name */

See this article in the NetBeans PHP Blog: https://blogs.oracle.com/netbeansphp/entry/defining_a_variable_type_in

Note: At least, in version 8.2; The key seems to be:

  • The single asterisk (/* instead of /**).
  • Placing the type after the variable name.
  • Having nothing before and after the type-hinting (except white-space, but even that is not allowed when the comment is not in a single line).
Wednesday, March 31, 2021
 
Kwadz
answered 7 Months ago
66

PHP 7.4 will support typed properties like so:

class Person
{
    public string $name;
    public DateTimeImmutable $dateOfBirth;
}

PHP 7.3 and earlier do not support this, but there are some alternatives.

You can make a private property which is accessible only through getters and setters which have type declarations:

class Person
{
    private $name;
    public function getName(): string {
        return $this->name;
    }
    public function setName(string $newName) {
        $this->name = $newName;
    }
}

You can also make a public property and use a docblock to provide type information to people reading the code and using an IDE, but this provides no runtime type-checking:

class Person
{
    /**
      * @var string
      */
    public $name;
}

And indeed, you can combine getters and setters and a docblock.

If you're more adventurous, you could make a fake property with the __get, __set, __isset and __unset magic methods, and check the types yourself. I'm not sure if I'd recommend it, though.

Wednesday, March 31, 2021
 
Giovanni
answered 7 Months ago
10

mark used methods in phpdoc as @used example

/**
* @uses  _iAmUsed()
* @param string $whoAreYou
*/ 
public function run($whoAreYou)
{
    $methodName = '_iAm' . $whoAreYou;
    if (method_exists($this, $methodName)) {
        $this->$methodName();
    }
}
Wednesday, March 31, 2021
 
AlterPHP
answered 7 Months ago
33

Your problem is that you want to use type hints but you want this class itself to be able to take arguments of its own type.

The type hints PEP (0484) explains that you can use the string version of the type's name as a forward reference. The example there is of a Tree data structure which sounds remarkably similar to this OrgUnit one.

For example, this works:

class OrgUnit(object):

    def __init__(self,
                 an_org_name: str,
                 its_parent_org_unit: 'OrgUnit' = None
                 ):

In Python 3.7, you will be able to activate postponed evaluation of annotations with from __future__ import annotations. This will automatically store annotations as strings instead of evaluating them, so you can do

from __future__ import annotations

class OrgUnit(object):
    def __init__(self,
                 an_org_name: str,
                 its_parent_org_unit: OrgUnit= None
                 ):
        ...

This is scheduled to become the default in Python 4.0.

Saturday, July 3, 2021
 
Sufi
answered 4 Months ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :