Hi, I'm Tomas Votruba

I help PHP companies to modernize their codebase,
increase profits and attract new talent.

To make this happen faster and at scale, I made Rector - software that handles instant upgrades and automated refactoring.

We provide an upgrade service to save you time and money.


"If you don't want to do something, you'll find an excuse.
If you really do, you'll find a way."

Learn about PHP in Posts

2024

11-19
How to flip Doctrine ODM repositories to Services
11-14
Alice, Nelmio, Hautelook, Faker - How to upgrade Doctrine Fixtures - Part 1
11-05
5 Ways to Extract Value from Overmocked Tests
10-10
How to Upgrade deprecated PHPUnit withConsecutive()
08-27
PHP is the Best Choice for Long‑Term Business
07-12
Scope and Downgrade your PHP Tools for Everyone to Use
06-17
Awesome PHP Packages from Japan
06-10
2 Tricks to get your Symfony configs lines to minimum
06-03
How to reload code highlighter on Livewire 3 component update
05-29
How to add visibility to 338 Class Constants in 25 seconds
05-15
Cool features of Swiss Knife
05-10
Get Quick Error Count for each PHPStan level
05-01
How adding Type Declarations makes Your Code Dangerous
04-17
Master the Change
03-07
Finalize Classes - Automated and Safe
02-05
Rector Book 2024 Release with Brand new Chapter
02-03
3 Signs Your Project is Becoming Legacy - Mock Rottening
01-27
Get Json output for PHPUnit 10
01-14
Zen Config in ECS 12

2023

12-30
5 Books I enjoyed Reading in 2023
12-28
3 Signs Your Project is Becoming Legacy - Arrays Creep
11-17
3 Signs Your Project is Becoming Legacy and How to Avoid Them
11-01
How to Autowire Multiple Instances of Same Type in Symfony and Laravel
10-13
How to make your Tool Commands List Easy to Ready
09-06
From Symfony to Laravel - 5 Steps to Prepare your Symfony Project for Migration
08-25
From Symfony to Laravel - Can Laravel even Compiler Pass
08-24
How to take Advantage of 3rd party Dependency Injection Container
08-20
Easy and Quick way to Measure lines of Code in PHP
08-18
Removing Service from Laravel Container is not that Easy
08-16
How to Remove Transitional Dependencies You don't Need
07-31
Unleash the Power of Simplicity: PHP CLI App with Minimal Dependencies
07-25
Experiment: How I replaced Symfony DI with Laravel Container in ECS
07-18
How to avoid Maintaining Classes you Don't Use
07-10
Two Kinds of Legacy Code Upgrade
04-19
Moving from Disqus to Twitter to make Know-how Sharing Easier
03-31
What I prefer about Laravel Dependency Injection over Symfony
03-24
Introducing Bladestan - PHPStan analysis of Blade templates
03-15
To Route or To Action - That is the Question
03-08
Introducing Punchcard - Object Configs for Laravel
02-26
Why I Migrated This Website From Symfony To Laravel
02-14
How to ask DaVinci and Codex to get the right answer
02-12
Run Config Transformer Everyday to keep YAML Away
01-31
Lets Share Fails and Tricks with GPT
01-28
Good Bye, Monorepo
01-12
How can we Generate Unit Tests - Part 2: Building Scoring Script
01-04
How can we Generate Unit Tests - Part 1: Testability Score

2022

12-30
How to release PHP 8.1 and 7.2 package in the Same Repository
12-01
How to Measure Your Type Coverage
07-25
How to Develop Sole Package in PHP 8.1 and Downgrade to PHP 7.2
07-18
8 News in Config Transformer that Converts Symfony YML to PHP
12-01
Can PHPStan find Dead Public Methods
06-27
Twig Smoke Rendering - Fortune Favors the Bold
06-20
Twig Smoke Rendering - Journey of Fails
06-13
Twig Smoke Rendering - Why do we Even Need it
06-06
5 Pitfalls of Upgrade to Native PHP Enums and How to Avoid Them
05-30
How to Make Configs like RectorConfig or ECSConfig for your Symfony Project
05-09
New in ECS: Simpler Config
05-02
How to test Symfony Routes to make Huge Refactoring Safe
04-25
How to Remove Dead Mock Calls from PHPUnit Tests
03-07
5 Constant Lists That Give Context to your Integers and Strings
02-07
How to Create Symfony Kernel for Tests with Different Configs
01-31
Get Rid of Mixed Callables with PHPStan

2021

11-22
Not all Mixed Types are Equally Useless
11-08
How to Run Naked Unit Tests in a New Legacy Project
11-01
Decomposing Symfony Kernel: What does Minimal Symfony Bundle Do
10-25
When Symfony Http Kernel is a Too Big Hammer to Use
10-18
5 Commands from Easy CI that Makes Your CI Stronger
10-11
Introducing up-to 16 Times Faster Easy Coding Standard
10-04
7 Steps to Start with Parallel Run in PHP CLI App
09-27
Hidden Productivity Costs of Parallel Run
09-20
Parallel in PHP for Dummies Cooking a Family Dinner
09-13
STAMP #5: How do we Know Types of Template Variables
11-01
STAMP #4: How to Run PHPStan Rules on Temporary PHP File
08-30
STAMP #3: How to Turn TWIG Helper Functions to Origin Object
08-23
STAMP #2: How to Turn Messy TWIG PHP to Something Useful
08-16
STAMP #1: How to Compile Twig to PHP
08-09
STAMP #0: Static Analysis of Templates
08-02
How to Easily Protect your Code Base from Commented PHP Code
07-26
How I made Huge Mistake with Interpretation of Laravel Downloads
07-12
A Week in a Life of Employed Open‑Source Developer
07-08
How to Scope Your PHP Tool in 10 Steps
07-05
Why do we Scope PHP Tools
06-28
How to Replace Single Node with Two Nodes in Abstract Syntax Tree
06-21
How to make Upgrade Safe with Bridge Testing
06-14
Doctrine Annotations and Attributes Living Together in Peace
06-07
Why Should We Talk about Our Mistakes in PHP Community
06-03
How I Redesigned my Website the Way I Refactor Legacy Projects
05-31
How to Refactor Custom Doctrine Annotations to Attributes
05-24
How Exception to the Convention Does More Harm than Good
06-01
Rector - The Power of Automated Refactoring Book Released
05-10
Write GitHub Actions for Gitlab Too
05-03
PHPStan Generics for Dummies - With 2 Parents
04-26
Dependency Juggling Code Smell
04-19
How can We use GitHub Actions in Gitlab
04-12
2 Ways to Write Big Numbers More Readable
04-05
Monorepo Split GitHub Action 2.0 with Gitlab split is Out!
03-29
How to Traverse PHPDoc and Modify It
03-15
Never Forget Symfony Config Options Again
02-22
It's not Null, it's Enum
02-11
Tree Coding vs. Bush Coding

2020

12-28
Why Coding Standards Should Not Be Part of CI
12-21
5 New Combos opened by Symfony 5.2 and PHP 8.0
12-14
New in Symplify 9: More than 110 PHPStan Rules
11-30
New in Symplify 9: Documentation Generator for PHP CS Fixer, Code Sniffer, PHPStan and Rector Rules
11-16
How to make a Dynamic Matrix in GitHub Actions
10-19
How to Split Test Monorepo with Composer 2
02-01
How We Stopped Merging Pull Requests
09-28
How to Add Colors to Continuous Integration Output
09-21
Symfony AutoBind Parameter is Dead, Long live Constant Parameters
09-14
How to Apply Coding Standard on PHP Snippets in Markdown Files
08-31
How Static Methods Kill You Like Corona
08-24
What if We Remove Strings from Symfony Extension Configuration
09-01
How to Get Rid of Magic, Static and Chaos from Latte Filters
08-03
How to Give Away 1500 € in 1 Tweet and Help 25 People Learn Something New
01-01
How to Switch from YAML Configs to PHP Today with Symplify
07-20
How to Update Hundreds of Test Fixtures with Single PHPUnit run
07-16
10 Cool Features You Get after switching from YAML to PHP Configs
07-13
The most Effective Test I found in 7 years of Testing
08-01
Cleaning Lady Notes: From Class Mess to PSR-4 Step by Step With Confidence
07-02
How to Patch a Package in Vendor, Yet Allow its Updates
06-29
How Will Programming look like in 2025
06-22
Why Class Constants Should be Typed
06-08
Drop RobotLoader and let Composer Deal with Autoloading
05-01
The Bulletproof Event Naming For Symfony Event Dispatcher
05-18
The Future of Pehapkari Meetups and Training - You
08-01
How to Upgrade to Symplify 8 - From Sniffs to PHPStan Rules
04-20
How to Hydrate Arrays to Objects via Constructor
04-13
How to Migrate Spaghetti to 304 Symfony 5 Controllers Over Weekend
11-01
Doctrine Entity Typed Properties With PHP 7.4
03-09
Art of Letting Go
03-02
We Do Not Need Senior Developers, We Need Senior Codebases
02-10
How to Test Monorepo After Split Before Actual Split
02-03
How to run Rector and PHPStan on Huge Project in 3 Seconds with PHPStorm
01-27
Switch Travis to GitHub Actions to Reduce Stress
01-13
Why is First Instant Feedback Crucial to Developers
11-01
Migrate Gedmo to KnpLabs

2019

12-30
Doctrine Behaviors 2.0 - Reloaded
12-23
5 Things I Improve when I Get to new Repository
12-16
8 Steps You Can Make Before Huge Upgrade to Make it Faster, Cheaper and More Stable
08-01
How to Get Rid of Technical Debt or What We Would Have Done Differently 2 Years ago
11-25
The Single Best Skill to Master Command Line
12-01
How to Delegate Code Reviews to CI
08-01
From 0 Doc Types to Full Type Declaration with Dynamic Analysis
11-01
Still on PHPUnit 4 Come to PHPUnit 8 Together in a Day
06-01
How we Migrated 54 357-lines Application from Nette to Symfony in 2 People under 80 Hours
08-01
How we Completed Thousands of Missing @var Annotations in a Day
08-01
How to Convert Listeners to Subscribers and Reduce your Configs
08-01
Why use One-Time Migration Scripts
11-01
7 Tips to Write Flawless Issue Reports on Github
07-01
5 Workflow Tips every PHP Developer Should Know
06-24
Do you use PHP_CodeSniffer and PHP CS Fixer PHPStorm Plugin You are Slow and Expensive
05-16
Don't Ever use Symfony Listeners
08-01
Alias as a Code Smell
04-29
Rector European Tour in May & June 2019
04-25
Don't Give Up Your PHP Code for Compiler Passes so Easily
04-18
Symfony 4.2 is used Twice More than Symfony 3.4
04-15
Pattern Refactoring
04-08
What You Lose by Switching to Symfony
11-01
How to Upgrade Twig from Underscored to Namespaces
04-01
Removing Static - There and Back Again
03-28
How to Mock Final Classes in PHPUnit
11-01
How to Instantly Migrate Nette\Tester to PHPUnit
09-01
How to Migrate PhpSpec to PHPUnit
11-01
How to Detect Dead PHP Code in Code Review in 7 Snippets
03-11
Why we Migrated from Nette to Symfony in 3 Weeks - Part 3 - Brain Drain Dead Packages-Lock
03-07
Why we Migrated from Nette to Symfony in 3 Weeks - Part 2 - Escaping Semantic Hell
11-01
How to turn Laravel from Static to Dependency Injection in one Day
11-01
How to Upgrade Symfony 2.8 to 3.4
02-25
5 Tips to Effective Work with Github Repository
02-21
How we Migrated from Nette to Symfony in 3 Weeks - Part 1
02-14
Why Config Coding Sucks
12-01
New in Rector: Asterisk Type Match
01-28
2 Files that Your Symfony Application Misses
01-24
How to Kill Parents
01-17
How Writing Posts Helps you to Become Better Programmer

2018

12-31
Your Most Favorite Posts in 2018
12-27
How To Convert All Your Symfony Service Configs to Autodiscovery
12-24
Thank You
08-01
Function create_function() is Deprecated in PHP 7.2 - How to Migrate
12-13
Kirill Smelov's PHPStorm Tips in 9 Gifs
08-01
The Rocket Science Behind Migration of Docblock Types to PHP Typehints
12-06
Don't Learn to Code
12-03
IT Bloggers, Deprecate Your Posts to Stop Spreading Legacy
11-26
14 Tips to Write PHP Code that is Hard to Maintain and Upgrade
02-01
How to Test Monorepo in 3 Layers
11-19
When You Should Use Monorepo and When Local Packages
11-01
How to Get PHP 7.4 Typed Properties to Your Code in Few Seconds
02-01
Will Autowired Arrays Finally Deprecate Tags in Symfony and Nette
11-01
Fatal error: Uncaught Error: [] operator not supported for strings in
10-25
Why AST Fixes your Coding Standard Better than Tokens
12-01
Brief History of Tools Watching and Changing Your PHP Code
10-18
How I Almost Missed My Talk in PHP Asia Conference
10-15
What is Your Third Door - Book Review
10-11
Hi, my name is Tom - Concat vs. Sprintf vs. In-String Variable
09-27
Open-Source Behind The Scenes - Finding the Rector Vision
08-01
New in Symplify 5: 3 News in EasyCodingStandard to Smoother Your Experience
11-01
7 Tips to Write Exceptions Everyone Will Love
09-13
Your Brain is Your Garden
09-10
5 Advices I Would Love to Get Before Starting to Maintain an Open Source
09-03
4 Ways to Add Global Option or Argument to Symfony Console Application
08-30
Ways I Fucked Up Open Source Code: Mock Everything and Test Units
08-27
Why and How to Avoid the Memory Lock
08-23
9 Features of PHPStorm Symfony Plugin You Should Not Miss in Gifs
08-16
What's New in PHP 7.3 in 30 Seconds in Diffs
08-13
Hidden Gems of PHP Packages: Symfony\Finder and SplFileInfo
08-06
Stylish and Standard Console Output with Symfony Style
08-02
5 Gotchas of the Bin File in PHP CLI Applications
07-30
Hidden Gems of PHP Packages: Nette\Utils
07-23
5 Signs You Should Never Have a Talk Abroad
07-12
Notes from 'Peace is Every Step' Book
07-09
6 Reasons Why Doctrine is Alive and Kicking
03-01
How to Convert Latte Templates to Twig in 27 Regular Expressions
06-28
Don't Read Books
06-18
14 Surprising Tips from Selling is Human to Influence Others
06-14
Collector Pattern for Dummies
08-01
How to Turn Mocks from Nightmare to Solid Kiss Tests
01-01
How to Migrate From PHP CS Fixer to ECS in 6 Steps
01-01
How to Migrate From PHP_CodeSniffer to ECS in 7 Steps
05-31
Symfony vs Laravel vs Nette - Which PHP Framework Should You Choose
05-28
Build Your First Symfony Console Application with Dependency Injection Under 4 Files
04-01
How to Test Private Services in Symfony
11-01
How to Load --config With Services in Symfony Console
05-07
Why You Should Combine Symfony Console and Dependency Injection
05-03
How Do You Treat Your Own First AI
04-30
Programming = Climbing a Huge Mountain
04-26
How I Got into Static Trap and Made Fool of Myself
04-19
4 Tips To Get Emotions to Your Blogging About Programming
04-12
The Best 5 of 256 Bloghacks Book
01-01
Try PSR-12 on Your Code Today
08-01
New in Coding Standard 4: Long Line Breaks Automated and 3 Legacy Prevention Fixers
03-22
How Teaching Suicides Itself by Killing the Passion
03-19
How to Criticize like a Senior Programmer
12-01
NEON vs. YAML and How to Migrate Between Them
03-08
Why is Collector Pattern so Awesome
03-05
Rector: Part 3 - Why Instant Upgrades
02-26
Rector: Part 2 - Maturity of PHP Ecosystem and Founding Fathers
11-01
Rector: Part 1 - What and How
02-12
Sleep Shorter to Get 62 % Smarter
01-29
How to Deal With Haters in Comments and Github
01-08
Clean and Decoupled Controllers, Commands and Event Subscribers Once and for All with Delegator Pattern

2017

12-25
Composer Local Packages for Dummies
12-04
Life 3.0: What Will You Do When AI Takes Over the World
11-20
How to Write Interesting Jobs Offers for Programmers
11-13
7 Tips You Should Know Before Going To University
10-01
How to change PHP code with Abstract Syntax Tree
10-30
What can You Learn from Menstruation and Symfony Releases
10-23
IMbox Zero
02-01
How to use Repository with Doctrine as Service in Symfony
10-09
How to Get the Most Valuable Feedback You Can Get
09-25
3 non-IT Books That Help you to Become Better Programmer
07-31
How PHP Coding Standard Tools Actually Work
01-01
How to Write Custom Fixer for PHP CS Fixer 3
01-01
How to Write Custom Sniff for Code Sniffer 3+
07-03
How to Deprecate PHP Package Without Leaving Anyone Behind
06-01
Thank you David Grudl
05-07
How to refactor to new Dependency Injection features in Symfony 3.3
01-01
Combine power of PHP_CodeSniffer and PHP CS Fixer in 3 lines
04-14
3 Symfony and Laravel Patterns that Make Code Easy to Extend Without Modification
05-01
Drop all Service Tags in Your Nette and Symfony Applications
01-28
Why I Switched Scrutinizer for PHPStan and You Should Too
01-15
7 rad, které bych si dal před odchodem na vysokou školu