{"id":15018666,"url":"https://github.com/pmmp/callbackvalidator","last_synced_at":"2025-09-29T11:31:46.488Z","repository":{"id":40576051,"uuid":"247741892","full_name":"pmmp/CallbackValidator","owner":"pmmp","description":"Tools for validating callback signatures in PHP","archived":false,"fork":true,"pushed_at":"2024-06-01T10:12:09.000Z","size":130,"stargazers_count":1,"open_issues_count":3,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2024-12-30T13:52:51.391Z","etag":null,"topics":["github-actions-enabled","on-packagist","php83","phpstan-l9","phpstan-strict"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":"DaveRandom/CallbackValidator","license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pmmp.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-03-16T15:14:40.000Z","updated_at":"2024-02-28T13:49:07.000Z","dependencies_parsed_at":"2023-02-17T12:01:16.106Z","dependency_job_id":null,"html_url":"https://github.com/pmmp/CallbackValidator","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/pmmp%2FCallbackValidator","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pmmp%2FCallbackValidator/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pmmp%2FCallbackValidator/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pmmp%2FCallbackValidator/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pmmp","download_url":"https://codeload.github.com/pmmp/CallbackValidator/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":234619333,"owners_count":18861456,"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":["github-actions-enabled","on-packagist","php83","phpstan-l9","phpstan-strict"],"created_at":"2024-09-24T19:52:15.341Z","updated_at":"2025-09-29T11:31:41.184Z","avatar_url":"https://github.com/pmmp.png","language":"PHP","readme":"Callback Validator\n==================\n\nValidates callback signatures against a prototype.\n\nThis is a fork of [daverandom/callback-validator](https://github.com/DaveRandom/CallbackValidator) used by PocketMine-MP. There are no significant changes from the upstream repository apart from more test versions, updated dependencies, and tagged releases for packages to use.\n\nSince the upstream version has no release, it affects the composer stability of packages that use it. This caused problems for packages depending on [`pocketmine/pocketmine-mp`](https://github.com/pmmp/PocketMine-MP) because they could not receive its latest versions.\n\n## Status\n\n![CI](https://github.com/pmmp/CallbackValidator/workflows/CI/badge.svg)\n\n## Usage\n\n```php\n// Create a prototype function (can be any callable)\n$prototype = function (A $a, B $b, $c): ?string {};\n\n// Validate that callables match the prototype\n$tests = [\n    $prototype, // true\n    function (A $a, B $b, $c) {}, // false - return type does not match\n    function ($a, $b, $c): ?string {}, // true - arguments are contravariant\n    function (A $a, B $b): ?string {}, // true - extra args don't cause errors\n    function (A $a, B $b, $c, $d): ?string {}, // false - Insufficient args cause an error\n    function (C $a, B $b, $c): ?string {}, // true if C is a supertype of A, false otherwise\n    function (SuperTypeOfA $a, B $b, $c): ?string {}, // true\n    function (A $a, B $b, $c): string {}, // true - return types are covariant\n];\n\n// Create a type from a prototype\n$type = CallbackType::createFromCallable($prototype);\n\nrun_tests($type, $tests);\n\n// ...or create a type by hand for more granular control over variance rules\n$type = new CallbackType(\n    new ReturnType(BuiltInTypes::STRING, ReturnType::NULLABLE | ReturnType::COVARIANT),\n    new ParameterType('a', A::class),\n    new ParameterType('b', B::class),\n    new ParameterType('c')\n);\n\nrun_tests($type, $tests);\n\nfunction run_tests(CallbackType $type, array $tests)\n{\n    foreach ($tests as $test) {\n        if ($type-\u003eisSatisfiedBy($test)) {\n            echo \"pass\\n\";\n        } else {\n            // CallbackType implements __toString() for easy inspections\n            echo CallbackType::createFromCallable($test) . \" does not satisfy {$type}\\n\";\n        }\n    }\n}\n```\n\n## TODO\n\n- Lots more tests\n- Explain (text explanation of why callback does not validate)\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpmmp%2Fcallbackvalidator","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpmmp%2Fcallbackvalidator","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpmmp%2Fcallbackvalidator/lists"}