0

I have an example function in PHP (8.2) that returns an array. Inside this array there is also an object, more precisely stdClass.

I use PHPStan as a static analyzer tool. How can I specify this (object shapes) structure syntactically correct to use it in @phpstan-return using PHPStan Array shapes ?

The example function getBooks():

function getBook(): array
{
    $author = new stdClass();
    $author->firstName = 'John';
    $author->lastName = 'Doe';

    return [
        'id' => 12345,
        'title' => 'Whoever may help me deserves a big "Thank You!"',
        'authors' => $author,
    ];
}

What I already tried and is an invalid syntax:

/**
 * @phpstan-return array{
 *     id: int,
 *     title: string,
 *     authors: object{
 *         firstName: string,
 *         lastName: string,
 *     },
 * }
 */

What I definitely already know is, that the object { .. } part is the syntactically incorrect one here.

WebDevPassion
  • 422
  • 1
  • 4
  • 12
  • As of PHPStan v1.10 **object shapes** are **not supported** currently. Also see https://github.com/phpstan/phpstan/issues/2923 and https://github.com/phpstan/phpstan/issues/6892 and the PR https://github.com/phpstan/phpdoc-parser/pull/141 – WebDevPassion Mar 03 '23 at 14:24
  • I guess the natural question is: if you can describe the shape to a static analyser, why would you not describe that shape to PHP itself, by defining a named class? – IMSoP Jun 22 '23 at 13:36

2 Answers2

2

As of PHPStan 1.10.12 this is now possible:

https://phpstan.org/writing-php-code/phpdoc-types#object-shapes

So, for your case, that would be written:

/**
 * @return object{
 *     id: int,
 *     title: string,
 *     authors: object{
 *         firstName: string,
 *         lastName: string,
 *     },
 * }
 */
Sylver
  • 2,285
  • 3
  • 29
  • 40
0

You can define the associative array architecture with the array<keyType, valType|valType|...> pattern:

/** @return array<string, int|stdClass|string> */
function getBook(): array
{ ... }

PHPStan demo

or specify that it is a mixed array:

/** @return array<mixed> */
function getBook(): array
{ ... }
fusion3k
  • 11,568
  • 4
  • 25
  • 47