Imagine calling a company and being transferred 15 times before reaching the right person. That’s high fan-out. Now imagine you are the single point of contact for 30 different departments. That’s high fan-in.
During a scan, we index all classes and their dependencies from type hints, new instantiations, instanceof checks, static method calls, and property/constant access. At validation time, we compute fan-out (outgoing deps) and fan-in (incoming deps) for each class.
High fan-out means your class depends on too many things and is fragile. High fan-in means too many things depend on this class and changes require extensive testing.
This class depends on 12+ classes. If any of them change, this class might break.
class ReportService
{
public function __construct(
private Database $db,
private Mailer $mail,
private PdfGenerator $pdf,
private ExcelWriter $excel,
private S3Storage $storage,
private Logger $log,
private Cache $cache,
private Queue $queue,
private EventBus $events,
private Config $config,
) {}
public function run(): void
{
$data = $this->db->query();
$report = $this->pdf->generate($data);
$this->storage->upload($report);
$this->mail->send(new Notification());
}
}
Use interfaces to reduce direct dependencies.
class ReportService
{
public function __construct(
private ReportRepository $reports,
private ReportRenderer $renderer,
) {}
public function run(): void
{
$report = $this->renderer->render($this->reports->fetch());
$this->reports->save($report);
}
}
rules:
E0029:
max_fan_out: 10
max_fan_in: 20
If Phanalist flags high fan-out, your class depends on too many other classes. Use interfaces, facades, or inject more abstract collaborators. If it flags high fan-in, your class is too central — consider splitting it or stabilizing its interface with tests.