Trying out PHP Refactoring Browser
Join the DZone community and get the full member experience.
Join For FreeRemember the times when they tried to convert you from your Unix-based PHP setup to an IDE, throwing away Vim and command line tools for Eclipse of PhpStorm?
One of the points of contention where the IDE was clearly at an advantage was the availability of automated refactorings: in a dynamic language like PHP, it's not easy nor totally safe to perform automatically the extraction of a method. That said, one of the selling points of PhpStorm is that it is capable of extracting code in exactly this way.
The religion war
IDE proponents love, in fact, an Integrated Development Environment that provides all the functionalities you need while writing and editing code; the followers of the Unix way typically write code in Vim while augmenting it via plugins where feasible and leveraging external tools that do one thing, and do it well.
For example, these are tasks accomplished by an IDE that are currently easily executable from the command line:
- building and testing a project: Phing and PHPUnit plus other BDD tools such as Behat can be run directly more easily than by visualizing their output inside Eclipse's window.
- Looking for code smells: PHP_CodeSniffer, PHP Copy&Paste Detector and PHP Mess Detector all run static analysis from the command line. PHP CS Fixer can clean up some of the simplest issues automatically.
- Profiling: XDebug and xhprof run code inside a real server producing performance measurements that can be organized via language-independent tools such as Kcachegrind.
Automated refactorings in PHP were out of the league of Vim and Unix users; thanks to Qafoo, however, a new open source tool is able to edit code with predefined refactoring recipes: PHP Refactoring Browser.
Let's get our expectations straight
Don't think that you will reach immediately the same level of productivity in refactorings as you can do by hand right now with Vim: PHP Refactoring Browser is in alpha and only provides a few basic refactoring, oriented to a single source file:
- Convert Local to Instance Variable
- Extract Method
- Rename Local Variable
The introductory post from Benjamin has examples of how these commands can be used, so I won't go into detail here. I love the philosophy of this tool anyway: exposing a Unix-based command line API for applying automated refactoring to PHP code.
The result is a Composer-ready library that you can install n any machine running a PHP interpreter, and that can be called by your editor of choice. Consider instead of many of IDE functionalities are buried inside them and have to be reinvented by other editors or every time you move to a server such as the CI environment (good luck running Eclipse on an headless machine).
While there existed similar limited tools in the past (I contributed to Scisr for example), PHP Refactoring Browser has the architecture and the credibility for being the center of pull requests augmenting its functionality.
Trying it out
The tool can be downloaded as a single Phar. I installed PHP Refactoring Browser via Composer, for an easier upgrade when its time comes; you have to be careful however in following this road, as there is a repository dependency that cannot be declared by the project. You should use this composer.json:
{ ..., "minimum-stability": "dev", "repositories": [ { "type": "vcs", "url": "https://github.com/QafooLabs/php-refactoring-browser" }, { "type": "vcs", "url": "https://github.com/schmittjoh/PHP-Parser" } ], "require": { "qafoolabs/php-refactoring-browser": "dev-master" } }
Note the version constraint 'dev-master', which is also present in PHP Refactoring Browser dependency towards the php-analyzer library; just to say this is not a stable release.
I performed the extraction of a field and of a method by myself without difficulties, as the output of refactoring commands is a unified diff that can be piped directly into patch. You can see in this Git repository's commit history how a pair of commands completed the job along with a manual step consisting of checking visibility and moving methods.
Extract Method works very well with private internal methods (whose scope is the default), but my constructor use case broke it and required a manual step (you shouldn't expect refactoring tools for dynamic languages to work correcty in all corner cases).
Conclusions
I definitely look forwards to a pair of lines to put in .vimrc to apply these refactorings from inside the editor, a very lightweight form of integration that lets the tool be able to evolve and be reused independently. Meanwhile I will take a look at the code with some real life use cases to see if some heuristic can improve the output of the tool and constitute a pull request.
Opinions expressed by DZone contributors are their own.
Comments