Суть PHP в том, что он не имеет определенного синтаксиса при использовании функции с необязательными аргументами. Это:
foo(10);
может быть это
function foo($a) {}
или это
function foo($a = 0) {}
или это
function foo($a, $b = 0, ...) {}
(или даже function foo() {}
, но не обращайте на это внимания сейчас).
Итак, как мы можем вывести его, когда функция используется до ее определения?
Одно из решений состоит в том, чтобы записать все случаи использования, пока не придет определение, а затем посмотреть, смогут ли они все объединиться с ним. Приведенный выше пример будет хранить
int -> unit
и позже проверьте, совместимо ли это с
int -> (typ list) -> unit
или что угодно (где typ list
список необязательных аргументов).
Вы думаете, это может сработать? Существуют ли другие традиционные способы борьбы с этим?
Вам, вероятно, придется либо вставлять переменные «слабого» типа и сохранять их до тех пор, пока не будет найдено определение функции, либо сначала построить полный AST, а затем выполнить его через вывод типа и вызвать ошибку, если есть функции, определения которых неизвестны (I Интересно, что вы думаете о встроенных функциях, возможно, использовать предварительно запеченную базу данных сигнатур?).
Я не знаю, в какой степени это отвечает на ваш вопрос, но чтобы уточнить мой комментарий выше, вы можете использовать встроенный в PHP набор классов отражения, чтобы помочь разобраться и получить полезную информацию о функциях и их аргументах.
Конкретно я думаю ReflectionFunction
а также ReflectionParameter
может быть полезным в вашем случае, хотя есть гораздо больше функций, которые могут помочь.
Например, вот очень простой пример, где вы хотите получить некоторую информацию об аргументах функции:
<?php
// a simple function with an
// optional/default argument
function foo($a, $b = 0)
{
return $a + $b;
}
// create a ReflectionFunction object
// passing the name of the function name.
// you can also pass a variable reference
// to an anonymous function.
$refl = new ReflectionFunction('foo');
// iterate over the ReflectionFunction's
// parameter list to get a ReflectionParameter
// object for each of foo's arguments. here we're
// just printing out a __toString() summary of each
// argument.
foreach ($refl->getParameters() as $param) {
echo $param . PHP_EOL;
}
Урожайность:
Parameter #0 [ <required> $a ]
Parameter #1 [ <optional> $b = 0 ]
Как видите, этот простой пример показывает некоторую информацию о foo
Список аргументов: номер параметра, обязательный / необязательный, имя переменной и значение по умолчанию.
$param
это пример ReflectionParameter
поэтому есть несколько методов, которые вы можете вызвать для получения дополнительной информации о каждом аргументе, включая:
export
__construct
__toString
getName
isPassedByReference
canBePassedByValue
getDeclaringFunction
getDeclaringClass
getClass
isArray
isCallable
allowsNull
getPosition
isOptional
isDefaultValueAvailable
getDefaultValue
isDefaultValueConstant
getDefaultValueConstantName
Надеюсь это поможет! 🙂