|
1
|
<?php |
|
2
|
|
|
3
|
/** |
|
4
|
* Converter Feature - Type conversion system |
|
5
|
* |
|
6
|
* Provides automatic type conversion with reflection-based type matching. |
|
7
|
* Transform route return values, exceptions, and domain objects to HTTP responses |
|
8
|
* without manual serialization code in every route handler. |
|
9
|
* |
|
10
|
* Features: |
|
11
|
* - Type-safe conversion using PHP's type system via reflection |
|
12
|
* - Union input types (single converter handles multiple input types) |
|
13
|
* - Specificity resolution (single > union, class > interface > parent) |
|
14
|
* - Extensible converter registration for custom types |
|
15
|
* - Returns null when conversion impossible (no exceptions) |
|
16
|
* |
|
17
|
* Common use cases: |
|
18
|
* - Route return value conversion (arrays → JSON, strings → text/plain) |
|
19
|
* - Exception to HTTP response conversion (Throwable → error pages) |
|
20
|
* - Content negotiation (same data → JSON/XML/HTML based on Accept header) |
|
21
|
* - Domain model serialization (custom objects → appropriate response format) |
|
22
|
* |
|
23
|
* @see ConverterRegistry For converter registration and management |
|
24
|
* @see ConverterInterface For implementing custom converters |
|
25
|
* @see README.md For comprehensive documentation and examples |
|
26
|
*/ |
|
27
|
|
|
28
|
namespace mini; |
|
29
|
|
|
30
|
use mini\Converter\ConverterRegistryInterface; |
|
31
|
use Psr\Http\Message\ResponseInterface; |
|
32
|
|
|
33
|
/** |
|
34
|
* Convert a value to a target type |
|
35
|
* |
|
36
|
* Uses the converter registry to find an appropriate converter for the given |
|
37
|
* input and target type. Throws if no suitable converter is found. |
|
38
|
* |
|
39
|
* The converter system uses reflection-based type matching to find the most |
|
40
|
* specific converter. Resolution order: direct single-type converter, union |
|
41
|
* type converter, parent class converters, interface converters. |
|
42
|
* |
|
43
|
* Examples: |
|
44
|
* ```php |
|
45
|
* // Convert exception to error response |
|
46
|
* $response = convert($exception, ResponseInterface::class); |
|
47
|
* |
|
48
|
* // Convert array to JSON response |
|
49
|
* $response = convert(['data' => 'value'], ResponseInterface::class); |
|
50
|
* |
|
51
|
* // Convert string to text response |
|
52
|
* $response = convert("Hello World", ResponseInterface::class); |
|
53
|
* |
|
54
|
* // Custom domain objects |
|
55
|
* $response = convert($userModel, ResponseInterface::class); |
|
56
|
* ``` |
|
57
|
* |
|
58
|
* Register converters in bootstrap.php: |
|
59
|
* ```php |
|
60
|
* $registry = Mini::$mini->get(ConverterRegistryInterface::class); |
|
61
|
* $registry->register(function(MyModel $m): ResponseInterface { ... }); |
|
62
|
* ``` |
|
63
|
* |
|
64
|
* @template O |
|
65
|
* @param mixed $input The value to convert |
|
66
|
* @param class-string<O> $targetType The desired output type |
|
67
|
* @return O The converted value |
|
68
|
* @throws \RuntimeException If no converter is registered for this input→target combination |
|
69
|
* @see ConverterRegistryInterface::register() For registering custom converters |
|
70
|
*/ |
|
71
|
function convert(mixed $input, string $targetType): mixed |
|
72
|
{ |
|
73
|
return Mini::$mini->get(ConverterRegistryInterface::class)->convert($input, $targetType); |
|
74
|
} |
|
75
|
|
|
76
|
/** |
|
77
|
* ============================================================================ |
|
78
|
* Converter Service Registration |
|
79
|
* ============================================================================ |
|
80
|
*/ |
|
81
|
|
|
82
|
namespace mini\Converter; |
|
83
|
|
|
84
|
use mini\Mini; |
|
85
|
use mini\Lifetime; |
|
86
|
|
|
87
|
// Register ConverterRegistryInterface as singleton |
|
88
|
Mini::$mini->addService(ConverterRegistryInterface::class, Lifetime::Singleton, fn() => Mini::$mini->loadServiceConfig(ConverterRegistryInterface::class)); |
|
89
|
|