PHP:: Полный литерал метода в строку

#php #string #class #methods #literals

#php #строка #класс #методы #литералы

Вопрос:

По сути, я стремлюсь передать статический метод класса обратному вызову, но не хочу делать это с помощью жестко запрограммированной строки, а скорее полного литерала метода класса. Мы можем сделать это, используя классы, подобные so:

 $name = NSFooClass::class;
 

вместо:

 $name = 'NSFooClass';
 

который даст нам строку полного имени класса. Я стремлюсь иметь возможность сделать что-то подобное для метода класса следующим образом:

 $name = NSFooClass::foo_method::method;
 

вместо:

 $name = 'NSFooClass::foo_method';
 

Это более управляемо, и я могу лучше использовать функциональность IDE, используя литералы. Любым аналогичным способом я могу добиться того, чего я хочу, с помощью методов класса без использования строк?

Ответ №1:

В настоящее время такого механизма, встроенного в язык, нет. Это было предложено — см., Например, Это обсуждение от февраля 2020 года, — но есть больше нюансов, о которых нужно подумать, чем может быть сразу видно; В частности:

  • Должен ли синтаксис разрешаться во время выполнения и проверять существование класса и метода ( ::class в большинстве случаев нет; голая функция, подобная strlen::func , должна была бы из-за способа разрешения пространств имен; реализация объекта __callStatic никогда не могла использоваться таким образом)?
  • Должен ли результат быть строкой, массивом (см. Ниже) или Closure объектом?

В любом случае, это тема для другого места…

Как говорится на странице руководства по callable типу, существует два способа указать статический метод для использования в качестве обратного вызова:

  • В виде строки, как в вашем примере 'NSFooClass::foo_method'
  • Как массив, где первая часть — это имя класса, а вторая часть — имя метода: ['NSFooClass', 'foo_method']

Поскольку только имя класса должно быть указано с информацией о пространстве имен, вы можете использовать ::class со вторым синтаксисом, чтобы получить почти то, что вы хотели:

 $callback = [NSFooClass::class, 'foo_method'];
 

Это позволяет любой приличной среде разработки определить ссылку на класс и позволяет ссылаться на него по импортированному или псевдонимному имени.

Стоит отметить, что если callable тип указан в параметре или объявлении возвращаемого типа или в docblock, некоторые IDE (например, PhpStorm) «поймут» любой формат как ссылку на метод и включат его в такие функции, как «поиск использований» и «перейти к объявлению».

Комментарии:

1. Отличный ответ! Один оператор, отвечающий на вопрос, за которым следует очень подробное объяснение, а также обходные пути. Большое вам спасибо!