Подключение к вызовам функций в php


Немного предыстории: Во время выполнения я хотел бы иметь возможность просматривать документацию в стиле javadoc, которая в настоящее время называется функциями, чтобы определить ее формальное (типизированное) объявление. Это позволило бы проверять типы во время выполнения (для простых и сложных типов) посредством отражения (за определенную плату) во время отладки и тестирования, что я бы счел чрезвычайно полезным.

Итак, в php я хотел бы, чтобы определяемая пользователем функция вызывалась всякий раз, когда будет вызвана любая другая функция. То есть, если вызывается функция foo(), я хотел бы, чтобы моя функция callHookHandler() вызывалась непосредственно перед этим.

Одним из решений было бы реализовать __call() во всех пользовательских классах, но это и громоздко, и не включает поддержку функций, определенных вне классов, поэтому я ищу лучшее решение.

Author: hakre, 2011-06-16

2 answers

Это звучит немного забавно, поэтому я собираюсь попробовать ответить на него.

Я надеюсь, что это поможет вам. Дай мне знать, как все пройдет.

Итак, то, о чем вы просите, можно сделать, и вот как:

Для Функций:

  1. Получить все определенные функции с помощью $function = get_defined_functions().
  2. Выполните цикл по ключу $functions['user'] и проверьте каждый из них с помощью класса ReflectionFunction. Вам нужно будет получить:
    1. Комментарий с использованием ->getDocComment()
    2. Аргументы, использующие ->getParameters()
  3. Творите чудеса (я дам вам понять, как разобрать комментарий, используя некоторые регулярные расширения, и сопоставить его со списком параметров из отражения. Не забывайте о дополнительных параметрах!)
  4. Переименуйте функцию, используя runkit_function_rename
  5. Сгенерируйте код в строке, которая проверяет параметры и вызывает переименованную функцию
  6. Создайте список параметров в виде строки
  7. Создайте новую функцию с помощью runkit_function_add, используя код, сгенерированный на шаге #5 и список параметров из шага #6.

Для Занятий:

  1. Получить список классов с помощью $classes = get_declared_classes();
  2. Просмотрите каждый из них и проверьте его с помощью ReflectionObject и ->getMethods(), чтобы получить методы. Убедитесь, что класс не является внутренним с помощью ->isInternal(), потому что мы ничего не можем сделать с внутренними классами.
  3. Во внутреннем цикле... пройдите через каждый метод, используя класс ReflectionMethod. Получите аргументы и комментарии PHPDoc/javadoc точно так же, как вы делали с обычными функции.
  4. Сделайте то же самое, что вы сделали с функциями, только вместо этого используйте runkit_method_add и runkit_method_rename.

Недостатки:

Вы не сможете выполнить проверку внутренних методов и функций класса (что нормально, потому что у них все равно не будет комментариев к документам).

Это большая работа! Я оставил много частей на ваше воображение, чтобы это не было длиной в короткую книгу.

Пожалуйста, пришлите мне это или откройте исходный код и дайте мне знать, когда ты заканчивай, я действительно хочу использовать это сам. Контактная информация находится на моем веб-сайте, который находится в моем профиле;)

В качестве альтернативы:

Вы можете использовать трассировку функции xdebug вместе с отражением, а затем проанализировать результаты после факта, чтобы вам не пришлось динамически редактировать код. Если вы хотите написать модульный тест, вы можете даже автоматизировать его.

Надеюсь, что проверка типов войдет в будущие версии PHP, и ждите: https://wiki.php.net/rfc/typechecking

Примечания:

Эта ссылка на класс содержит потенциально полезный пример анализа документов в разделе комментариев страница: http://us.php.net/manual/en/class.reflectionmethod.php

Ссылки

 5
Author: Andrew Curioso, 2017-08-03 20:27:33

Альтернативный способ подключиться к вызову функции - использовать трюк с пространствами имен: Перехват выполнения системных функций в PHP

Вы также можете использовать Go! структура для определения аспекта, позволяющего автоматически перехватывать выполнение системных функций.

 1
Author: lisachenko, 2013-09-18 23:13:11