Как формируются имена зависимостей
Лучше рассмотреть конкретный пример.
<?php
namespace App;
class Example
{
public function __construct(
int $arg_1,
Foo $arg_2,
string|int $arg_3,
int|string $arg_4,
Foo|string $arg_5,
string|Foo $arg_6,
?int $arg_7,
?Foo $arg_8,
$arg_9,
I $arg_10
Foo|int ...$arg_11,
) {
}
}
class Foo {}
interface I {}
| Номер аргумента | Имя аргумента | Глобавльное имя | Локальное имя |
|---|---|---|---|
| 1 | arg_1 | “arg_1” | “App\Example$arg_1 |
| 2 | arg_2 | “App\Foo” | “App\Example$arg_2” |
| 3 | arg_3 | “string|int” | “App\Example$arg_3” |
| 4 | arg_4 | “string|int” | “App\Example$arg_4” |
| 5 | arg_5 | “App\Foo|string” | “App\Example$arg_5” |
| 6 | arg_6 | “App\Foo|string” | “App\Example$arg_6” |
| 7 | arg_7 | “arg_7” | “App\Example$arg_7 |
| 8 | arg_8 | “?App\Foo” | “App\Example$arg_8” |
| 9 | arg_9 | “arg_9” | “App\Example$arg_9” |
| 10 | arg_10 | “App\I” | “App\Example$arg_10” |
| 11 | arg_11 | “…App\Foo|int” | “…App\Example$arg_11” |
Имя аргумента != имени зависимости
Необходимо разделять имя аргумента и имя зависимости, это разные вещи.
Имя зависимости это более сложная вещь, которая может в себя включать имя аргумента.
Глобальное vs Локальное имена зависимостей.
Глобальное имя зависимости используется на уровне всего проекта, использовать такие имена удобно чтобы один раз зарегистрировать значение и использовать его в разных зависимостях, например реализацию интерфейса или абстрактного класса.
Локальное имя это возможность переопределить зависимость в конкретном ОДНОМ месте, точечно.
С помощью таких имен удобно задавать примитивные параметры вроде логинов или паролей и тд.
Правила формирования локальных имен.
В общем виде именование выглядит следующим образом:
$prefix . $fqcn . '$' . $argument_name
$prefix = '...' если аргумент является variadic, в остальных случаях $prefix = ''.
$fqcn - это полное имя куда внедряется зависимость.
$argument_name это имя аргумента.
Правила формирования глобальных имен.
Если у аргумента не указан тип или он является primitive (string, int, bool, array и тд), то:
$prefix . $argument_name
В остальных случаях:
$prefix . (string)$type
$prefix = '...' если аргумент является variadic, в остальных случаях $prefix = ''.
$argument_name - имя аргумента.
Самое интересное тут как PHP приводит тип к строке.
Если тип является nullable то в начале ему указывается ?.
Если тип является составным (Union, или Intersection, или DNF) тогда тип сортируется в “определенной” последовательности, мало кому известной и нигде не зафиксированной.
В приведенном выше примере посмотрите глобальные имена для аргумента 3 и 4, в конструкторе порядок у них разный, а php приводит их к одинаковому имени, а также посмотрите на аргумент 5 и 6 из таблицы, ситуация аналогичная.