liquidrazor / class-locator
Minimal deterministic class discovery and validation library for PHP 8.3+.
v0.1.0
2026-03-27 00:05 UTC
Requires
- php: ^8.3
- liquidrazor/file-locator: ^v0.1
README
A minimal PHP 8.3+ library for deterministic class discovery and validation.
What it does
- Uses
liquidrazor/file-locatorto discover PHP files - Maps file paths → FQCN using PSR-4 rules
- Validates that your codebase matches its declared structure
That’s it.
Philosophy
- Filesystem is truth
- Deterministic mapping over guesswork
- Validation is explicit, not implicit
- No magic, no hidden loading
- Built for real-world broken projects
Dependency Model
ClassLocator is built on top of:
liquidrazor/file-locator
It does NOT define roots.
It consumes whatever FileLocator provides.
Namespace Resolution
ClassLocator does NOT detect namespaces for discovery.
Instead:
- Namespace roots are loaded from
composer.json(PSR-4) - File paths are mapped deterministically to expected FQCN
- Namespace parsing is used ONLY for validation (depending on mode)
Filesystem + Composer define expectation.
Files must comply.
Modes
ENFORCING (default)
- Requires valid Composer PSR-4 mappings
- Validates all files
- Throws on critical violations
- Fails fast on broken structure
STRICT
- Validates all files
- Collects violations
- Does not throw
LENIENT
- Best-effort discovery
- Skips invalid entries
- Minimal validation
Validation
Validation compares:
expected (path + composer)
vs
actual (file namespace + symbol)
Detects:
- Namespace mismatch
- Class/interface/trait/enum mismatch
- Files outside PSR-4 scope
- Duplicate FQCN
- Missing or invalid Composer mappings
Usage
$fileLocator = new FileLocator(...); $classLocator = new ClassLocator($fileLocator); $result = $classLocator->locate();
Public API
ClassLocator
new ClassLocator(FileLocator $fileLocator, Mode $mode = Mode::ENFORCING)
LocateResult locate()
Mode (enum)
Mode::ENFORCING Mode::STRICT Mode::LENIENT
LocateResult
array getClasses()
array getViolations()
bool hasViolations()
ClassInfo
string getFqcn()
string getPath()
Violation
string getMessage()
string getPath()
What it does NOT do
- No DI
- No service registration
- No autoload manipulation
- No file execution
- No framework coupling
Summary
Give it a FileLocator.
It gives you classes.
If your project is lying, it tells you.