Created
April 4, 2024 06:58
-
-
Save rsky/1fcd7eef42cb71272113e610d8bcfcd9 to your computer and use it in GitHub Desktop.
PHP名前付き引数を配列から展開してみる
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
interface Instantiatable | |
{ | |
} | |
class Instantiator | |
{ | |
/** | |
* @template T | |
* @param class-string<T> $class_name | |
* @param Parameter[] $params | |
* @return T | |
*/ | |
public function instantiate(string $class_name, array $params): object | |
{ | |
if (!is_a($class_name, Instantiatable::class, true)) { | |
throw new \InvalidArgumentException("$class_name does not implement Instantiatable"); | |
} | |
return new $class_name(...array_reduce($params, function ($kwargs, $param) { | |
$kwargs[$param->getName()] = $param->getValue(); | |
return $kwargs; | |
}, [])); | |
} | |
} | |
class Parameter | |
{ | |
public function __construct( | |
private readonly string $name, | |
private readonly string $type, | |
private readonly string $value, | |
) { | |
} | |
public function getName(): string | |
{ | |
return $this->name; | |
} | |
public function getValue(): mixed | |
{ | |
return match ($this->type) { | |
'string' => $this->value, | |
'int' => intval($this->value), | |
'float' => floatval($this->value), | |
'bool' => boolval($this->value), | |
default => throw new \UnexpectedValueException("Unexpected type: {$this->type}"), | |
}; | |
} | |
} | |
class Hoge implements Instantiatable | |
{ | |
public function __construct(private readonly int $a, private readonly int $b) | |
{ | |
} | |
public function __toString(): string | |
{ | |
return "a={$this->a}, b={$this->b}"; | |
} | |
} | |
$paramSets = [ | |
[ | |
new Parameter(name: 'a', type: 'int', value: '100'), | |
new Parameter(name: 'b', type: 'int', value: '200'), | |
], | |
[ | |
new Parameter(name: 'b', type: 'int', value: '2'), | |
new Parameter(name: 'a', type: 'int', value: '3'), | |
], | |
]; | |
$instantiator = new Instantiator(); | |
foreach ($paramSets as $params) { | |
$hoge = $instantiator->instantiate(Hoge::class, $params); | |
echo $hoge, "\n"; | |
} | |
__halt_compiler(); | |
This will outputs: | |
$ php ctor_named_args.php | |
a=100, b=200 | |
a=3, b=2 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment