Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

support property declaration for objects, like we have for arrays #2923

Closed
staabm opened this issue Jan 29, 2020 · 19 comments
Closed

support property declaration for objects, like we have for arrays #2923

staabm opened this issue Jan 29, 2020 · 19 comments

Comments

@staabm
Copy link
Contributor

staabm commented Jan 29, 2020

Feature request

would be great to have support for a phpdoc syntax which allows to describe the structure of a object, e.g. a stdClass

https://phpstan.org/r/78964e3e-117f-4e0f-8134-034f6017a5a3

initial psalm issue: vimeo/psalm#390
implemented in psalm via vimeo/psalm@4ec7903
psalm sandbox: https://psalm.dev/r/3b59c8aa2b

@szepeviktor
Copy link
Contributor

Developers mangle objects and although it is not the nicest thing in the world but definitely exists.

@rkrx
Copy link

rkrx commented Oct 13, 2021

Developers mangle objects and although it is not the nicest thing in the world but definitely exists.

The main reason you would want to use loose objects is that they have an advantage in memory-consumption when you pass them in the form of parameters to functions/methods.

You can get an array of objects directly from a database query and pass them around. Only arrays are passed by copy. Objects are passed by reference.

And it does not always make sense to create a class or an interface for each database result just to tell phpstan something. The overhead is partly not justifiable.

But it would definitely be useful to be able to define the properties of objects the way array keys are defined for an array:

/** @var array<int, object{a: string, b: int, c: float}> $objects */
$objects = $db->query(...)->fetchObjects();

@szepeviktor
Copy link
Contributor

@rkrx Please expect a big NO-NO from Ondřej.

@rkrx
Copy link

rkrx commented Oct 13, 2021

Please expect a big NO-NO from Ondřej.

That is just a suggestion. I can imagine that you can solve something like that in another way. But that's exactly how you would do it in Typescript and exactly how I would expect to declare properties for objects in PHP.

@puggan
Copy link

puggan commented Jul 20, 2022

Would be nice if it at least wouldn't fail the hole phpdoc just because the object-shape was used.
https://phpstan.org/r/b07bc838-ca4e-46af-ae0e-3ef323b1e7a5

The example above fails at level 0

@phpstan-bot
Copy link
Contributor

@puggan After the latest push in 1.10.x, PHPStan now reports different result with your code snippet:

@@ @@
- 9: PHPDoc tag @phpstan-type has invalid value (Unexpected token "{", expected '*/' at offset 41): Unexpected token "{", expected '*/' at offset 41
+PHP 8.2 (3 errors)
+==========
+
+ 9: Invalid type definition detected in type alias tStringObject.
 13: Access to an undefined property A::$b.
-14: Access to an undefined property A::$i.
+14: Access to an undefined property A::$i.
+
+PHP 7.1 – 8.1 (1 error)
+==========
+
+ 9: Invalid type definition detected in type alias tStringObject.
Full report

PHP 8.2 (3 errors)

Line Error
9 Invalid type definition detected in type alias tStringObject.
13 Access to an undefined property A::$b.
14 Access to an undefined property A::$i.

PHP 7.1 – 8.1 (1 error)

Line Error
9 Invalid type definition detected in type alias tStringObject.

@phpstan-bot
Copy link
Contributor

@puggan After the latest push in 1.10.x, PHPStan now reports different result with your code snippet:

@@ @@
- 9: PHPDoc tag @phpstan-type has invalid value (Unexpected token "{", expected '*/' at offset 41): Unexpected token "{", expected '*/' at offset 41
+PHP 8.2 (3 errors)
+==========
+
+ 9: PHPDoc tag @phpstan-type tStringObject has invalid value: Unexpected token "{", expected TOKEN_PHPDOC_EOL at offset 41
 13: Access to an undefined property A::$b.
-14: Access to an undefined property A::$i.
+14: Access to an undefined property A::$i.
+
+PHP 7.1 – 8.1 (1 error)
+==========
+
+ 9: PHPDoc tag @phpstan-type tStringObject has invalid value: Unexpected token "{", expected TOKEN_PHPDOC_EOL at offset 41
Full report

PHP 8.2 (3 errors)

Line Error
9 PHPDoc tag @phpstan-type tStringObject has invalid value: Unexpected token "{", expected TOKEN_PHPDOC_EOL at offset 41
13 Access to an undefined property A::$b.
14 Access to an undefined property A::$i.

PHP 7.1 – 8.1 (1 error)

Line Error
9 PHPDoc tag @phpstan-type tStringObject has invalid value: Unexpected token "{", expected TOKEN_PHPDOC_EOL at offset 41

@ondrejmirtes
Copy link
Member

Would be nice if it at least wouldn't fail the hole phpdoc just because the object-shape was used

It no longer does.

@gomeztoo
Copy link

gomeztoo commented Apr 5, 2023

I could use this feature. There are a fair number of data-sets that are passed around in our code in json-form.
Some data is stored in json-format in the database, and others are passed around between servers as encrypted hash paraeters.
While I can define the data shapes in array-form using @phpstan-type, it would be a bit neater (and probably a bit more easier to comprehend for others) if I could define object shapes rather than array shapes.

I know there is some code out there that you can use to load json-decoded data into a class (i.e. https://github.com/cweiske/jsonmapper), but that may not be suitable for every situation.

@phpstan-bot
Copy link
Contributor

@staabm After the latest push in 1.10.x, PHPStan now reports different result with your code snippet:

@@ @@
-3: PHPDoc tag @param has invalid value (object{foo:string} $o): Unexpected token "{", expected variable at offset 17
+3: PHPDoc tag @param for parameter $o contains unresolvable type.
 4: Access to an undefined property object::$foo.
Full report
Line Error
3 PHPDoc tag @param for parameter $o contains unresolvable type.
4 Access to an undefined property object::$foo.

@ondrejmirtes
Copy link
Member

As you can see from @phpstan-bot's message, I'm currently working on this, and live-tweeting the process: https://twitter.com/OndrejMirtes/status/1643873013731844096

@phpstan-bot
Copy link
Contributor

@staabm After the latest push in 1.10.x, PHPStan now reports different result with your code snippet:

@@ @@
-3: PHPDoc tag @param has invalid value (object{foo:string} $o): Unexpected token "{", expected variable at offset 17
+3: PHPDoc tag @param for parameter $o with type object{foo: string} is incompatible with native type object.
 4: Access to an undefined property object::$foo.
Full report
Line Error
3 PHPDoc tag @param for parameter $o with type object{foo: string} is incompatible with native type object.
4 Access to an undefined property object::$foo.

@phpstan-bot
Copy link
Contributor

@puggan After the latest push in 1.10.x, PHPStan now reports different result with your code snippet:

@@ @@
- 9: PHPDoc tag @phpstan-type has invalid value (Unexpected token "{", expected '*/' at offset 41): Unexpected token "{", expected '*/' at offset 41
+PHP 8.2 (2 errors)
+==========
+
 13: Access to an undefined property A::$b.
-14: Access to an undefined property A::$i.
+14: Access to an undefined property A::$i.
+
+PHP 7.1 – 8.1
+==========
+
+No errors
Full report

PHP 8.2 (2 errors)

Line Error
13 Access to an undefined property A::$b.
14 Access to an undefined property A::$i.

PHP 7.1 – 8.1

No errors

@phpstan-bot
Copy link
Contributor

@staabm After the latest push in 1.10.x, PHPStan now reports different result with your code snippet:

@@ @@
-3: PHPDoc tag @param has invalid value (object{foo:string} $o): Unexpected token "{", expected variable at offset 17
-4: Access to an undefined property object::$foo.
+No errors

@ondrejmirtes
Copy link
Member

Alright, we can consider this implemented 🎉 There's a few rough edges I need to smooth out after Easter but it's already working pretty well.

@domstubbs
Copy link

You really can’t beat thinking a feature would be neat, checking GitHub and discovering that it was implemented 30 minutes ago. Thanks for all of your work on this.

@ondrejmirtes
Copy link
Member

Object shapes support released in PHPStan 1.10.12: https://github.com/phpstan/phpstan/releases/tag/1.10.12

@tillkruss
Copy link

@ondrejmirtes OMG, amazing work! ❤️‍🔥

@github-actions
Copy link

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators May 14, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

9 participants