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.


"A seed grows with no sound, but a tree falls with a huge noise. Destruction has noise, but creation is quiet. This is the power of silence. Grow Silently"

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