donatj / php-dnf-solver
PHP DNF (Disjunctive Normal Form) Signature Compatibility Solver
Fund package maintenance!
www.paypal.me/donatj/15
Ko Fi
donatj
Installs: 17 252
Dependents: 0
Suggesters: 0
Security: 0
Stars: 1
Watchers: 2
Forks: 0
Open Issues: 1
Requires
- php: ^8.1.0 || ^8.2.0 || ^8.3.0
Requires (Dev)
- corpus/coding-standard: ~0.8.0
- donatj/drop: ^1.1
- donatj/mddoc: ^0.10.0
- friendsofphp/php-cs-fixer: ^3.16
- phpstan/phpstan: ^1.10
- phpunit/phpunit: ^10
- slevomat/coding-standard: ^8.11
- squizlabs/php_codesniffer: ^3.7
This package is auto-updated.
Last update: 2024-11-11 10:41:59 UTC
README
PHP DNF (Disjunctive Normal Form) Signature Compatibility Solver - see: https://wiki.php.net/rfc/dnf_types
Requirements
- php: ^8.1.0 || ^8.2.0 || ^8.3.0
Installing
Install the latest version with:
composer require 'donatj/php-dnf-solver'
Examples
Example Parameter Satisfaction Check
<?php namespace Examples; use donatj\PhpDnfSolver\DNF; use donatj\PhpDnfSolver\Types\UserDefinedType; require __DIR__ . '/../vendor/autoload.php'; interface A {} interface B {} interface C {} interface D {} class Foo implements A, B {} class Bar implements B, C {} class Baz implements C, D {} $qux = function ( A|(B&C) $aOrB ) : void {}; $quxParamType = (new \ReflectionFunction($qux))->getParameters()[0]->getType(); $quxDnf = DNF::getFromReflectionType($quxParamType); var_dump($quxDnf->isSatisfiedBy( new UserDefinedType(Foo::class) )); // true var_dump($quxDnf->isSatisfiedBy( new UserDefinedType(Bar::class) )); // true var_dump($quxDnf->isSatisfiedBy( new UserDefinedType(Baz::class) )); // false
Outputs:
bool(true)
bool(true)
bool(false)
Example DNF Building
<?php namespace Examples; use donatj\PhpDnfSolver\Types\AndClause; use donatj\PhpDnfSolver\Types\BuiltInType; use donatj\PhpDnfSolver\Types\OrClause; use donatj\PhpDnfSolver\Types\UserDefinedType; require __DIR__ . '/../vendor/autoload.php'; interface A {} interface B {} interface C {} var_dump((new OrClause( new UserDefinedType(A::class), new UserDefinedType(B::class), new UserDefinedType(C::class) ))->dnf()); // A|B|C var_dump((new OrClause( new UserDefinedType(A::class), new AndClause( new UserDefinedType(B::class), new UserDefinedType(C::class) ) ))->dnf()); // A|(B&C) var_dump((new OrClause( new AndClause(new UserDefinedType(A::class), new UserDefinedType(B::class)), new AndClause( new UserDefinedType(B::class), new UserDefinedType(C::class) ), new BuiltInType('null'), ))->dnf()); // (A&B)|(B&C)|null
Outputs:
string(32) "Examples\A|Examples\B|Examples\C"
string(34) "Examples\A|(Examples\B&Examples\C)"
string(52) "(Examples\A&Examples\B)|(Examples\B&Examples\C)|null"
Documentation
Class: \donatj\PhpDnfSolver\DNF
Method: DNF::getFromReflectionType
function getFromReflectionType(\ReflectionType $type) : \donatj\PhpDnfSolver\SingularDnfTypeInterface|\donatj\PhpDnfSolver\NestedDnfTypeInterface
Helper to convert a ReflectionType into it's DNF representation
Example sources include
- ReflectionFunctionAbstract::getParameters()[…]->getType()
- ReflectionParameter::getType()
- ReflectionMethod::getReturnType()
- ReflectionProperty::getType()
Method: DNF::reflectionTypeSatisfiesReflectionType
function reflectionTypeSatisfiesReflectionType(\ReflectionType $satisfyingType, \ReflectionType $satisfiedType) : bool
Helper to quickly check if a ReflectionType satisfies another ReflectionType
Parameters:
- \ReflectionType
$satisfyingType
- The type which must be satisfied (e.g. a parameter type) - \ReflectionType
$satisfiedType
- The type which must satisfy the other (e.g. a return type)
Method: DNF::getFromVarType
function getFromVarType(\ReflectionParameter|\ReflectionProperty $parameter) : \donatj\PhpDnfSolver\SingularDnfTypeInterface|\donatj\PhpDnfSolver\NestedDnfTypeInterface|null
Helper to quickly get a DNF representation of a (ReflectionParameter or ReflectionProperty)'s return type
Method: DNF::getFromReturnType
function getFromReturnType(\ReflectionFunctionAbstract $func) : \donatj\PhpDnfSolver\SingularDnfTypeInterface|\donatj\PhpDnfSolver\NestedDnfTypeInterface|null
Helper to quickly get a DNF representation of a ReflectionFunctionAbstract (ReflectionFunction /
ReflectionMethod)'s return type
Class: \donatj\PhpDnfSolver\Exceptions\InvalidArgumentException
Class: \donatj\PhpDnfSolver\Exceptions\LogicException
Class: \donatj\PhpDnfSolver\Types\AndClause
Represents an "and clause" - a set of types which must all be satisfied - e.g. "A&B&C"
Method: AndClause->__construct
function __construct(\donatj\PhpDnfSolver\SingularDnfTypeInterface ...$types)
Parameters:
- \donatj\PhpDnfSolver\SingularDnfTypeInterface
$types
- The list of types to be satisfied
Method: AndClause->dnf
function dnf() : string
Return the canonical string representation of the DNF representation of this type
Method: AndClause->isSatisfiedBy
function isSatisfiedBy(\donatj\PhpDnfSolver\SingularDnfTypeInterface|\donatj\PhpDnfSolver\NestedDnfTypeInterface $value) : bool
Tests if this type is satisfied by the given type
For example, if this type is "A|(B&C)" and the given type matches just "A", this method returns true.
If the given type matches just "B", this method returns false.
If the given type matches "B&C", this method returns true.
Method: AndClause->count
function count() : int
Returns the number of types in this DNF type
Method: AndClause->getTypes
function getTypes() : array
Returns:
- \donatj\PhpDnfSolver\SingularDnfTypeInterface[]
Class: \donatj\PhpDnfSolver\Types\BuiltInType
Represents a "built in type" as defined by ReflectionNamedType::isBuiltin()
This includes:
- int
- float
- string
- bool
- array
- iterable
Method: BuiltInType->__construct
function __construct(string $name)
Parameters:
- string
$name
- The name of the built-in type
Method: BuiltInType->dnf
function dnf() : string
Return the canonical string representation of the DNF representation of this type
Method: BuiltInType->getTypeName
function getTypeName() : string
Returns the fully qualified type name of this type
Method: BuiltInType->isSatisfiedBy
function isSatisfiedBy(\donatj\PhpDnfSolver\SingularDnfTypeInterface|\donatj\PhpDnfSolver\NestedDnfTypeInterface $value) : bool
Tests if this type is satisfied by the given type
For example, if this type is "A|(B&C)" and the given type matches just "A", this method returns true.
If the given type matches just "B", this method returns false.
If the given type matches "B&C", this method returns true.
Method: BuiltInType->count
function count() : int
Always 1 for singular types
Returns the number of types in this DNF type
Class: \donatj\PhpDnfSolver\Types\CallableType
Represents a "callable" type
This includes:
- callable
- Closure
- Invokable classes
Method: CallableType->dnf
function dnf() : string
Return the canonical string representation of the DNF representation of this type
Method: CallableType->isSatisfiedBy
function isSatisfiedBy(\donatj\PhpDnfSolver\SingularDnfTypeInterface|\donatj\PhpDnfSolver\NestedDnfTypeInterface $value) : bool
Tests if this type is satisfied by the given type
For example, if this type is "A|(B&C)" and the given type matches just "A", this method returns true.
If the given type matches just "B", this method returns false.
If the given type matches "B&C", this method returns true.
Method: CallableType->getTypeName
function getTypeName() : string
Returns the fully qualified type name of this type
Method: CallableType->count
function count() : int
Always 1 for singular types
Returns the number of types in this DNF type
Class: \donatj\PhpDnfSolver\Types\OrClause
Represents a "or" clause - a set of types where any one of them must be satisfied - e.g. "A|B|(C&D)"
Method: OrClause->__construct
function __construct(\donatj\PhpDnfSolver\Types\AndClause|\donatj\PhpDnfSolver\SingularDnfTypeInterface ...$types)
Parameters:
- \donatj\PhpDnfSolver\Types\AndClause | \donatj\PhpDnfSolver\SingularDnfTypeInterface
$types
- The list of types to be satisfied. Does not accept an OrClause as DNF defines that as invalid.
Method: OrClause->dnf
function dnf() : string
Return the canonical string representation of the DNF representation of this type
Method: OrClause->isSatisfiedBy
function isSatisfiedBy(\donatj\PhpDnfSolver\SingularDnfTypeInterface|\donatj\PhpDnfSolver\NestedDnfTypeInterface $value) : bool
Tests if this type is satisfied by the given type
For example, if this type is "A|(B&C)" and the given type matches just "A", this method returns true.
If the given type matches just "B", this method returns false.
If the given type matches "B&C", this method returns true.
Method: OrClause->count
function count() : int
Returns the number of types in this DNF type
Method: OrClause->getTypes
function getTypes() : array
Returns:
- \donatj\PhpDnfSolver\Types\AndClause[]
Class: \donatj\PhpDnfSolver\Types\UserDefinedType
Represents a "user defined type" - a class, interface, or trait, etc.
<?php namespace donatj\PhpDnfSolver\Types; class UserDefinedType { public $className; }
Method: UserDefinedType->__construct
function __construct(string $className)
Parameters:
- class-string
$className
- The name of the class, interface, or trait to be satisfied
Throws: \donatj\PhpDnfSolver\Exceptions\InvalidArgumentException
- if the user defined type does not exist after triggering registered autoloaders
Method: UserDefinedType->dnf
function dnf() : string
Return the canonical string representation of the DNF representation of this type
Method: UserDefinedType->getTypeName
function getTypeName() : string
Returns the fully qualified type name of this type
Returns:
- class-string
Method: UserDefinedType->isSatisfiedBy
function isSatisfiedBy(\donatj\PhpDnfSolver\SingularDnfTypeInterface|\donatj\PhpDnfSolver\NestedDnfTypeInterface $value) : bool
Tests if this type is satisfied by the given type
For example, if this type is "A|(B&C)" and the given type matches just "A", this method returns true.
If the given type matches just "B", this method returns false.
If the given type matches "B&C", this method returns true.
Method: UserDefinedType->count
function count() : int
Always 1 for singular types
Returns the number of types in this DNF type