typhoon/过载

PHP中缺失的方法过载功能。

0.1.1 2023-11-27 02:32 UTC

This package is auto-updated.

Last update: 2024-08-28 15:09:28 UTC


README

PHP中缺失的方法过载功能。

PHP Version Require Latest Stable Version Total Downloads psalm-level type-coverage Code Coverage Mutation testing badge

安装

composer require typhoon/overloading

用法

要将方法handleInthandleString标记为过载方法handle,请将#[Overload('handle')]属性添加到handleInthandleString,并从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插件。
  • 支持静态分析类型。