norvica/invoker

使用可配置的参数解析调用PHP的可调用函数。

v0.2.0 2023-10-10 20:27 UTC

This package is auto-updated.

Last update: 2024-09-26 18:29:15 UTC


README

Latest Stable Version Checks

Invoker是一个轻量级的PHP库,简化了带有命名参数的函数或方法的调用。它旨在灵活地解决缺失的参数,利用自定义解析机制动态提供所需参数。

特性

  • 可以使用命名参数调用任何可调用(函数/方法)。
  • 可以使用自定义解析器进行动态参数解析。
  • 无依赖项,可直接集成到您的项目中。

安装

通过Composer安装

composer require norvica/invoker

基本用法

以下是一个调用简单可调用函数的快速示例

// using function
$result = \Norvica\Invoker\call('some_function', ['arg1' => 'value1']);

// using class
$result = \Norvica\Invoker\Invoker::call('some_function', ['arg1' => 'value1']);

当然,让我们根据dataProvider添加一些高级示例和说明到您的readme.md中。这将向潜在用户展示您的Invoker库的灵活性。

高级用法

Invoker库可以处理各种类型的可调用对象,包括

  • 普通函数
  • 闭包
  • 具有__invoke()方法的对象实例
  • 具有公共方法的对象实例
  • 类上的静态方法

以下是使用库调用这些方法的示例

普通函数

$result = \Norvica\Invoker\call('some_function', ['arg1' => 'value1']);

闭包

$closure = function (string $arg1) {
  // [...]
};
$result = \Norvica\Invoker\call($closure, ['arg1' => 'value1']);

具有__invoke方法的对象

$object = new ClassWithInvokeMethod();
$result = \Norvica\Invoker\call($object, ['arg1' => 'value1']);

// same as
$result = \Norvica\Invoker\call([$object, '__invoke'], ['arg1' => 'value1']);

具有公共方法的对象

$object = new ClassWithPublicMethod();
$result = \Norvica\Invoker\call([$object, 'someMethod'], ['arg1' => 'value1']);

具有静态方法的类

$result = \Norvica\Invoker\call([ClassWithStaticMethod::class, 'someMethod'], ['arg1' => 'value1']);

// or
$result = \Norvica\Invoker\call(ClassWithStaticMethod::class . '::foo', ['arg1' => 'value1']);

可变参数

库还支持可变参数。以下是传递数组给可变参数的示例。

$closure = function (string $arg1, int ...$number) {
  // [...]
};
$result = \Norvica\Invoker\call($closure, ['arg1' => 'value1', 'number' => [1, 2, 3]]);

使用解析器

您可以通过遵守Resolver接口实现自己的解析器,该接口有两个方法:resolve()supports()

示例:解析PSR-11容器服务

以下是创建PSR-11容器简单解析器的示例

use Norvica\Invoker\Resolver;
use ReflectionParameter;
use Psr\Container\ContainerInterface;

final class ServiceResolver implements Resolver
{
    public function __construct(
        private ContainerInterface $container,
    ) {}

    public function resolve(ReflectionParameter $parameter): mixed
    {
        return $this->container->get((string) $parameter->getType());
    }

    public function supports(ReflectionParameter $parameter): bool
    {
        return $this->container->has((string) $parameter->getType());
    }
}

要使用此解析器调用方法

$container = // your PSR-11 container
$resolver = new ServiceResolver($container);
$result = \Norvica\Invoker\call([$someObject, 'someMethod'], ['foo' => 'bar'], $resolver);

示例:解析PSR-7请求

解析器可以针对PSR-7 ServerRequest和Response对象进行定制。以下是处理ServerRequestInterface的示例解析器。

use Norvica\Invoker\Resolver;
use ReflectionParameter;
use Psr\Http\Message\ServerRequestInterface;

final class RequestResolver implements Resolver
{
    public function __construct(
        private YourRequestFactory $factory,
    ) {}

    public function resolve(ReflectionParameter $parameter): ServerRequestInterface
    {
        return $this->factory->createFromGlobals();
    }

    public function supports(ReflectionParameter $parameter): bool
    {
        return is_a((string) $parameter->getType(), ServerRequestInterface::class, true);
    }
}

要使用它

$requestResolver = new RequestResolver($yourRequestFactory);
$result = \Norvica\Invoker\call($someInvokableController, ['id' => '123'], $requestResolver);

当然。添加该部分将明确说明库的范围和哲学。以下是将其包含在您的readme.md中的方法

运行测试

./vendor/bin/phpunit --testdox

项目哲学:简洁和简单

Invoker库的主要目标是保持尽可能简洁和简单。重点是提供用于以命名参数和自定义解析器调用可调用的核心实用工具。

范围之外

虽然我们感谢建议和pull requests,但请注意,特定实现解析器或额外功能被视为此库的范围之外。我们旨在保持代码库干净且易于维护,而不添加可能导致膨胀或复杂性的功能。

如果您需要更专业的行为,我们鼓励您扩展库或根据项目需求实现自己的解析器。

类似概念和替代方案

如果您对库感兴趣,您可能还希望探索其他类似工具和框架,它们提供了参数解析或方法调用功能。

Symfony动作参数解析

一个值得注意的替代方案是Symfony的动作参数解析。该功能允许您将传入的请求或任何其他数据转换为传递到控制器方法中的参数。虽然它与Symfony生态系统紧密集成,但它提供了一组内置解析器以及创建自定义解析器的功能。

PHP-DI Invoker

另一个具有非常相似理念的成熟项目是 PHP-DI Invoker。请随意查看项目的 README