phpstan
phpstan copied to clipboard
ext/xml: set_*_handler() functions allows to set relative method names for callables
While doing some refactoring on ext/xml I discovered that the callable handler parameter has some rather strange semantics, in that it allows to set a method name to be called on the object set via xml_set_object()
Don't know if you want to fix this, but just raising awareness.
https://phpstan.org/r/cacb12c0-9730-41db-a969-f23ca0d27351
Related to:
- https://github.com/php/php-src/pull/12340
- https://github.com/php/doc-en/pull/2832
I'd say that the parameter isn't of a callable type but generally a mixed type, or callable-array|string at best. That would get rid us of the error.
I'm checking the php-src stubs (extracted for PHPStan purposes) - the PHPDoc callable type should disappear: https://github.com/phpstan/php-8-stubs/blob/main/stubs/ext/xml/xml_set_character_data_handler.php
If we wanted then to check invalid inputs, we'd need a special rule with implemented logic for these scenarios.
While working on the PR I'd consider the type to be "really" callable|string|null, as you can pass a normal callable string too. But maybe that's what callable-array|string is for?
Note the docs are currently saying that false is accepted to unset the handler which is true, but any value that cast to string which is an empty string has this behaviour.
The plan however is to make null (and empty strings for the time being) be the only way to disable a handler (so false would be coerced to an empty string in weak typing mode).
Oh yeah, sure, there are other callables like an object with __invoke, so callable|string|null is correct.
@Girgias After the latest push in 1.12.x, PHPStan now reports different result with your code snippet:
@@ @@
+PHP 8.4 (14 errors)
+==========
+
+ 5: Property XML_Parser::$dummy has no type specified.
+ 7: Method XML_Parser::parse() has no return type specified.
+ 7: Method XML_Parser::parse() has parameter $data with no type specified.
+13: Parameter #2 $start_handler of function xml_set_element_handler expects (callable(): mixed)|null, 'startHandler' given.
+13: Parameter #3 $end_handler of function xml_set_element_handler expects (callable(): mixed)|null, 'endHandler' given.
+20: Tip: Method XML_Parser::startHandler() always throws an exception, it should have return type "never".
+20: Method XML_Parser::startHandler() has no return type specified.
+20: Method XML_Parser::startHandler() has parameter $XmlParser with no type specified.
+20: Method XML_Parser::startHandler() has parameter $attr with no type specified.
+20: Method XML_Parser::startHandler() has parameter $tag with no type specified.
+26: Method XML_Parser::endHandler() has no return type specified.
+26: Method XML_Parser::endHandler() has parameter $XmlParser with no type specified.
+26: Method XML_Parser::endHandler() has parameter $tag with no type specified.
+31: Class XML_Parser referenced with incorrect case: Xml_Parser.
+
PHP 8.0 – 8.3 (14 errors)
==========
Full report
PHP 8.4 (14 errors)
| Line | Error |
|---|---|
| 5 | Property XML_Parser::$dummy has no type specified. |
| 7 | Method XML_Parser::parse() has no return type specified. |
| 7 | Method XML_Parser::parse() has parameter $data with no type specified. |
| 13 | `Parameter #2 $start_handler of function xml_set_element_handler expects (callable(): mixed) |
| 13 | `Parameter #3 $end_handler of function xml_set_element_handler expects (callable(): mixed) |
| 20 | Tip: Method XML_Parser::startHandler() always throws an exception, it should have return type "never". |
| 20 | Method XML_Parser::startHandler() has no return type specified. |
| 20 | Method XML_Parser::startHandler() has parameter $XmlParser with no type specified. |
| 20 | Method XML_Parser::startHandler() has parameter $attr with no type specified. |
| 20 | Method XML_Parser::startHandler() has parameter $tag with no type specified. |
| 26 | Method XML_Parser::endHandler() has no return type specified. |
| 26 | Method XML_Parser::endHandler() has parameter $XmlParser with no type specified. |
| 26 | Method XML_Parser::endHandler() has parameter $tag with no type specified. |
| 31 | Class XML_Parser referenced with incorrect case: Xml_Parser. |
PHP 8.0 – 8.3 (14 errors)
| Line | Error |
|---|---|
| 5 | Property XML_Parser::$dummy has no type specified. |
| 7 | Method XML_Parser::parse() has no return type specified. |
| 7 | Method XML_Parser::parse() has parameter $data with no type specified. |
| 13 | Parameter #2 $start_handler of function xml_set_element_handler expects callable(): mixed, 'startHandler' given. |
| 13 | Parameter #3 $end_handler of function xml_set_element_handler expects callable(): mixed, 'endHandler' given. |
| 20 | Tip: Method XML_Parser::startHandler() always throws an exception, it should have return type "never". |
| 20 | Method XML_Parser::startHandler() has no return type specified. |
| 20 | Method XML_Parser::startHandler() has parameter $XmlParser with no type specified. |
| 20 | Method XML_Parser::startHandler() has parameter $attr with no type specified. |
| 20 | Method XML_Parser::startHandler() has parameter $tag with no type specified. |
| 26 | Method XML_Parser::endHandler() has no return type specified. |
| 26 | Method XML_Parser::endHandler() has parameter $XmlParser with no type specified. |
| 26 | Method XML_Parser::endHandler() has parameter $tag with no type specified. |
| 31 | Class XML_Parser referenced with incorrect case: Xml_Parser. |
PHP 7.2 – 7.4 (14 errors)
| Line | Error |
|---|---|
| 5 | Property XML_Parser::$dummy has no type specified. |
| 7 | Method XML_Parser::parse() has no return type specified. |
| 7 | Method XML_Parser::parse() has parameter $data with no type specified. |
| 13 | Parameter #2 $shdl of function xml_set_element_handler expects callable(): mixed, 'startHandler' given. |
| 13 | Parameter #3 $ehdl of function xml_set_element_handler expects callable(): mixed, 'endHandler' given. |
| 20 | Tip: Method XML_Parser::startHandler() always throws an exception, it should have return type "never". |
| 20 | Method XML_Parser::startHandler() has no return type specified. |
| 20 | Method XML_Parser::startHandler() has parameter $XmlParser with no type specified. |
| 20 | Method XML_Parser::startHandler() has parameter $attr with no type specified. |
| 20 | Method XML_Parser::startHandler() has parameter $tag with no type specified. |
| 26 | Method XML_Parser::endHandler() has no return type specified. |
| 26 | Method XML_Parser::endHandler() has parameter $XmlParser with no type specified. |
| 26 | Method XML_Parser::endHandler() has parameter $tag with no type specified. |
| 31 | Class XML_Parser referenced with incorrect case: Xml_Parser. |
@Girgias After the latest push in 2.1.x, PHPStan now reports different result with your code snippet:
@@ @@
5: Property XML_Parser::$dummy has no type specified.
7: Method XML_Parser::parse() has no return type specified.
7: Method XML_Parser::parse() has parameter $data with no type specified.
-13: Parameter #2 $start_handler of function xml_set_element_handler expects callable(): mixed, 'startHandler' given.
-13: Parameter #3 $end_handler of function xml_set_element_handler expects callable(): mixed, 'endHandler' given.
+13: Parameter #2 $start_handler of function xml_set_element_handler expects (callable(): mixed)|null, 'startHandler' given.
+13: Parameter #3 $end_handler of function xml_set_element_handler expects (callable(): mixed)|null, 'endHandler' given.
20: Tip: Method XML_Parser::startHandler() always throws an exception, it should have return type "never".
20: Method XML_Parser::startHandler() has no return type specified.
20: Method XML_Parser::startHandler() has parameter $XmlParser with no type specified.
Full report
PHP 8.0 – 8.3 (14 errors)
| Line | Error |
|---|---|
| 5 | Property XML_Parser::$dummy has no type specified. |
| 7 | Method XML_Parser::parse() has no return type specified. |
| 7 | Method XML_Parser::parse() has parameter $data with no type specified. |
| 13 | `Parameter #2 $start_handler of function xml_set_element_handler expects (callable(): mixed) |
| 13 | `Parameter #3 $end_handler of function xml_set_element_handler expects (callable(): mixed) |
| 20 | Tip: Method XML_Parser::startHandler() always throws an exception, it should have return type "never". |
| 20 | Method XML_Parser::startHandler() has no return type specified. |
| 20 | Method XML_Parser::startHandler() has parameter $XmlParser with no type specified. |
| 20 | Method XML_Parser::startHandler() has parameter $attr with no type specified. |
| 20 | Method XML_Parser::startHandler() has parameter $tag with no type specified. |
| 26 | Method XML_Parser::endHandler() has no return type specified. |
| 26 | Method XML_Parser::endHandler() has parameter $XmlParser with no type specified. |
| 26 | Method XML_Parser::endHandler() has parameter $tag with no type specified. |
| 31 | Class XML_Parser referenced with incorrect case: Xml_Parser. |
PHP 7.2 – 7.4 (14 errors)
| Line | Error |
|---|---|
| 5 | Property XML_Parser::$dummy has no type specified. |
| 7 | Method XML_Parser::parse() has no return type specified. |
| 7 | Method XML_Parser::parse() has parameter $data with no type specified. |
| 13 | Parameter #2 $shdl of function xml_set_element_handler expects callable(): mixed, 'startHandler' given. |
| 13 | Parameter #3 $ehdl of function xml_set_element_handler expects callable(): mixed, 'endHandler' given. |
| 20 | Tip: Method XML_Parser::startHandler() always throws an exception, it should have return type "never". |
| 20 | Method XML_Parser::startHandler() has no return type specified. |
| 20 | Method XML_Parser::startHandler() has parameter $XmlParser with no type specified. |
| 20 | Method XML_Parser::startHandler() has parameter $attr with no type specified. |
| 20 | Method XML_Parser::startHandler() has parameter $tag with no type specified. |
| 26 | Method XML_Parser::endHandler() has no return type specified. |
| 26 | Method XML_Parser::endHandler() has parameter $XmlParser with no type specified. |
| 26 | Method XML_Parser::endHandler() has parameter $tag with no type specified. |
| 31 | Class XML_Parser referenced with incorrect case: Xml_Parser. |
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.