Imagine a city intersection.
If an intersection has 20 roads coming in and 20 roads going out, it’s a nightmare. If one road closes, the whole city stops.
This rule measures the traffic flowing in and out of your Namespaces.
We look at an entire namespace (like App\Domain\Billing) and count the connections:
Billing? If this is high, Billing is very important and must be carefully tested, because changing it breaks other things.Billing use? If this is high, Billing is very fragile, because if any of those external things change, Billing breaks.If either score gets too high (default > 20), your namespace is tangled up in a traffic jam.
This namespace is highly coupled to the outside world (High Ce).
namespace App\Services\Reporting;
// High Ce! We are depending on DB, Mail, PDF, Excel, S3, and Logger
// namespaces just to generate a report.
use App\Infrastructure\Database\Connection;
use App\Infrastructure\Mail\SmtpMailer;
use App\Vendors\PdfGenerator;
use App\Vendors\ExcelWriter;
use App\Infrastructure\Storage\S3Bucket;
use App\Infrastructure\Logging\Syslog;
class ReportGenerator {
// ...
}
Use interfaces to invert the dependencies so your namespace doesn’t rely on the outside world directly.
namespace App\Services\Reporting;
// Ce = 0! We don't depend on infrastructure.
// We define our own interfaces, and the outside world must adapt to us.
interface MailerInterface {}
interface StorageInterface {}
class ReportGenerator {
public function __construct(MailerInterface $mailer, StorageInterface $storage) {}
}
rules:
E0022:
max_ca: 20
max_ce: 20
If Phanalist flags your namespace for Ca or Ce, it means your folders are too tangled together. Use interfaces to break the dependencies between different parts of your app!