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

phpstan requires ext-simplexml to be installed #9714

Closed
SomeBdyElse opened this issue Aug 1, 2023 · 12 comments
Closed

phpstan requires ext-simplexml to be installed #9714

SomeBdyElse opened this issue Aug 1, 2023 · 12 comments
Labels
Milestone

Comments

@SomeBdyElse
Copy link

SomeBdyElse commented Aug 1, 2023

Bug report

In our local dev environment, phpstan requires ext-simplexml to be installed to analyze code with the SimpleXMLElement constructor. The on-line PHPStan playground does it correctly. Locally, we get the following stack trace:

0bfe5f978e66:/app# ./vendor/bin/phpstan --version
PHPStan - PHP Static Analysis Tool 1.10.26
0bfe5f978e66:/app# ./vendor/bin/phpstan analyse -v --memory-limit=2G
Note: Using configuration file /app/phpstan.neon.
 319/319 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 100% 2 secs

 -- ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 
     Error                                                                                                                                                                          
 -- ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 
     Internal error: Internal error: Class "SimpleXMLElement" not found in file /app/src/…/Classes/Command/AbstractCommand.php                                      
                                                                                                                                                                                    
     Post the following stack trace to https://github.com/phpstan/phpstan/issues/new?template=Bug_report.yaml:                                                                      
     #0 phar:///app/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(2550):                                                                                   
     PHPStan\Type\Php\SimpleXMLElementConstructorThrowTypeExtension->getThrowTypeFromStaticMethodCall()                                                                             
     #1 phar:///app/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(2180): PHPStan\Analyser\NodeScopeResolver->getConstructorThrowPoint()                    
     #2 phar:///app/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(1585): PHPStan\Analyser\NodeScopeResolver->processExprNode()                             
     #3 phar:///app/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(2930): PHPStan\Analyser\NodeScopeResolver->PHPStan\Analyser\{closure}()                  
     #4 phar:///app/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(1593): PHPStan\Analyser\NodeScopeResolver->processAssignVar()                            
     #5 phar:///app/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(599): PHPStan\Analyser\NodeScopeResolver->processExprNode()                              
     #6 phar:///app/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(384): PHPStan\Analyser\NodeScopeResolver->processStmtNode()                              
     #7 phar:///app/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(557): PHPStan\Analyser\NodeScopeResolver->processStmtNodes()                             
     #8 phar:///app/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(384): PHPStan\Analyser\NodeScopeResolver->processStmtNode()                              
     #9 phar:///app/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(640): PHPStan\Analyser\NodeScopeResolver->processStmtNodes()                             
     #10 phar:///app/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(384): PHPStan\Analyser\NodeScopeResolver->processStmtNode()                             
     #11 phar:///app/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(612): PHPStan\Analyser\NodeScopeResolver->processStmtNodes()                            
     #12 phar:///app/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(353): PHPStan\Analyser\NodeScopeResolver->processStmtNode()                             
     #13 phar:///app/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/FileAnalyser.php(173): PHPStan\Analyser\NodeScopeResolver->processNodes()                                     
     #14 phar:///app/vendor/phpstan/phpstan/phpstan.phar/src/Command/WorkerCommand.php(130): PHPStan\Analyser\FileAnalyser->analyseFile()                                           
     #15 phar:///app/vendor/phpstan/phpstan/phpstan.phar/vendor/evenement/evenement/src/Evenement/EventEmitterTrait.php(97):                                                        
     PHPStan\Command\WorkerCommand->PHPStan\Command\{closure}()                                                                                                                     
     #16 phar:///app/vendor/phpstan/phpstan/phpstan.phar/vendor/clue/ndjson-react/src/Decoder.php(117): _PHPStan_d55c4f2c2\Evenement\EventEmitter->emit()                           
     #17 phar:///app/vendor/phpstan/phpstan/phpstan.phar/vendor/evenement/evenement/src/Evenement/EventEmitterTrait.php(97):                                                        
     _PHPStan_d55c4f2c2\Clue\React\NDJson\Decoder->handleData()                                                                                                                     
     #18 phar:///app/vendor/phpstan/phpstan/phpstan.phar/vendor/react/stream/src/Util.php(62): _PHPStan_d55c4f2c2\Evenement\EventEmitter->emit()                                    
     #19 phar:///app/vendor/phpstan/phpstan/phpstan.phar/vendor/evenement/evenement/src/Evenement/EventEmitterTrait.php(97):                                                        
     _PHPStan_d55c4f2c2\React\Stream\Util::_PHPStan_d55c4f2c2\React\Stream\{closure}()                                                                                              
     #20 phar:///app/vendor/phpstan/phpstan/phpstan.phar/vendor/react/stream/src/DuplexResourceStream.php(154): _PHPStan_d55c4f2c2\Evenement\EventEmitter->emit()                   
     #21 phar:///app/vendor/phpstan/phpstan/phpstan.phar/vendor/react/event-loop/src/StreamSelectLoop.php(201): _PHPStan_d55c4f2c2\React\Stream\DuplexResourceStream->handleData()  
     #22 phar:///app/vendor/phpstan/phpstan/phpstan.phar/vendor/react/event-loop/src/StreamSelectLoop.php(173):                                                                     
     _PHPStan_d55c4f2c2\React\EventLoop\StreamSelectLoop->waitForStreamActivity()                                                                                                   
     #23 phar:///app/vendor/phpstan/phpstan/phpstan.phar/src/Command/WorkerCommand.php(96): _PHPStan_d55c4f2c2\React\EventLoop\StreamSelectLoop->run()                              
     #24 phar:///app/vendor/phpstan/phpstan/phpstan.phar/vendor/symfony/console/Command/Command.php(259): PHPStan\Command\WorkerCommand->execute()                                  
     #25 phar:///app/vendor/phpstan/phpstan/phpstan.phar/vendor/symfony/console/Application.php(870): _PHPStan_d55c4f2c2\Symfony\Component\Console\Command\Command->run()           
     #26 phar:///app/vendor/phpstan/phpstan/phpstan.phar/vendor/symfony/console/Application.php(261): _PHPStan_d55c4f2c2\Symfony\Component\Console\Application->doRunCommand()      
     #27 phar:///app/vendor/phpstan/phpstan/phpstan.phar/vendor/symfony/console/Application.php(157): _PHPStan_d55c4f2c2\Symfony\Component\Console\Application->doRun()             
     #28 phar:///app/vendor/phpstan/phpstan/phpstan.phar/bin/phpstan(124): _PHPStan_d55c4f2c2\Symfony\Component\Console\Application->run()                                          
     #29 phar:///app/vendor/phpstan/phpstan/phpstan.phar/bin/phpstan(125): _PHPStan_d55c4f2c2\{closure}()                                                                           
     #30 /app/vendor/phpstan/phpstan/phpstan(8): require('...')                                                                                                                     
     #31 /app/vendor/bin/phpstan(117): include('...')                                                                                                                               
     #32 {main}                                                                                                                                                                     
     Child process error (exit code 1):   

Once we install php81-simplexml, phpstan misses the obvious type error shown in the playground example and passes the file without complaint. This seems incorrect, as the example contains a type error.

Code snippet that reproduces the problem

https://phpstan.org/r/a523934f-ea45-45f1-98fb-5691c4afb358

Expected output

phpstan should complain about the error, as it does in the playground.

Did PHPStan help you today? Did it make you happy in any way?

It makes our code better :)

@ondrejmirtes
Copy link
Member

PHP has this extension enabled by default: https://www.php.net/manual/en/simplexml.installation.php

Yeah, it should not crash, but your environment is pretty atypical 😊

If PHPStan is not able to detect an error and you can't reproduce it on the playground, please create a small reproducing repository that shows the problem. You can also involve Docker if you want.

@SomeBdyElse
Copy link
Author

SomeBdyElse commented Aug 1, 2023

Hi @ondrejmirtes ! What a quick reply! :) Please find a sample repo here:
https://github.com/SomeBdyElse/phpstan-issue-9714
You can run the test.sh bash script to see the issue or read https://github.com/SomeBdyElse/phpstan-issue-9714/blob/main/README.md too see my output.

@ondrejmirtes
Copy link
Member

There's no difference between the result in your Docker image and in the playground: https://phpstan.org/r/3b235cce-1d56-49e2-94e3-ea2173fd1ecf

The difference is between SimpleXmlElement and SimpleXMLElement: https://phpstan.org/r/33ce796c-083f-4622-bfa9-a14f714d6319

@SomeBdyElse
Copy link
Author

You are right. As far as I can see the class is named \SimpleXMLElement with a capital XML.
https://www.php.net/manual/en/class.simplexmlelement.php

Here is the Playground example with a capital XML.
https://phpstan.org/r/f03f7f5f-b5ed-4809-b024-c774d1ea19d5
I would expect phpstan to complain about the foreach($elements as, as $elements might be null or false.

The git repository already has a capital XML.
https://github.com/SomeBdyElse/phpstan-issue-9714/blob/main/test.php#L7

  • Installing ext-simplexml should not make any difference in phpstan's behavior. Right?
  • My phpstan does not complain about the foreach($elements as either.

Or am I somehow missing the correct spelling of SimpleXMLElement?

@ondrejmirtes
Copy link
Member

My guess is that with SimpleXMLElement PHPStan understands that xpath method cannot return |false|null but with SimpleXmlElement the according dynamic return type extension isn't executed so there's a false positive. It's definitely a bug. There should be no errors reported.

@SomeBdyElse
Copy link
Author

Oh, I did not realize there is a dynamic return type. Nice 😄. In that case phpstan's behavior with ext-simplexml installed is correct.

The error without ext-simplexml remains.

@ondrejmirtes
Copy link
Member

There are two bugs:

  1. PHPStan should not crash without ext-simplexml
  2. This result is wrong: https://phpstan.org/r/33ce796c-083f-4622-bfa9-a14f714d6319

@ondrejmirtes ondrejmirtes added this to the Easy fixes milestone Aug 1, 2023
@SomeBdyElse SomeBdyElse changed the title phpstan requires SimpleXMLElement to be installed phpstan requires ext-simplexml to be installed Aug 1, 2023
@mvorisek
Copy link
Contributor

mvorisek commented Aug 2, 2023

related with #9553 - xpath should be parsed, not tried to be evaluated, as parsing is required to understand if the xpath returns DOMElement (which is returned in 99% usecases), no ext needed then

@phpstan-bot
Copy link
Contributor

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

@@ @@
-11: Argument of an invalid type array<SimpleXMLElement>|false|null supplied for foreach, only iterables are supported.
+No errors

@phpstan-bot
Copy link
Contributor

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

@@ @@
-9: Argument of an invalid type array<SimpleXMLElement>|false|null supplied for foreach, only iterables are supported.
+No errors

@ondrejmirtes
Copy link
Member

@github-actions
Copy link

github-actions bot commented Sep 6, 2023

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 Sep 6, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

4 participants