typhoon / 过载
PHP中缺失的方法过载功能。
0.1.1
2023-11-27 02:32 UTC
Requires
- php: ^8.1
- ext-filter: *
Requires (Dev)
- dragon-code/benchmark: ^2.5
- ergebnis/composer-normalize: ^2.39
- friendsofphp/php-cs-fixer: ^3.38.2
- icanhazstring/composer-unused: ^0.8.10
- infection/infection: ^0.27.8
- maglnet/composer-require-checker: ^4.7.1
- phpunit/phpunit: ^10.4.2
- phpyh/coding-standard: ^2.5.0
- psalm/plugin-phpunit: ^0.18.4
- rector/rector: ^0.18.10
- symfony/filesystem: ^6.3
- symfony/var-dumper: ^6.3.8
- vimeo/psalm: ^5.15.0
README
PHP中缺失的方法过载功能。
安装
composer require typhoon/overloading
用法
要将方法handleInt
和handleString
标记为过载方法handle
,请将#[Overload('handle')]
属性添加到handleInt
和handleString
,并从handle
中调用Overload::call()
。您不需要向Overload::call()
传递参数,这会自动完成。但是,如果您需要,可以显式返回Overload::call()
。之后,您将能够使用任何参数调用handle
,并在它们的签名匹配时调用过载方法。
use Typhoon\Overloading\Overload; final class WhateverHandler { public function handle(mixed ...$args): string { return Overload::call(); } #[Overload('handle')] public function handleInt(int $int): string { return __METHOD__; } #[Overload('handle')] public function handleString(string $string): string { return __METHOD__; } #[Overload('handle')] public function handleStdClass(\stdClass $object): string { return __METHOD__; } #[Overload('handle')] public function handleNamedOptionalArguments(int $int = 0, float $float = M_E): string { return __METHOD__; } } $handler = new WhateverHandler(); // WhateverHandler::handleInt var_dump($handler->handle(300)); // WhateverHandler::handleString var_dump($handler->handle('Hello world!')); // WhateverHandler::handleStdClass var_dump($handler->handle(new \stdClass())); // WhateverHandler::handleNamedOptionalArguments var_dump($handler->handle(float: 1.5)); // WhateverHandler::handleNamedOptionalArguments var_dump($handler->handle()); // No matching overloading methods for WhateverHandler::handle(string, bool). var_dump($handler->handle('Hey!', true));
关于速度呢?
当然,使用过载比直接调用方法慢,但并不慢到无法忍受。以下是对WhateverHandler
的简单基准测试。
// warm up $handler->handle(); \DragonCode\Benchmark\Benchmark::start() ->withoutData() ->round(2) ->compare([ 'direct call' => static fn (): string => $handler->handleNamedOptionalArguments(), 'overloaded call' => static fn (): string => $handler->handle(), ]);
------- ---------------- -------------------
# direct call overloaded call
------- ---------------- -------------------
min 0 ms - 0 bytes 0 ms - 0 bytes
max 0 ms - 0 bytes 0.02 ms - 0 bytes
avg 0 ms - 0 bytes 0 ms - 0 bytes
total 0.95 ms 1.16 ms
------- ---------------- -------------------
Order - 1 - - 2 -
------- ---------------- -------------------
重要的是要理解memoization在这里起着非常重要的作用。例如,CLI工作者和通过Roadrunner提供的服务应用程序将从中受益。对于PHP-FPM,您可以通过Overload::useFileCache('/path/to/cache');
启用适合OPcaching的文件缓存。
TODO
- 完成测试。
- 在README中解释缓存。
- 优化生成的代码。
- 从上游方法声明继承属性。
- 允许预热类。
- Psalm插件。
- PHPStan插件。
- 支持静态分析类型。