phpstan / phpstan

PHP Static Analysis Tool - discover bugs in your code without running it!
https://phpstan.org/
MIT License
12.99k stars 887 forks source link

WordPress support #35

Closed Mte90 closed 7 years ago

Mte90 commented 7 years ago

I get many errors during a scan of a WordPress plugin (I analyse the folder of a plugin) so I think that I need to prepare a file with a list of all the functions and classes because I get many errors because they not exist.

I get also many errors about the autoloading but in WordPress you can also chose to not use composer (direct file to include) so there are many errors about it.

Anyone have suggestions for these problems?

ondrejmirtes commented 7 years ago

You can try making it work using PHPStan autoloading settings (autoload_files and autoload_directories, see: Autoloading).

artjomsimon commented 7 years ago

I tried this:

    autoload_files:
        - %rootDir%/../../../../wp-load.php

Running PHPStan in Level 0 then gives me a PHP Notice: Undefined index: SERVER_PROTOCOL in ~wordpress-project/wp-includes/load.php on line 16 and a call stack:

PHP Notice:  Undefined index: HTTP_HOST in <my-wordpress-dir>/wp-includes/ms-settings.php on line 48
PHP Stack trace:
PHP   1. {main}() <my-wordpress-dir>/repo/vendor/phpstan/phpstan/bin/phpstan:0
PHP   2. Symfony\Component\Console\Application->run() <my-wordpress-dir>/repo/vendor/phpstan/phpstan/bin/phpstan:26
PHP   3. Symfony\Component\Console\Application->doRun() <my-wordpress-dir>/repo/vendor/symfony/console/Application.php:130
PHP   4. Symfony\Component\Console\Application->doRunCommand() <my-wordpress-dir>/repo/vendor/symfony/console/Application.php:223
PHP   5. PHPStan\Command\AnalyseCommand->run() <my-wordpress-dir>/repo/vendor/symfony/console/Application.php:869
PHP   6. PHPStan\Command\AnalyseCommand->execute() <my-wordpress-dir>/repo/vendor/symfony/console/Command/Command.php:264
PHP   7. require_once() <my-wordpress-dir>/repo/vendor/phpstan/phpstan/src/Command/AnalyseCommand.php:179
PHP   8. require_once() <my-wordpress-dir>/wp-load.php:37
PHP   9. require_once() <my-wordpress-dir>/wp-config.php:175
PHP  10. require() <my-wordpress-dir>/wp-settings.php:123

Notice: Undefined index: HTTP_HOST in <my-wordpress-dir>/wp-includes/ms-settings.php on line 48

Call Stack:
    0.0004     363792   1. {main}() <my-wordpress-dir>/repo/vendor/phpstan/phpstan/bin/phpstan:0
    0.0328    5302024   2. Symfony\Component\Console\Application->run() <my-wordpress-dir>/repo/vendor/phpstan/phpstan/bin/phpstan:26
    0.0404    5601464   3. Symfony\Component\Console\Application->doRun() <my-wordpress-dir>/repo/vendor/symfony/console/Application.php:130
    0.0405    5601464   4. Symfony\Component\Console\Application->doRunCommand() <my-wordpress-dir>/repo/vendor/symfony/console/Application.php:223
    0.0405    5601464   5. PHPStan\Command\AnalyseCommand->run() <my-wordpress-dir>/repo/vendor/symfony/console/Application.php:869
    0.0407    5604584   6. PHPStan\Command\AnalyseCommand->execute() <my-wordpress-dir>/repo/vendor/symfony/console/Command/Command.php:264
    0.0464    6317264   7. require_once('<my-wordpress-dir>/wp-load.php') <my-wordpress-dir>/repo/vendor/phpstan/phpstan/src/Command/AnalyseCommand.php:179
    0.0465    6341288   8. require_once('<my-wordpress-dir>/wp-config.php') <my-wordpress-dir>/wp-load.php:37
    0.0468    6430736   9. require_once('<my-wordpress-dir>/wp-settings.php') <my-wordpress-dir>/wp-config.php:175
    0.0596    9416528  10. require('<my-wordpress-dir>/wp-includes/ms-settings.php') <my-wordpress-dir>/wp-settings.php:123

PHP Notice:  Undefined index: SERVER_PROTOCOL in <my-wordpress-dir>/wp-includes/load.php on line 16
PHP Stack trace:
PHP   1. {main}() <my-wordpress-dir>/repo/vendor/phpstan/phpstan/bin/phpstan:0
PHP   2. Symfony\Component\Console\Application->run() <my-wordpress-dir>/repo/vendor/phpstan/phpstan/bin/phpstan:26
PHP   3. Symfony\Component\Console\Application->doRun() <my-wordpress-dir>/repo/vendor/symfony/console/Application.php:130
PHP   4. Symfony\Component\Console\Application->doRunCommand() <my-wordpress-dir>/repo/vendor/symfony/console/Application.php:223
PHP   5. PHPStan\Command\AnalyseCommand->run() <my-wordpress-dir>/repo/vendor/symfony/console/Application.php:869
PHP   6. PHPStan\Command\AnalyseCommand->execute() <my-wordpress-dir>/repo/vendor/symfony/console/Command/Command.php:264
PHP   7. require_once() <my-wordpress-dir>/repo/vendor/phpstan/phpstan/src/Command/AnalyseCommand.php:179
PHP   8. require_once() <my-wordpress-dir>/wp-load.php:37
PHP   9. require_once() <my-wordpress-dir>/wp-config.php:175
PHP  10. ms_site_check() <my-wordpress-dir>/wp-settings.php:452
PHP  11. apply_filters() <my-wordpress-dir>/wp-includes/ms-load.php:79
PHP  12. WP_Hook->apply_filters() <my-wordpress-dir>/wp-includes/plugin.php:203
PHP  13. VGL\Controller\SEOController->redirectInactiveBlogs() <my-wordpress-dir>/wp-includes/class-wp-hook.php:298
PHP  14. VGL\Service\WPRedirectService->redirectToHome() <my-wordpress-dir>/src/Controller/SEOController.php:287
PHP  15. wp_redirect() <my-wordpress-dir>/src/Service/WPRedirectService.php:25
PHP  16. status_header() <my-wordpress-dir>/wp-includes/pluggable.php:1208
PHP  17. wp_get_server_protocol() <my-wordpress-dir>/wp-includes/functions.php:1070

and a similar one about SERVER_PROTOCOL being undefined. My guess is that due to the way things work in the wordpress codebase, we have some of the problems mentioned in #67 here (mixed class definitions and procedural code).

PHPStan doesn't even start analyzing, it seems the runtime simply quits after printing the Notices.

ondrejmirtes commented 7 years ago

PHPStan is not yet ready for analysing code that mixes declarations and side effects. It works well on mature, object-oriented, codebases, and WordPress is not one of those. But I'm keeping this in mind and have ideas how to improve PHPStan to work on anything.

po 31. 7. 2017 v 15:54 odesílatel Artjom Simon notifications@github.com napsal:

I tried this:

autoload_files:
    - %rootDir%/../../../../wp-load.php

Running PHPStan in Level 0 then gives me a PHP Notice: Undefined index: SERVER_PROTOCOL in ~wordpress-project/wp-includes/load.php on line 16 and a call stack:

PHP Notice: Undefined index: HTTP_HOST in /wp-includes/ms-settings.php on line 48 PHP Stack trace: PHP 1. {main}() /repo/vendor/phpstan/phpstan/bin/phpstan:0 PHP 2. Symfony\Component\Console\Application->run() /repo/vendor/phpstan/phpstan/bin/phpstan:26 PHP 3. Symfony\Component\Console\Application->doRun() /repo/vendor/symfony/console/Application.php:130 PHP 4. Symfony\Component\Console\Application->doRunCommand() /repo/vendor/symfony/console/Application.php:223 PHP 5. PHPStan\Command\AnalyseCommand->run() /repo/vendor/symfony/console/Application.php:869 PHP 6. PHPStan\Command\AnalyseCommand->execute() /repo/vendor/symfony/console/Command/Command.php:264 PHP 7. require_once() /repo/vendor/phpstan/phpstan/src/Command/AnalyseCommand.php:179 PHP 8. require_once() /wp-load.php:37 PHP 9. require_once() /wp-config.php:175 PHP 10. require() /wp-settings.php:123

Notice: Undefined index: HTTP_HOST in /wp-includes/ms-settings.php on line 48

Call Stack: 0.0004 363792 1. {main}() /repo/vendor/phpstan/phpstan/bin/phpstan:0 0.0328 5302024 2. Symfony\Component\Console\Application->run() /repo/vendor/phpstan/phpstan/bin/phpstan:26 0.0404 5601464 3. Symfony\Component\Console\Application->doRun() /repo/vendor/symfony/console/Application.php:130 0.0405 5601464 4. Symfony\Component\Console\Application->doRunCommand() /repo/vendor/symfony/console/Application.php:223 0.0405 5601464 5. PHPStan\Command\AnalyseCommand->run() /repo/vendor/symfony/console/Application.php:869 0.0407 5604584 6. PHPStan\Command\AnalyseCommand->execute() /repo/vendor/symfony/console/Command/Command.php:264 0.0464 6317264 7. require_once('/wp-load.php') /repo/vendor/phpstan/phpstan/src/Command/AnalyseCommand.php:179 0.0465 6341288 8. require_once('/wp-config.php') /wp-load.php:37 0.0468 6430736 9. require_once('/wp-settings.php') /wp-config.php:175 0.0596 9416528 10. require('/wp-includes/ms-settings.php') /wp-settings.php:123

PHP Notice: Undefined index: SERVER_PROTOCOL in /wp-includes/load.php on line 16 PHP Stack trace: PHP 1. {main}() /repo/vendor/phpstan/phpstan/bin/phpstan:0 PHP 2. Symfony\Component\Console\Application->run() /repo/vendor/phpstan/phpstan/bin/phpstan:26 PHP 3. Symfony\Component\Console\Application->doRun() /repo/vendor/symfony/console/Application.php:130 PHP 4. Symfony\Component\Console\Application->doRunCommand() /repo/vendor/symfony/console/Application.php:223 PHP 5. PHPStan\Command\AnalyseCommand->run() /repo/vendor/symfony/console/Application.php:869 PHP 6. PHPStan\Command\AnalyseCommand->execute() /repo/vendor/symfony/console/Command/Command.php:264 PHP 7. require_once() /repo/vendor/phpstan/phpstan/src/Command/AnalyseCommand.php:179 PHP 8. require_once() /wp-load.php:37 PHP 9. require_once() /wp-config.php:175 PHP 10. ms_site_check() /wp-settings.php:452 PHP 11. apply_filters() /wp-includes/ms-load.php:79 PHP 12. WP_Hook->apply_filters() /wp-includes/plugin.php:203 PHP 13. VGL\Controller\SEOController->redirectInactiveBlogs() /wp-includes/class-wp-hook.php:298 PHP 14. VGL\Service\WPRedirectService->redirectToHome() /src/Controller/SEOController.php:287 PHP 15. wp_redirect() /src/Service/WPRedirectService.php:25 PHP 16. status_header() /wp-includes/pluggable.php:1208 PHP 17. wp_get_server_protocol() /wp-includes/functions.php:1070

and a similar one about SERVER_PROTOCOL being undefined. My guess is that due to the way things work in the wordpress codebase, we have some of the problems mentioned in #67 https://github.com/phpstan/phpstan/issues/67 here (mixed class definitions and procedural code).

PHPStan doesn't even start analyzing, it seems the runtime simply quits after printing the Notices.

— You are receiving this because you modified the open/close state.

Reply to this email directly, view it on GitHub https://github.com/phpstan/phpstan/issues/35#issuecomment-319073818, or mute the thread https://github.com/notifications/unsubscribe-auth/AAGZuIVePdY4l2SSzpNG5CnjvmIBgR30ks5sTdyggaJpZM4LNjP2 .

--

Ondřej Mirtes

szepeviktor commented 6 years ago

@Mte90 Try this in PHP or simple variables in shell: https://github.com/wp-cli/wp-cli/blob/851a650d8518d94acc91b17ee098f3cfcbfeabd3/php/wp-cli.php#L16-L20

Mte90 commented 6 years ago

I think that variables are not enough, the scan need to run wordpress to analyze the plugin itself.

szepeviktor commented 6 years ago

I think the target market of phpstan is not WordPress. I am a WordPress expert so I know its weaknesses.

Mte90 commented 6 years ago

Yeah I know, in the meantime there was more tool helpful on that with PHPCS and also Tide that is a work in progress so for that reason I didn't added any update to that ticket.

ondrejmirtes commented 6 years ago

Hi, PHPStan works best on modern object-oriented code. I might try to make some optimizations so that it's usable and useful on WP as well, but I think it's better to focus my efforts on codebases that might benefit from PHPStan far more.

zaantar commented 6 years ago

FYI, we've achieved some results when using PHPStan together with https://github.com/GiacoCorsiglia/wordpress-stubs, but we had to manually edit the generated file to overcome this issue: https://github.com/GiacoCorsiglia/php-stubs-generator/issues/1

Perhaps this helps someone.

Mte90 commented 6 years ago

Seems cool maybe write a tutorial/wiki page with all the steps with also the manual patch to use everything can be very helpful :-D

zaantar commented 6 years ago

I will keep you posted as soon as I have a complete result. Might take time, though.

szepeviktor commented 6 years ago

For anyone interested: you may get started by autoloading https://github.com/GiacoCorsiglia/wordpress-stubs

parameters:
    autoload_files:
        - %currentWorkingDirectory%/wordpress-stubs.php

phpstan analyze --level=0 wp-admin/ it takes several minutes.

remcotolsma commented 6 years ago

It is also possible to use PHPStan without stubs, i just applied it in the following library: https://github.com/wp-pay-gateways/omnikassa-2

We use the following libraries for this:

composer require --dev johnpbloch/wordpress
composer require --dev wp-phpunit/wp-phpunit

phpstan.neon.dist

parameters:
    customRulesetUsed: false
    level: max
    bootstrap: tests/phpstan-bootstrap.php
    paths:
        - src

tests/phpstan-bootstrap.php

<?php

putenv( sprintf( 'WP_PHPUNIT__TESTS_CONFIG=%s', 'tests/wp-config.php' ) );

require_once __DIR__ . '/../vendor/autoload.php';

require_once getenv( 'WP_PHPUNIT__DIR' ) . '/includes/functions.php';

require getenv( 'WP_PHPUNIT__DIR' ) . '/includes/bootstrap.php';
szepeviktor commented 5 years ago

For googlers: see https://github.com/szepeviktor/phpstan-wordpress

Contributions welcome!