This document explains why static analysis is a core requirement
for using maatify/data-adapters, and how type safety is preserved
without runtime complexity.
This package is designed to be used with:
- PHPStan (Level Max)
- Psalm (strict mode)
Static analysis is not an enhancement here —
it is a design dependency.
Without static analysis:
- The adapter contract loses most of its value
- Type safety degrades to
object - Misuse becomes easy and silent
PHP cannot express:
- Generic interfaces
- Generic return types
- Template constraints
At runtime, this forces signatures like:
public function getDriver(): object;By itself, this is insufficient.
Docblock templates are used to restore type information at analysis time.
The adapter contract is defined as:
/**
* @template TDriver of object
*/
interface AdapterInterface
{
/** @return TDriver */
public function getDriver(): object;
}Concrete adapters then bind the template explicitly:
/**
* @implements AdapterInterface<PDO>
*/
final class MySQLPDOAdapter {}This allows static analyzers to infer:
- The exact driver type
- Method availability
- Invalid usage at analysis time
getDriver()returnsobject- No metadata
- No reflection
- No runtime type enforcement
getDriver()is inferred asPDO,Redis, etc.- IDE autocomplete works correctly
- Invalid calls are caught before execution
This separation is intentional.
Returning the concrete type would require:
- Multiple interfaces
- Union types
- Driver-specific contracts
- Runtime branching
All of these introduce:
- Complexity
- Fragile APIs
- Maintenance overhead
Using object + static analysis achieves:
- Maximum safety
- Minimum runtime cost
To benefit from this design, projects must:
- Enable PHPStan or Psalm
- Allow docblock generics
- Run analysis as part of CI
Example (PHPStan):
parameters:
level: maxLower levels reduce the guarantees provided by this package.
If generics are ignored:
getDriver()degrades toobject- All driver-specific methods become invisible
Suppressing analysis errors:
- Defeats the purpose of adapters
- Reintroduces runtime surprises
Static analysis enables:
- Deterministic behavior
- Early failure
- Safe refactoring
- Clear architectural boundaries
Without it, this package becomes a thin wrapper with no safety value.
Using this package without static analysis is considered unsupported usage.
No runtime checks will be added to compensate.