Core concepts

Generic types

PHP autodoc makes use of generic types in the analyzed code base.

Example 1

This example demonstrates the support for generics in PHP class and how PHP autodoc understands array destructuring to determine possible array values.

/**
 * @template T
 */
class GenericClass
{
    public function __construct(
        /**
         * @var T
         */
        public $data,
    ) {}
}
public function genericExample1(): array
{
    $animals = ['cat', 'dog', 'capybara'];

    return [
        'with_int_parameter' => new GenericClass(rand()),
        'with_string_parameter' => new GenericClass('test'),
        'with_array_parameter' => new GenericClass([
            'elephant',
            ...$animals,
        ]),
    ];
}

Example 2

This example demonstrates extension of generic class and how PHP autodoc remembers class-string variables to determine constructed instance type even when it is not specified using PHPDoc annotations.

/**
 * @extends GenericClass<int>
 */
class ClassExtendingGenericClass extends GenericClass
{
    public function __construct(
        public int $n,
    ) {
        parent::__construct($n);
    }
}
public function genericExample2(): array
{
    $integer = 1;
    $date = new \DateTime();

    return [
        'generic' => $this->getInstanceWithPhpDoc(
            className: GenericClass::class,
            classConstructorParam: $date,
        ),
        'generic_without_phpdoc' => $this->getInstance(
            className: GenericClass::class,
            classConstructorParam: $date,
        ),
        'extended' => $this->getInstanceWithPhpDoc(
            className: ClassExtendingGenericClass::class,
            classConstructorParam: $integer,
        ),
        'extended_without_phpdoc' => $this->getInstance(
            className: ClassExtendingGenericClass::class,
            classConstructorParam: $integer,
        ),
    ];
}

/**
 * @template TClass of GenericClass
 * @template TParam
 *
 * @param class-string<TClass> $className
 * @param TParam $classConstructorParam
 *
 * @return TClass<TParam>
 */
private function getInstanceWithPhpDoc(
    string $className,
    mixed $classConstructorParam,
): object
{
    return new $className($classConstructorParam);
}

/**
 * In some cases, when the class name is hard-coded, autodoc can
 * determine what class is being constructed from variable.
 * 
 * In this case the return type is analyzed from method body
 * since `@return` tag is not specified.
 */
private function getInstance(
    string $className,
    mixed $classConstructorParam,
): mixed
{
    return new $className($classConstructorParam);
}