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
PHP8.2 - Interface property annotation not found inside class #8550
Comments
I'm hesitant to support this, because |
I understand. However this is a big shortcut when there's a lot of magic methods and properties involved, like Laravel's Model for example. Another example with magic methods : https://phpstan.org/r/02a7420c-a73a-473d-b5f6-241e19e0e387 Using the property on the This is simply a shortcoming of PHP Interfaces. |
For laravel models you can add |
Adding But your exemple shows something interesting:
It makes no sense that 3 doesn't work if 1 does while 2 doesn't. |
Having the same problem since updating to PHP8.2. @lcharette did you find a fix? Besides the getter/setter? |
This was allowed with versions before PHP 8.2. Maybe shouldn't have because the language itself doesn't support it. Although you could argue the language should probably allow this, like many other languages have support for properties. The PHP manual states that you should use abstract classes instead. But that's not always what you want. |
We also commonly use this technique. |
Adding
I guess it would be good if phpstan would report if indeed given property was defined on the interface but is not defined on the class, ie if https://phpstan.org/r/57b63210-3875-4f28-871c-cf97d91ef779 would error edit: apologies - idk if I was running 8.2 or not, but today I'm getting |
Considering my case is mostly Database Models, I could use the Universal object crates, add each model Interface in my config and the error would be suppressed. However, this isn't a perfect solution. If my No other solution provided by the new blog post seams applicable in this case. As @eithed noted,
Consider this other example :
This is still an issue IMO. On the new blog post, in Add @property PHPDoc, a warning about this issue should be added too. |
I am currently seeing this issue on 8.2, without it being an interface. Something as simple as this: https://phpstan.org/r/7a7162bc-f3fc-45c3-b3c6-dadf6969e38b |
@solomonjames Have you read the linked article? https://phpstan.org/blog/solving-phpstan-access-to-undefined-property |
@ondrejmirtes Ok, I just realized my specific problem... The vendor library has their docblocks like so /**
* @property string name
*/ instead of /**
* @property string $name
*/ I was able to resolve it with a stub. Thank you! |
@solomonjames please open a PR in the vendor lib for that change too if you can and didn't do already 😊 |
This is fixable by patching https://github.com/phpstan/phpstan-src/blob/19c838bbe9576c83c95ebb1f9fedd5e5b8664306/src/Reflection/ClassReflection.php#L380
would a PR to allow this be accepted? Could put it behind a feature Flag if required |
We have used this to workaround the issue for now, all our concrete classes are laravel models so they have __set
|
The hack @JasonEleventeen applied should be unnecessary. I am in a similar situation that interfaces are annotated with Applying the The documentation indicates that the annotated properties are detected if these magic methods are present: Therefore, I expect it to work now with the mixin applied. However, it still does not work. Applying the hack from @JasonEleventeen does fix it though. Furthermore, it is not detecting any magic properties from the This seems more like a bug than a feature request. @ondrejmirtes Example code. /**
* @property-read Collection<int,Statusable> $statuses
*
* @mixin \Eloquent */
interface StatusableInterface
{
public function statuses(): HasMany;
}
|
This is now possible to solve with See an example: https://phpstan.org/r/2dec4d59-482d-4894-ba05-0c2453e28f2b When the typehinted interface is implemented by a class, it requires the class to extend a class in The class can then declare the property as native or via other means like |
@phpstan-require-extends does not fix the general underlying issue, we might as well use DTO's instead if we have to write a base model for every interface.. |
@JasonEleventeen The question you should ask is: How do the properties work in the actual app? When you typehint the interface and access those properties, what's the actual implementation that makes them work? That's your class that you should put in |
If the interface depends on the model whats the point of the interface? |
@JasonEleventeen Interfaces in PHP do not support properties at all. We found a way to do it but it requires usage of |
PHP does not support generics either, that's part why we use phpstan and this did work previously, if its a definite will not fix that's fine, but I don't think the @phpstan-require-extends workaround is an actual fix |
@JasonEleventeen I'd like to know about your specific use case #8550 (comment). You must have "some" reason to "declare" properties on an interface. I'd like to know how it works in your code. Feel free to open a new discussion about this. |
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. |
Bug report
Similar to #8537, when a property is documented in an interface
@property
annotation, it's not recognized by classes using this interface. This is not an issue on PHP 8.0 and 8.1.Code snippet that reproduces the problem
https://phpstan.org/r/75fa6a47-cbc4-4eb3-b5eb-cf4851f6b805
Access to an undefined property SomeInterface::$var.
Expected output
No errors!
Did PHPStan help you today? Did it make you happy in any way?
PHPStan helped me become a better PHP dev :)
The text was updated successfully, but these errors were encountered: