How to Reveal Static Call Relationships in Your Code
What is new?
Updated with EasyCI package, that acquired the Static Detector package.
Static methods are easy to use. Have a guess. How long would it take to make 700 static methods in your code? 2-3 years? Now imagine you need a replace one with dependency injection.
You're dead. Well, at first, it feels like it. Then you can start to analyze the problem and make a refactoring plan. To increase plan chances for success, we needed data.
How can we get more data about static in our code?
Meet Static Detector.
"3 developers try to find one static method they can safely change."

Where is the end of it? Where to start?
Yay, we found one static method that seems independent on others. Let's send pull-requests for review.
Later that day, on code review...
- "Well, it depends on one more method. Let's refactor it too..."
- "Oh, now we need to change 2 methods in the template too... Hm, how do we get a service into that template?"
- "Hm, this template is created in a static method as well. Let's register it as a service..."
- "Ups, 3 more classes use this static service..."
Turmoil.
Stop & Relax
In a situation like this, let's take time to step back, breathe, and relax. There is a way to get out this, but brute force is not one of them.
"A journey of a thousand miles begins with a single step."
Recipe for Static Success
If we refactor 100+ static methods manually, we'll probably end up in the stress and frustration like in the story above.
The goal is to take one method at a time. But not just any static method. The easiest possible. How do we find it?
Take Low Hanging Fruit
The easiest static method is the one with the least coupling, or with a coupling that is easiest to remove, e.g.
- static method that is never used → remove it
- static method that is used only locally → remove
static
- static method that is used only in local static method → make it
private
- static method that is used only in template → refactor is to filter service
But you already know that, right? Anyone can remove method that is never used. What is the hard problem? How can we be sure the method is not really used?
Static Detector to the Rescue
To get these data, we use a handy tool symplify/easy-ci.
Install it:
composer require symplify/easy-ci --dev
Run it on your directory:
vendor/bin/easy-ci detect-static src
We'll see the overview of all static methods, with all related static calls.
From the most spread one in the top, into the least coupled in the bottom.
For following file:
<?php
// src/SomeStatic.php
final class SomeStatic
{
public static function neverCalled()
{
}
public function run()
{
self::calledJustOnce();
}
public static function calledJustOnce()
{
}
}
We get this result:

Now even 700+ static methods do seem like such a big problem, right?

Happy coding!
Have you find this post useful? Do you want more?
Follow me on Twitter, RSS or support me on GitHub Sponsors.