# Tomas Votruba > PHP developer and coach writing about legacy code, automated refactoring, static analysis and kaizen. Creator of Rector, ECS and other PHP tooling. ## Pages - [Tools I built](https://tomasvotruba.com/tools): PHP packages maintained by Tomas Votruba - [Books](https://tomasvotruba.com/books): books on PHP and refactoring ## Recent writing - [There is NO cache](https://tomasvotruba.com/blog/there-is-no-cache): The cost of a slow language is called cache. That's why [Easy CS](https://github.com/symplify/easy-coding-standard) runs only on files changed since the last… - [Unicorn Benefits of Rust/Go Tooling in PHP](https://tomasvotruba.com/blog/unicorn-benefits-rust-go-tooling-in-php): We've established that we, PHP devs, can benefit from tooling written in a language we don't understand as well as we do PHP. How exactly? - [Rust/Go Leverage in PHP](https://tomasvotruba.com/blog/rust-go-leverage-in-php): In the previous post we looked at how Rust's speed of static analysis opened the door for non-PHP languages to analyze PHP codebases. What influence did it… - [Is PHP a Rusty language](https://tomasvotruba.com/blog/is-php-a-rusty-language): We lived in quiet and peaceful times in the PHP community about 11 months ago, in late 2025. We didn't have agents yet, we managed projects manually and we had… - [How I use Agents to Extract Hidden Feedback from Github and Improved Rector](https://tomasvotruba.com/blog/how-I-use-agents-to-extract-hidden-feedback-from-github-and-improved-rector): I was randomly drifting through Github trending PHP repositories, and checking how popular projects use `rector.php`. A lot of them use it extensively, with … - [7 tips to Improve your ECS Config](https://tomasvotruba.com/blog/7-tips-to-improve-your-ecs-config): Easy Coding Standard got a [new release last week](/blog/ecs-13-2-lighter-smarter-more-fun-for-large-legacy-projects) with a couple of cool features and new… - [ECS 13.2: Lighter, Smarter and More Fun for Large/Legacy Projects](https://tomasvotruba.com/blog/ecs-13-2-lighter-smarter-more-fun-for-large-legacy-projects): Easy Coding Standard focuses on easy setup, easy run, and easy use. Last year we [simplified the config](/blog/zen-config-in-ecs) to a single fluent line. … - [Find the One PHPStan Rule You Need, Beyond the Core](https://tomasvotruba.com/blog/find-the-one-phpstan-rule-you-need-beyond-the-core): PHPStan core gets you to level 10 with solid type checks. But some gems, the rules that catch *your* anti-patterns, live scattered across a dozen community… - [Introducing CTOR: Prefer Constructor over Always-Called Setters](https://tomasvotruba.com/blog/introducing-ctor-prefer-constructor-over-always-called-setters): We've all seen it: `new Human()` followed by three `setName()`, `setAge()`, `setEmail()` calls that are always there. Not optional - just pretending. These are… - [Alice, Nelmio, Hautelook, Faker - How to Upgrade Doctrine Fixtures - Part 3](https://tomasvotruba.com/blog/alice-nelmio-hautelook-faker-and-how-to-upgrade-doctrine-fixtures-part-3): In previous parts ([part 1](/blog/alice-nelmio-hautelook-faker-and-how-to-upgrade-doctrine-fixtures-part-1) and [part 2](/blog/alice-nelmio-hautelook-faker-and… - [5 Books I Enjoyed Reading in 2025](https://tomasvotruba.com/blog/5-books-2025): Keeping the tradition from [previous](/blog/5-books-i-enjoyed-reading-in-2024) [years](/blog/5-books-i-enyjoed-reading-in-2023), here is my short list of 5… - [The Patch for Laravel Container](https://tomasvotruba.com/blog/the-patch-for-laravel-container): [I switched this website from Symfony to Laravel](/blog/why-I-migrated-this-website-from-symfony-to-laravel) 2,5 years ago, and I [love Laravel Container](… - [How we Maintain Dozens of Symfony Workflows with Peace](https://tomasvotruba.com/blog/how-we-maintain-dozens-of-symfony-workflows-with-peace): There are dozens of posts and talks about how Symfony Workflows work and what they are for. To give you the simplest example, if you have a post - it can be… - [Upgrading Sensio Security Annotation: The Full Story](https://tomasvotruba.com/blog/upgrading-sensio-security-annotation-the-full-story): The `@Security` annotation, which originated in the Sensio extra bundle, goes a long way. The official upgrade docs have a few misleading pointers, that force… - [Create Weird Fun PHPStan Rules like Nobody's Watching](https://tomasvotruba.com/blog/create-weird-fun-phpstan-rules): There are 2 ways to use PHPStan. You can use native levels, and official extensions and raise the level from 0 to 8. This is a good start, but it often… - [Why AST beats GPTs - featuring php-parser, ChatGPT 4.5 and Grok 3](https://tomasvotruba.com/blog/why-ast-beats-gpt): As I'm manually writing this article, GPTs are on the hype train now. In this post, we'll use freshly released ChatGPT 4.5 and Grok 3 and see, if they know the… - [Custom PHPStan Rules to Improve Every Symfony project](https://tomasvotruba.com/blog/custom-phpstan-rules-to-improve-every-symfony-project): Using PHPStan is not just about getting to level 8 with less than 100 ignored cases. Yes, there are also [official extensions](https://packagist.org/?query… - [Cost-effective Container Smoke Tests every Symfony Project must have](https://tomasvotruba.com/blog/cost-effective-container-smoke-tests-every-symfony-project-must-have): Today, I'll share a trademark secret that allows us to move fast and make huge changes without fear. When we're starting a new [Symfony 2.8-7.2 upgrade… - [5 Books I enjoyed Reading in 2024](https://tomasvotruba.com/blog/5-books-i-enjoyed-reading-in-2024): Another year is gone, and it's [tradition](/blog/5-books-i-enyjoed-reading-in-2023) to pick 5 books I enjoyed reading in 2024. - [Alice, Nelmio, Hautelook, Faker - How to upgrade Doctrine Fixtures - Part 2](https://tomasvotruba.com/blog/alice-nelmio-hautelook-faker-and-how-to-upgrade-doctrine-fixtures-part-2): In the first part, [we've kicked off the plan](/blog/alice-nelmio-hautelook-faker-and-how-to-upgrade-doctrine-fixtures-part-1) to upgrade all these packages to… - [Symfony @required - Avoid the Temptation and Use it Right](https://tomasvotruba.com/blog/symfony-required-avoid-the-temptation-and-use-it-right): Symfony 3 introduced a [`@required` annotation](https://symfony.com/doc/3.x/service_container/calls.html) (now also an attribute) that allows injecting more… - [Unused Definitions with Behat Static Analysis](https://tomasvotruba.com/blog/unused-definitions-with-behat-static-analysis): Recently, I've been working on projects with Behat tests. There are hundreds of definitions that can be used in feature file scenarios. I accidentally noticed… - [Why Final Classes make Rector and PHPStan more powerful](https://tomasvotruba.com/blog/why-final-classes-make-rector-and-phpstan-more-powerful): Final classes bring much more value than `extends` it lacks. It teaches composition over inheritance, makes upgrades easier, and [even mocking](/blog/2019/03… - [Off the Beaten Path to Upgrade Symfony 2.8 to 7.2](https://tomasvotruba.com/blog/off-the-beaten-path-to-upgrade-symfony-28-to-72): There are two types of upgrades. One follows only `UPGRADE.md` files on every release, replacing what has been removed with new alternatives. It works, and we… - [How to flip Doctrine ODM repositories to Services](https://tomasvotruba.com/blog/how-to-flip-doctrine-odm-repositories-to-services): While working with legacy projects, I often encountered this anti-pattern of misusing repositories. Instead of easy-to-inject service, projects are locked into… - [Alice, Nelmio, Hautelook, Faker - How to upgrade Doctrine Fixtures - Part 1](https://tomasvotruba.com/blog/alice-nelmio-hautelook-faker-and-how-to-upgrade-doctrine-fixtures-part-1): Upgrading Doctrine Fixtures can be challenging work. It requires the coordination of four different package groups on Github. One cannot be upgraded without… - [5 Ways to Extract Value from Overmocked Tests](https://tomasvotruba.com/blog/5-ways-to-extract-value-from-overmocked-tests): The legacy projects we work with are often flooded with mocks. I already wrote [How to Remove Dead Mock Calls from PHPUnit Tests](/blog/how-to-remove-dead-mock… - [How to Upgrade deprecated PHPUnit withConsecutive()](https://tomasvotruba.com/blog/how-to-upgrade-deprecated-phpunit-with-consecutive): The `withConsecutive()` method [was deprecated in PHPUnit 9](https://github.com/sebastianbergmann/phpunit/issues/4255#issuecomment-636422439) and removed in… - [PHP is the Best Choice for Long‑Term Business](https://tomasvotruba.com/blog/php-is-the-best-choice-for-long-term-business): Recently, I listened to Lex Friedman's [podcast with Pieter Levels](https://open.spotify.com/episode/6KBpL2XfR9VdojbKNpE7cX). Pieter talked about his… - [Scope and Downgrade your PHP Tools for Everyone to Use](https://tomasvotruba.com/blog/scope-and-downgrade-your-php-tool-for-everyone-to-use): Yesterday, I came across a cool PHP tool. I wanted to try it, but the installation instructions were a bit tricky. The tool required a specific PHP version and… ## Full index - [RSS feed](https://tomasvotruba.com/rss) - [Sitemap](https://tomasvotruba.com/sitemap.xml)