Whoops as ErrorHandler
I recently switched to Whoops in my apps.
It provides a better exception rendering for development mode for most cases.
Just load the plugin (dereuromark/cakephp-whoops) and modify the bootstrap line:
//(new ErrorHandler(Configure::consume('Error')))->register();
(new \CakephpWhoops\Error\WhoopsHandler(Configure::consume('Error')))->register();
If you already have a src/Application.php
and run a middleware setup, you also want to make sure you either remove the ErrorHandlerMiddleware
there, or provide a custom one for Whoops.
You can test it for example with my sandbox app.
Check it out locally, set it up in minutes and give it a test run.
Jump from browser to IDE
With the Whoops error handler the probably nicest feature is the "click to IDE" one.
It allows to click on the class inside the displayed code piece and jump right into the IDE into the exact line of that file displayed in the browser stack trace.
Be more productive leveraging your IDE
Using the new IdeHelper plugin you can now not only bake annotations into new code, but also adjust
your existing code all the time.
The plugin provides a shell to quickly sync the existing annotations with your code.
This way you can maximize IDE compatibility and with that prevent obvious issues and mistakes.
The IDE will usually mark problematic code yellow (missing, wrong method etc).
It can also enable you to click through the classes and object chains which otherwise would just be plain text and have no typehinting.
Finally autocomplete will be available for all the "magically" provided classes and methods this way.
This plugin is supposed to work with ANY IDE that supports annotations.
The plugin wiki contains even details and tips/settings for each of those IDEs – collected by the community.
Enable PHPStan in your app and plugins
PHPStan is a super useful static code analysis tool.
It will help you to find issues with your code way beyond what the test suite or IDE syntax checks can do.
For example, if you have two many different return types and only respect one of them, it will mark this as issue.
It will also tell you about interface mismatch or other similar code smells.
Adjust Travis
Add a new matrix row and a script call for that matrix entry:
...
matrix:
include:
...
- php: 7.0
env: PHPSTAN=1 DEFAULT=0
...
script:
...
- if [[ $PHPSTAN == 1 ]]; then composer require --dev phpstan/phpstan && vendor/bin/phpstan analyse -l 1 src; fi
...
Level 1 (-l 1
) is the lowest level, once everything passes you can go up to level 5 currently. I recommend trying level 3, if possible.
If you need to ignore certain errors, you can use a custom phpstan.neon
file in your /tests
directory and then append -c tests/phpstan.neon
into the command for travis.
vendor/bin/phpstan analyse -c tests/phpstan.neon -l 1 src
For me such a file looked like this, for example:
parameters:
autoload_files:
- %rootDir%/../../../tests/bootstrap.php
excludes_analyse:
- %rootDir%/../../../src/TestSuite/*
ignoreErrors:
- '#Call to an undefined method Cake\\Datasource\\EntityInterface\:\:source\(\)#'
Don’t try to ignore too much, though – only "false positives" are recommended to be added here.
You can also write custom PHPStan extensions, see the current CakePHP core /tests/PHPStan
folder for details.
Using it locally
I added this to my plugins’s composer.json
files:
"scripts": {
...,
"phpstan": "phpstan analyse -l 1 src",
"phpstan-setup": "cp composer.json composer.backup && composer require --dev phpstan/phpstan && mv composer.backup composer.json"
}
This will allow local testing without messing up your composer file 🙂
For app instead of plugin development you also want to backup-restore the lock file.
Now just run
composer phpstan-setup
composer phpstan
I bet you will find a few useful issues to resolve right on the first run of this tool.
And the part 2? 😀
Hi Mark
Thanks for your introduction to PHPStan. Ive tried to get rid of all errors, but there is one which I can’t:
use of CakePHP constants…e.g.:
"Constant ROOT not found."
Of course, these constants are defined elsewhere (in the Cake core).
Is there any trick to get this valid or should I just exclude this test?
Thanks,
Frank
Make sure either define those, or include the bootstrap file (as done e.g. in CakePHP core).