{"id":15525237,"url":"https://github.com/donatj/php-dnf-solver","last_synced_at":"2025-08-21T11:19:13.840Z","repository":{"id":161076358,"uuid":"635863863","full_name":"donatj/php-dnf-solver","owner":"donatj","description":"PHP DNF (Disjunctive Normal Form) Signature Compatibility Solver","archived":false,"fork":false,"pushed_at":"2025-04-10T04:14:23.000Z","size":138,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"dev","last_synced_at":"2025-04-10T05:16:55.525Z","etag":null,"topics":["dnf","php8","type-resolution","types"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/donatj.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"custom":"https://www.paypal.me/donatj/15","ko_fi":"donatj","github":"donatj"}},"created_at":"2023-05-03T16:03:26.000Z","updated_at":"2025-04-10T04:10:14.000Z","dependencies_parsed_at":null,"dependency_job_id":"59a9df0a-bd57-4d5a-bcda-b88b66d20fe9","html_url":"https://github.com/donatj/php-dnf-solver","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/donatj%2Fphp-dnf-solver","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/donatj%2Fphp-dnf-solver/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/donatj%2Fphp-dnf-solver/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/donatj%2Fphp-dnf-solver/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/donatj","download_url":"https://codeload.github.com/donatj/php-dnf-solver/tar.gz/refs/heads/dev","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250401721,"owners_count":21424568,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["dnf","php8","type-resolution","types"],"created_at":"2024-10-02T10:55:55.697Z","updated_at":"2025-04-23T08:46:19.913Z","avatar_url":"https://github.com/donatj.png","language":"PHP","funding_links":["https://www.paypal.me/donatj/15","https://ko-fi.com/donatj","https://github.com/sponsors/donatj"],"categories":[],"sub_categories":[],"readme":"# PHP DNF Solver\n\n[![Latest Stable Version](https://poser.pugx.org/donatj/php-dnf-solver/version)](https://packagist.org/packages/donatj/php-dnf-solver)\n[![License](https://poser.pugx.org/donatj/php-dnf-solver/license)](https://packagist.org/packages/donatj/php-dnf-solver)\n[![ci.yml](https://github.com/donatj/php-dnf-solver/actions/workflows/ci.yml/badge.svg)](https://github.com/donatj/php-dnf-solver/actions/workflows/ci.yml)\n[![Coverage Status](https://coveralls.io/repos/github/donatj/php-dnf-solver/badge.svg)](https://coveralls.io/github/donatj/php-dnf-solver)\n\n\nPHP DNF (Disjunctive Normal Form) Signature Compatibility Solver - see: https://wiki.php.net/rfc/dnf_types\n\n## Requirements\n\n- **php**: ~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0\n\n## Installing\n\nInstall the latest version with:\n\n```bash\ncomposer require 'donatj/php-dnf-solver'\n```\n\n## Examples\n\n### Example Parameter Satisfaction Check\n\n```php\n\u003c?php\n\nnamespace Examples;\n\nuse donatj\\PhpDnfSolver\\DNF;\nuse donatj\\PhpDnfSolver\\Types\\UserDefinedType;\n\nrequire __DIR__ . '/../vendor/autoload.php';\n\ninterface A {}\ninterface B {}\ninterface C {}\ninterface D {}\n\nclass Foo implements A, B {}\nclass Bar implements B, C {}\nclass Baz implements C, D {}\n\n$qux = function ( A|(B\u0026C) $aOrB ) : void {};\n\n$quxParamType = (new \\ReflectionFunction($qux))-\u003egetParameters()[0]-\u003egetType();\n\n$quxDnf = DNF::getFromReflectionType($quxParamType);\n\nvar_dump($quxDnf-\u003eisSatisfiedBy(\n\tnew UserDefinedType(Foo::class)\n)); // true\n\nvar_dump($quxDnf-\u003eisSatisfiedBy(\n\tnew UserDefinedType(Bar::class)\n)); // true\n\nvar_dump($quxDnf-\u003eisSatisfiedBy(\n\tnew UserDefinedType(Baz::class)\n)); // false\n\n```\n\nOutputs:\n\n```\nbool(true)\nbool(true)\nbool(false)\n```\n\n### Example DNF Building\n\n```php\n\u003c?php\n\nnamespace Examples;\n\nuse donatj\\PhpDnfSolver\\Types\\AndClause;\nuse donatj\\PhpDnfSolver\\Types\\BuiltInType;\nuse donatj\\PhpDnfSolver\\Types\\OrClause;\nuse donatj\\PhpDnfSolver\\Types\\UserDefinedType;\n\nrequire __DIR__ . '/../vendor/autoload.php';\n\ninterface A {}\ninterface B {}\ninterface C {}\n\nvar_dump((new OrClause(\n\tnew UserDefinedType(A::class),\n\tnew UserDefinedType(B::class),\n\tnew UserDefinedType(C::class)\n))-\u003ednf()); // A|B|C\n\nvar_dump((new OrClause(\n\tnew UserDefinedType(A::class),\n\tnew AndClause(\n\t\tnew UserDefinedType(B::class),\n\t\tnew UserDefinedType(C::class)\n\t)\n))-\u003ednf()); // A|(B\u0026C)\n\nvar_dump((new OrClause(\n\tnew AndClause(new UserDefinedType(A::class), new UserDefinedType(B::class)),\n\tnew AndClause(\n\t\tnew UserDefinedType(B::class),\n\t\tnew UserDefinedType(C::class)\n\t),\n\tnew BuiltInType('null'),\n))-\u003ednf()); // (A\u0026B)|(B\u0026C)|null\n\n```\n\nOutputs:\n\n```\nstring(32) \"Examples\\A|Examples\\B|Examples\\C\"\nstring(34) \"Examples\\A|(Examples\\B\u0026Examples\\C)\"\nstring(52) \"(Examples\\A\u0026Examples\\B)|(Examples\\B\u0026Examples\\C)|null\"\n```\n\n## Documentation\n\n### Class: donatj\\PhpDnfSolver\\DNF\n\n#### Method: DNF::getFromReflectionType\n\n```php\nfunction getFromReflectionType(\\ReflectionType $type) : \\donatj\\PhpDnfSolver\\SingularDnfTypeInterface|\\donatj\\PhpDnfSolver\\NestedDnfTypeInterface\n```\n\nHelper to convert a ReflectionType into it's DNF representation  \n\n##### Example sources include\n\n- ReflectionFunctionAbstract::getParameters()[…]-\u003egetType()  \n- ReflectionParameter::getType()  \n- ReflectionMethod::getReturnType()  \n- ReflectionProperty::getType()\n\n---\n\n#### Method: DNF::reflectionTypeSatisfiesReflectionType\n\n```php\nfunction reflectionTypeSatisfiesReflectionType(\\ReflectionType $satisfyingType, \\ReflectionType $satisfiedType) : bool\n```\n\nHelper to quickly check if a ReflectionType satisfies another ReflectionType\n\n##### Parameters:\n\n- ***\\ReflectionType*** `$satisfyingType` - The type which must be satisfied (e.g. a parameter type)\n- ***\\ReflectionType*** `$satisfiedType` - The type which must satisfy the other (e.g. a return type)\n\n---\n\n#### Method: DNF::getFromVarType\n\n```php\nfunction getFromVarType(\\ReflectionParameter|\\ReflectionProperty $parameter) : \\donatj\\PhpDnfSolver\\SingularDnfTypeInterface|\\donatj\\PhpDnfSolver\\NestedDnfTypeInterface|null\n```\n\nHelper to quickly get a DNF representation of a (ReflectionParameter or ReflectionProperty)'s return type\n\n---\n\n#### Method: DNF::getFromReturnType\n\n```php\nfunction getFromReturnType(\\ReflectionFunctionAbstract $func) : \\donatj\\PhpDnfSolver\\SingularDnfTypeInterface|\\donatj\\PhpDnfSolver\\NestedDnfTypeInterface|null\n```\n\nHelper to quickly get a DNF representation of a ReflectionFunctionAbstract (ReflectionFunction /  \nReflectionMethod)'s return type\n\n### Class: donatj\\PhpDnfSolver\\Exceptions\\InvalidArgumentException\n\n### Class: donatj\\PhpDnfSolver\\Exceptions\\LogicException\n\n### Class: donatj\\PhpDnfSolver\\Types\\AndClause\n\nRepresents an \"and clause\" - a set of types which must all be satisfied - e.g. \"A\u0026B\u0026C\"\n\n#### Method: AndClause-\u003e__construct\n\n```php\nfunction __construct(\\donatj\\PhpDnfSolver\\SingularDnfTypeInterface ...$types)\n```\n\n##### Parameters:\n\n- ***\\donatj\\PhpDnfSolver\\SingularDnfTypeInterface*** `$types` - The list of types to be satisfied\n\n---\n\n#### Method: AndClause-\u003ednf\n\n```php\nfunction dnf() : string\n```\n\nReturn the canonical string representation of the DNF representation of this type\n\n---\n\n#### Method: AndClause-\u003eisSatisfiedBy\n\n```php\nfunction isSatisfiedBy(\\donatj\\PhpDnfSolver\\SingularDnfTypeInterface|\\donatj\\PhpDnfSolver\\NestedDnfTypeInterface $value) : bool\n```\n\nTests if this type is satisfied by the given type  \n  \nFor example, if this type is \"A|(B\u0026C)\" and the given type matches just \"A\", this method returns true.  \nIf the given type matches just \"B\", this method returns false.  \nIf the given type matches \"B\u0026C\", this method returns true.\n\n---\n\n#### Method: AndClause-\u003ecount\n\n```php\nfunction count() : int\n```\n\nReturns the number of types in this DNF type\n\n---\n\n#### Method: AndClause-\u003egetTypes\n\n```php\nfunction getTypes() : array\n```\n\n##### Returns:\n\n- ***\\donatj\\PhpDnfSolver\\SingularDnfTypeInterface[]***\n\n### Class: donatj\\PhpDnfSolver\\Types\\BuiltInType\n\nRepresents a \"built in type\" as defined by ReflectionNamedType::isBuiltin()\n\nThis includes:\n- int\n- float\n- string\n- bool\n- array\n- iterable\n\n#### Method: BuiltInType-\u003e__construct\n\n```php\nfunction __construct(string $name)\n```\n\n##### Parameters:\n\n- ***string*** `$name` - The name of the built-in type\n\n---\n\n#### Method: BuiltInType-\u003ednf\n\n```php\nfunction dnf() : string\n```\n\nReturn the canonical string representation of the DNF representation of this type\n\n---\n\n#### Method: BuiltInType-\u003egetTypeName\n\n```php\nfunction getTypeName() : string\n```\n\nReturns the fully qualified type name of this type\n\n---\n\n#### Method: BuiltInType-\u003eisSatisfiedBy\n\n```php\nfunction isSatisfiedBy(\\donatj\\PhpDnfSolver\\SingularDnfTypeInterface|\\donatj\\PhpDnfSolver\\NestedDnfTypeInterface $value) : bool\n```\n\nTests if this type is satisfied by the given type  \n  \nFor example, if this type is \"A|(B\u0026C)\" and the given type matches just \"A\", this method returns true.  \nIf the given type matches just \"B\", this method returns false.  \nIf the given type matches \"B\u0026C\", this method returns true.\n\n---\n\n#### Method: BuiltInType-\u003ecount\n\n```php\nfunction count() : int\n```\n\nAlways 1 for singular types\n\nReturns the number of types in this DNF type\n\n### Class: donatj\\PhpDnfSolver\\Types\\CallableType\n\nRepresents a \"callable\" type\n\nThis includes:\n- callable\n- Closure\n- Invokable classes\n\n#### Method: CallableType-\u003ednf\n\n```php\nfunction dnf() : string\n```\n\nReturn the canonical string representation of the DNF representation of this type\n\n---\n\n#### Method: CallableType-\u003eisSatisfiedBy\n\n```php\nfunction isSatisfiedBy(\\donatj\\PhpDnfSolver\\SingularDnfTypeInterface|\\donatj\\PhpDnfSolver\\NestedDnfTypeInterface $value) : bool\n```\n\nTests if this type is satisfied by the given type  \n  \nFor example, if this type is \"A|(B\u0026C)\" and the given type matches just \"A\", this method returns true.  \nIf the given type matches just \"B\", this method returns false.  \nIf the given type matches \"B\u0026C\", this method returns true.\n\n---\n\n#### Method: CallableType-\u003egetTypeName\n\n```php\nfunction getTypeName() : string\n```\n\nReturns the fully qualified type name of this type\n\n---\n\n#### Method: CallableType-\u003ecount\n\n```php\nfunction count() : int\n```\n\nAlways 1 for singular types\n\nReturns the number of types in this DNF type\n\n### Class: donatj\\PhpDnfSolver\\Types\\OrClause\n\nRepresents a \"or\" clause - a set of types where any one of them must be satisfied - e.g. \"A|B|(C\u0026D)\"\n\n#### Method: OrClause-\u003e__construct\n\n```php\nfunction __construct(\\donatj\\PhpDnfSolver\\Types\\AndClause|\\donatj\\PhpDnfSolver\\SingularDnfTypeInterface ...$types)\n```\n\n##### Parameters:\n\n- ***\\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.\n\n---\n\n#### Method: OrClause-\u003ednf\n\n```php\nfunction dnf() : string\n```\n\nReturn the canonical string representation of the DNF representation of this type\n\n---\n\n#### Method: OrClause-\u003eisSatisfiedBy\n\n```php\nfunction isSatisfiedBy(\\donatj\\PhpDnfSolver\\SingularDnfTypeInterface|\\donatj\\PhpDnfSolver\\NestedDnfTypeInterface $value) : bool\n```\n\nTests if this type is satisfied by the given type  \n  \nFor example, if this type is \"A|(B\u0026C)\" and the given type matches just \"A\", this method returns true.  \nIf the given type matches just \"B\", this method returns false.  \nIf the given type matches \"B\u0026C\", this method returns true.\n\n---\n\n#### Method: OrClause-\u003ecount\n\n```php\nfunction count() : int\n```\n\nReturns the number of types in this DNF type\n\n---\n\n#### Method: OrClause-\u003egetTypes\n\n```php\nfunction getTypes() : array\n```\n\n##### Returns:\n\n- ***\\donatj\\PhpDnfSolver\\Types\\AndClause[]***\n\n### Class: donatj\\PhpDnfSolver\\Types\\UserDefinedType\n\nRepresents a \"user defined type\" - a class, interface, or trait, etc.\n\n```php\n\u003c?php\nnamespace donatj\\PhpDnfSolver\\Types;\n\nclass UserDefinedType {\n\tpublic $className;\n}\n```\n\n#### Method: UserDefinedType-\u003e__construct\n\n```php\nfunction __construct(string $className)\n```\n\n##### Parameters:\n\n- ***class-string*** `$className` - The name of the class, interface, or trait to be satisfied\n\n**Throws**: `\\donatj\\PhpDnfSolver\\Exceptions\\InvalidArgumentException` - if the user defined type does not exist after triggering registered autoloaders\n\n---\n\n#### Method: UserDefinedType-\u003ednf\n\n```php\nfunction dnf() : string\n```\n\nReturn the canonical string representation of the DNF representation of this type\n\n---\n\n#### Method: UserDefinedType-\u003egetTypeName\n\n```php\nfunction getTypeName() : string\n```\n\nReturns the fully qualified type name of this type\n\n##### Returns:\n\n- ***class-string***\n\n---\n\n#### Method: UserDefinedType-\u003eisSatisfiedBy\n\n```php\nfunction isSatisfiedBy(\\donatj\\PhpDnfSolver\\SingularDnfTypeInterface|\\donatj\\PhpDnfSolver\\NestedDnfTypeInterface $value) : bool\n```\n\nTests if this type is satisfied by the given type  \n  \nFor example, if this type is \"A|(B\u0026C)\" and the given type matches just \"A\", this method returns true.  \nIf the given type matches just \"B\", this method returns false.  \nIf the given type matches \"B\u0026C\", this method returns true.\n\n---\n\n#### Method: UserDefinedType-\u003ecount\n\n```php\nfunction count() : int\n```\n\nAlways 1 for singular types\n\nReturns the number of types in this DNF type","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdonatj%2Fphp-dnf-solver","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdonatj%2Fphp-dnf-solver","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdonatj%2Fphp-dnf-solver/lists"}