PHPackages                             baraja-core/service-method-invoker - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. baraja-core/service-method-invoker

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

baraja-core/service-method-invoker
==================================

Invoke method by service, name and arguments.

v2.4.0(3y ago)2230.8k14PHPPHP ^8.1CI failing

Since Apr 23Pushed 4mo ago1 watchersCompare

[ Source](https://github.com/baraja-core/service-method-invoker)[ Packagist](https://packagist.org/packages/baraja-core/service-method-invoker)[ Docs](https://github.com/baraja-core/service-method-invoker)[ RSS](/packages/baraja-core-service-method-invoker/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (10)Dependencies (8)Versions (36)Used By (4)

Service Method Invoker
======================

[](#service-method-invoker)

[![Integrity check](https://github.com/baraja-core/service-method-invoker/workflows/Integrity%20check/badge.svg)](https://github.com/baraja-core/service-method-invoker/workflows/Integrity%20check/badge.svg)

A robust PHP library for safely invoking methods on services with automatic parameter validation, type coercion, and entity hydration. Perfect for API endpoints, command handlers, and any scenario where you need to dynamically call methods with user-provided data.

🎯 Key Features
--------------

[](#-key-features)

- **Safe method invocation** with automatic parameter validation and type checking
- **Automatic type coercion** for scalar types (bool, int, float, string, array)
- **Entity hydration** - automatically converts array data to typed objects/DTOs
- **PHP 8.1+ enum support** with case-insensitive matching
- **Nullable parameter handling** with proper default value support
- **Tracy Debugger integration** with custom BlueScreen panels for debugging
- **Circular reference detection** in nested entity hydration
- **Custom entity repository support** for resolving entities by ID
- **Detailed exception messages** with context about the failing service and method

🏗️ Architecture
---------------

[](#️-architecture)

The package consists of several components working together to provide safe method invocation:

```
┌─────────────────────────────────────────────────────────────────┐
│                    ServiceMethodInvoker                         │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │  invoke(service, method, params)                        │   │
│  │  getInvokeArgs(service, method, params)                 │   │
│  └─────────────────────────────────────────────────────────┘   │
│           │                    │                    │           │
│           ▼                    ▼                    ▼           │
│  ┌─────────────┐    ┌─────────────────┐    ┌──────────────┐    │
│  │Type Coercion│    │Entity Hydration │    │Enum Handling │    │
│  │ fixType()   │    │hydrateDataTo..()│    │processEnum..()│   │
│  └─────────────┘    └─────────────────┘    └──────────────┘    │
└─────────────────────────────────────────────────────────────────┘
         │                       │
         ▼                       ▼
┌─────────────────┐    ┌─────────────────────────┐
│     Helpers     │    │ ProjectEntityRepository │
│ - Type parsing  │    │ - Find entities by ID   │
│ - Annotations   │    │ (optional interface)    │
│ - Use statements│    └─────────────────────────┘
└─────────────────┘
         │
         ▼
┌─────────────────┐    ┌─────────────────────────┐
│   BlueScreen    │    │  RuntimeInvokeException │
│ Tracy panel     │    │  Contextual exceptions  │
└─────────────────┘    └─────────────────────────┘

```

### 🔧 Components

[](#-components)

ComponentDescription`ServiceMethodInvoker`Main class responsible for invoking methods with validated and hydrated parameters`Service`Interface for services that extends `Stringable` for user-friendly error messages`RuntimeInvokeException`Exception class that carries service context, method name, and parameters for debugging`BlueScreen`Tracy Debugger integration that renders detailed error panels with source code`Helpers`Utility class for type resolution, annotation parsing, and use statement extraction`ProjectEntityRepository`Interface for custom entity resolution by ID (e.g., Doctrine integration)📦 Installation
--------------

[](#-installation)

It's best to use [Composer](https://getcomposer.org) for installation, and you can also find the package on [Packagist](https://packagist.org/packages/baraja-core/service-method-invoker) and [GitHub](https://github.com/baraja-core/service-method-invoker).

To install, simply use the command:

```
$ composer require baraja-core/service-method-invoker
```

You can use the package manually by creating an instance of the internal classes, or register a DIC extension to link the services directly to the Nette Framework.

**Requirements:** PHP 8.1 or higher

🚀 Basic Usage
-------------

[](#-basic-usage)

### Simple Method Invocation

[](#simple-method-invocation)

Think of a simple service as an API endpoint with a public method for hydrating your data:

```
$invoker = new \Baraja\ServiceMethodInvoker;
$apiEndpoint = new \Baraja\MyApiEndpoint;

$data = $invoker->invoke($apiEndpoint, 'actionDetail', ['id' => 42]);

var_dump($data); // return "My id is: 42"
```

And your endpoint can be:

```
class MyApiEndpoint
{
    public function actionDetail(int $id): string
    {
        return 'My id is: ' . $id;
    }
}
```

### Getting Invoke Arguments Without Execution

[](#getting-invoke-arguments-without-execution)

If you need to prepare the arguments without actually invoking the method:

```
$invoker = new \Baraja\ServiceMethodInvoker;
$args = $invoker->getInvokeArgs($service, 'methodName', $params);

// $args is now a validated and hydrated array ready for method invocation
```

🎭 Type Coercion
---------------

[](#-type-coercion)

The invoker automatically handles type conversion based on method parameter types:

### Scalar Types

[](#scalar-types)

```
class MyService
{
    public function process(
        int $count,      // "42" -> 42, "null" -> null (if nullable)
        float $price,    // "19.99" -> 19.99
        bool $active,    // "true", "1", "yes" -> true; others -> false
        string $name,    // kept as-is
        array $items,    // kept as-is
    ): void {
        // ...
    }
}

$invoker->invoke($service, 'process', [
    'count' => '42',
    'price' => '19.99',
    'active' => 'yes',
    'name' => 'Test',
    'items' => ['a', 'b'],
]);
```

### Nullable Parameters

[](#nullable-parameters)

When a parameter is nullable and receives an empty or falsy value, it's converted to `null`:

```
public function find(?int $id): void
{
    // '' or '0' with nullable type -> null
    // '0' with non-nullable int -> 0
}
```

### Boolean Conversion

[](#boolean-conversion)

The following string values are treated as `true`: `"1"`, `"true"`, `"yes"` (case-insensitive). All other values are converted to `false`.

📊 Entity Hydration
------------------

[](#-entity-hydration)

One of the most powerful features is automatic entity/DTO hydration from array data:

### Simple Entity

[](#simple-entity)

```
class CreateUserRequest
{
    public function __construct(
        public string $email,
        public string $name,
        public ?int $age = null,
    ) {}
}

class UserController
{
    public function create(CreateUserRequest $request): User
    {
        // $request is automatically hydrated from the params array
        return new User($request->email, $request->name);
    }
}

$invoker->invoke($controller, 'create', [
    'email' => 'john@example.com',
    'name' => 'John Doe',
    'age' => 25,
]);
```

### Nested Entities

[](#nested-entities)

The invoker supports nested entity hydration:

```
class Address
{
    public function __construct(
        public string $street,
        public string $city,
    ) {}
}

class Order
{
    public function __construct(
        public string $product,
        public Address $shippingAddress,
    ) {}
}

$invoker->invoke($service, 'createOrder', [
    'product' => 'Widget',
    'shippingAddress' => [
        'street' => '123 Main St',
        'city' => 'Prague',
    ],
]);
```

### Property Hydration via Setters

[](#property-hydration-via-setters)

If an entity has setter methods, they will be used for hydration:

```
class UserEntity
{
    private string $email;

    public function setEmail(string $email): void
    {
        $this->email = strtolower($email);
    }
}
```

### Circular Reference Detection

[](#circular-reference-detection)

The invoker detects and prevents circular references in entity hydration:

```
class NodeA
{
    public NodeB $child;
}

class NodeB
{
    public NodeA $parent; // This would cause a circular reference
}

// RuntimeInvokeException: Circular reference detected...
```

🔢 PHP 8.1+ Enum Support
-----------------------

[](#-php-81-enum-support)

The invoker fully supports PHP enums with case-insensitive matching:

```
enum Status: string
{
    case Active = 'active';
    case Inactive = 'inactive';
    case Pending = 'pending';
}

class OrderService
{
    public function updateStatus(int $orderId, Status $status): void
    {
        // ...
    }
}

// All of these work:
$invoker->invoke($service, 'updateStatus', ['orderId' => 1, 'status' => 'active']);
$invoker->invoke($service, 'updateStatus', ['orderId' => 1, 'status' => 'ACTIVE']);
$invoker->invoke($service, 'updateStatus', ['orderId' => 1, 'status' => 'Active']);
```

If an invalid enum value is provided, a helpful error message is shown:

```
Value "unknown" is not possible option of enum "Status". Did you mean "active", "inactive", "pending"?

```

🔍 Custom Entity Repository
--------------------------

[](#-custom-entity-repository)

For integrating with ORMs like Doctrine, implement the `ProjectEntityRepository` interface:

```
use Baraja\ServiceMethodInvoker\ProjectEntityRepository;

class DoctrineEntityRepository implements ProjectEntityRepository
{
    public function __construct(
        private EntityManagerInterface $em,
    ) {}

    public function find(string $className, int|string $id): ?object
    {
        return $this->em->find($className, $id);
    }
}

$invoker = new ServiceMethodInvoker(
    projectEntityRepository: new DoctrineEntityRepository($entityManager),
);
```

This allows automatic entity resolution from IDs:

```
class ArticleController
{
    public function show(Article $article): Response
    {
        // $article is automatically loaded from the database using the ID
    }
}

$invoker->invoke($controller, 'show', ['article' => 42]);
// Article with ID 42 is automatically loaded via the repository
```

📑 The Data Parameter
--------------------

[](#-the-data-parameter)

When `dataMustBeArray` is `true`, a parameter named `data` must be typed as `array` and will receive all input parameters:

```
class BatchProcessor
{
    public function process(array $data): void
    {
        // $data contains all the input parameters
    }
}

$invoker->invoke($processor, 'process', [
    'item1' => 'value1',
    'item2' => 'value2',
], dataMustBeArray: true);

// $data = ['item1' => 'value1', 'item2' => 'value2']
```

🐛 Tracy Debugger Integration
----------------------------

[](#-tracy-debugger-integration)

When Tracy Debugger is available, the package automatically registers a custom BlueScreen panel that provides:

- **Service class name** and the exact method being called
- **Source code highlighting** of the failing method
- **Input parameters table** showing all passed values
- **Direct editor link** to open the file at the exact line

This integration is automatic when Tracy is installed - no configuration needed.

⚠️ Exception Handling
---------------------

[](#️-exception-handling)

The `RuntimeInvokeException` provides rich context for debugging:

```
try {
    $invoker->invoke($service, 'method', $params);
} catch (RuntimeInvokeException $e) {
    $e->getService();  // The service object that failed
    $e->getMethod();   // The method name that was being called
    $e->getParams();   // The parameters that were passed
    $e->getMessage();  // Detailed error message
}
```

### Common Exceptions

[](#common-exceptions)

ScenarioException TypeMethod doesn't exist`InvalidArgumentException`Method is not callable`InvalidArgumentException`Required parameter missing`RuntimeInvokeException`Invalid enum value`RuntimeInvokeException`Type incompatibility`RuntimeInvokeException`Circular reference in entities`RuntimeInvokeException`Entity class doesn't exist`RuntimeInvokeException`🎨 Service Interface
-------------------

[](#-service-interface)

Implement the `Service` interface on your services for better error messages:

```
use Baraja\Service;

class UserApiEndpoint implements Service
{
    public function __toString(): string
    {
        return 'User API Endpoint';
    }

    public function getUser(int $id): array
    {
        // ...
    }
}

// Error messages will now show "User API Endpoint" instead of the class name
```

📋 DateTime Handling
-------------------

[](#-datetime-handling)

`DateTimeInterface` implementations are automatically instantiated:

```
class EventService
{
    public function schedule(
        string $name,
        \DateTimeImmutable $startDate,
    ): void {
        // $startDate is automatically created from the string value
    }
}

$invoker->invoke($service, 'schedule', [
    'name' => 'Conference',
    'startDate' => '2024-06-15 10:00:00',
]);
```

🔒 Default Values for Empty Inputs
---------------------------------

[](#-default-values-for-empty-inputs)

When a non-nullable parameter receives an empty value, appropriate defaults are used:

TypeDefault Value`string``""` (empty string)`int``0``float``0.0``bool``false``array``[]`👤 Author
--------

[](#-author)

**Jan Barasek** -

📄 License
---------

[](#-license)

`baraja-core/service-method-invoker` is licensed under the MIT license. See the [LICENSE](https://github.com/baraja-core/service-method-invoker/blob/master/LICENSE) file for more details.

###  Health Score

48

—

FairBetter than 95% of packages

Maintenance51

Moderate activity, may be stable

Popularity32

Limited adoption so far

Community17

Small or concentrated contributor base

Maturity76

Established project with proven stability

 Bus Factor1

Top contributor holds 98.1% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~25 days

Recently: every ~73 days

Total

31

Last Release

1455d ago

Major Versions

v1.2.5 → v2.0.02021-02-08

PHP version history (4 changes)v1.0.0PHP &gt;=7.1.0

v1.1.0PHP &gt;=7.4.0

v2.0.0PHP ^8.0

v2.4.0PHP ^8.1

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/3382204?v=4)[baraja](/maintainers/baraja)[@baraja](https://github.com/baraja)

---

Top Contributors

[![janbarasek](https://avatars.githubusercontent.com/u/4738758?v=4)](https://github.com/janbarasek "janbarasek (105 commits)")[![dependabot-preview[bot]](https://avatars.githubusercontent.com/in/2141?v=4)](https://github.com/dependabot-preview[bot] "dependabot-preview[bot] (1 commits)")[![HamAndRock](https://avatars.githubusercontent.com/u/24235083?v=4)](https://github.com/HamAndRock "HamAndRock (1 commits)")

---

Tags

invokeinvokermethodphp

###  Code Quality

Static AnalysisPHPStan

Type Coverage Yes

### Embed Badge

![Health badge](/badges/baraja-core-service-method-invoker/health.svg)

```
[![Health](https://phpackages.com/badges/baraja-core-service-method-invoker/health.svg)](https://phpackages.com/packages/baraja-core-service-method-invoker)
```

###  Alternatives

[torann/geoip

Support for multiple Geographical Location services.

2.2k14.2M76](/packages/torann-geoip)[jetbrains/phpstorm-attributes

PhpStorm specific attributes

41416.0M647](/packages/jetbrains-phpstorm-attributes)[babdev/pagerfanta-bundle

Bundle integrating Pagerfanta with Symfony

20917.8M65](/packages/babdev-pagerfanta-bundle)[jakeasmith/http_build_url

Provides functionality for http\_build\_url() to environments without pecl\_http.

19817.7M93](/packages/jakeasmith-http-build-url)[php-di/phpdoc-reader

PhpDocReader parses @var and @param values in PHP docblocks (supports namespaced class names with the same resolution rules as PHP)

7431.6M55](/packages/php-di-phpdoc-reader)[haydenpierce/class-finder

A library that can provide of a list of classes in a given namespace

3214.8M114](/packages/haydenpierce-class-finder)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
