Laying the past to rest
In 2019, after the break-in at pear.php.net, we suggested that PEAR needed a plan for its retirement. Seven years later, an RFC provides one. What it gets right, and why a frozen archive is not yet a safe one.
Read moreArticles about Development Tools by Sebastian Bergmann
In 2019, after the break-in at pear.php.net, we suggested that PEAR needed a plan for its retirement. Seven years later, an RFC provides one. What it gets right, and why a frozen archive is not yet a safe one.
Read more
In April 2022, I spent two hours talking about mutation testing with Marco Pivetta and Stefan Priebsch. The recording recently resurfaced. What of it has survived four years?
Read more
Every PHP tool that prints to a terminal now has two readers, and most of us have only been writing for one of them.
Read more
ISO/IEC 18974 describes what an open source security assurance program has to prove. Composer already produces much of that evidence as a by-product of every build. What it does not produce: an archive, a second look at software that has already shipped, and a name next to every responsibility.
Read more
Andrew Nesbitt explains the size of npm dependency trees with the resolver. In PHP, the resolver is ultimately the engine itself: one name, one definition, one version per process. That is why PHP trees stay small, and why PHPUnit's PHAR has to rename its dependencies.
Read more
A car manufacturer lists an Android botnet in its open source attribution. The entry gives away how the list was made: by scanning instead of by declaring. Why a declared dependency list is worth more than a scanned one, and how the PHPUnit PHAR discloses its own contents.
Read more
A security vulnerability in PHPCSUtils revealed an eval() call in a static analysis tool. Why disable_functions cannot reach eval(), and what a switch in the PHP engine to disable it could look like.
Read more
2025 and 2026 proved to be a stress test for the supply chains of all package ecosystems. A review of Composer and Packagist: what PHP does well, what it can learn — and who owns our infrastructure.
Read more
On every run, PHPUnit knows how long each test took, how much memory it used, and why it failed. Most of that evaporates. otr-report reads it back out of the Open Test Reporting logfile and puts it within reach.
Read more
We protect what exists. But do we ask often enough whether it should exist at all? How removing unused branches can protect against Poisoned Pipeline Execution.
Read more
A walk through the GitHub Actions weaknesses in PHPUnit's workflows, how each one could have been exploited, and what was changed to close them.
Read more
“It feels slow” is not a diagnosis. I explain the three disciplines that turn vague complaints into actionable data: tracing, profiling, and benchmarking.
Read more
Composer 2.9 moved security advisory enforcement from an opt-in third-party package into the resolver itself. This article walks through how the mechanism works, how it relates to the older packages it replaces, and where it can bite you.
Read more
How thoroughly do your tests cover the code, and how reliably do they detect real errors? I show you how to find out.
Read more
Psalm or PHPStan: which tool is the better choice for code analysis? Or is it worth combining both tools for maximum code quality?
Read more
Should PHP_CodeSniffer or PHP-CS-Fixer be used to get code “in shape”? Should both tools even be used together?
Read more
Should you use PCOV or Xdebug to collect code coverage data? I give a personal answer.
Read more
I explain why using overly open version restrictions can lead to problems.
Read moreA new article is published every Wednesday. Subscribe to the RSS feed and it arrives straight in your feed reader.
The newsletter brings you a comprehensive analysis of new PHPUnit features, implementation details, and the strategic considerations behind each improvement via email every two months.