Get defined functions: примеры (PHP)

Использование get_defined_functions для анализа функций в PHP
Раздел: Функции/аргументы
get_defined_functions(bool $exclude_disabled = true): array
Описание функции get_defined_functions

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

В PHP 8 функция имеет следующую сигнатуру:

get_defined_functions(bool $exclude_disabled = true): array

Единственный параметр $exclude_disabled управляет включением в результат отключенных (например, через директиву disable_functions) встроенных функций. Если параметр равен true, такие функции исключаются из массива. Значение по умолчанию — true.

Возвращаемый массив имеет фиксированную структуру с двумя ключами: internal (встроенные функции PHP) и user (функции, объявленные пользователем в коде). Каждый ключ содержит индексный массив строк с именами функций.

Базовые примеры использования
Получение всех доступных функций
<?php
// Объявим пользовательскую функцию для наглядности
function customHelper() {}

$allFunctions = get_defined_functions();
echo "Встроенных функций: " . count($allFunctions['internal']) . "\n";
echo "Пользовательских функций: " . count($allFunctions['user']) . "\n";

// Вывод первых 5 встроенных функций
print_r(array_slice($allFunctions['internal'], 0, 5));
?>
Встроенных функций: 1592
Пользовательских функций: 1
Array
(
    [0] => zend_version
    [1] => func_num_args
    [2] => func_get_arg
    [3] => func_get_args
    [4] => strlen
)
Использование параметра $exclude_disabled
<?php
// Предположим, что функция shell_exec отключена в php.ini
// disable_functions = shell_exec

$excluded = get_defined_functions(true);
$included = get_defined_functions(false);

$diff = array_diff($included['internal'], $excluded['internal']);
echo "Функции, исключаемые при exclude_disabled=true:\n";
print_r($diff);
?>
Функции, исключаемые при exclude_disabled=true:
Array
(
    [0] => shell_exec
)
Похожие функции в PHP

Для анализа среды выполнения и метапрограммирования в PHP существуют и другие функции.

Проверяет существование конкретной функции. Более эффективна для точечной проверки, так как не требует построения полного списка.

if (function_exists('array_filter')) {
    echo 'Функция доступна';
}
get_defined_vars

Возвращает все определенные переменные в текущей области видимости. Похожа по концепции, но работает с переменными.

get_declared_classes

Возвращает массив с именами объявленных классов. Аналог для объектно-ориентированной структуры.

Функцию get_defined_functions предпочтительнее использовать, когда необходим полный перечень функций для анализа, генерации документации или создания динамических маршрутов. Для единичных проверок лучше подходят function_exists или is_callable.

Типичные ошибки при использовании
Некорректная обработка структуры массива

Ожидание, что функция вернет простой список, а не многомерный массив.

<?php
$funcs = get_defined_functions();
// Ошибка: попытка применить count() напрямую
$count = count($funcs); // Вернет 2 (ключи 'internal' и 'user')
?>
Попытка вызова функции по имени без проверки

Получение имени из списка не гарантирует, что функция может быть безопасно вызвана в текущем контексте.

<?php
$funcs = get_defined_functions();
$randomFunc = $funcs['internal'][array_rand($funcs['internal'])];
// Опасный вызов без проверки
// $randomFunc(); // Может привести к неожиданным последствиям
?>
Игнорирование отключенных функций

При установке параметра $exclude_disabled в false в список могут попасть функции, вызов которых приведет к фатальной ошибке.

<?php
$funcs = get_defined_functions(false);
if (in_array('shell_exec', $funcs['internal'])) {
    // shell_exec может быть отключена, вызов вызовет ошибку
    // shell_exec('ls');
}
?>
Изменения в последних версиях PHP

В PHP 7.0.1 был добавлен параметр $exclude_disabled. До этой версии функция не принимала аргументов, а отключенные встроенные функции всегда исключались из результата.

Начиная с PHP 8.0, функция возвращает массив, где ключи internal и user гарантированно присутствуют, даже если соответствующие списки пусты. В более ранних версиях поведение могло отличаться.

В PHP 8.1 и 8.2 значительных изменений в работе функции не произошло, но продолжается рост количества встроенных функций, поэтому размер возвращаемого массива увеличивается с каждым релизом.

Расширенные примеры использования
Поиск пользовательских функций по паттерну
Пример php
<?php
function calculateTotal() {}
function validateEmail() {}
function sendNotification() {}

$defined = get_defined_functions();
// Поиск пользовательских функций, содержащих 'validate'
$validateFuncs = array_filter($defined['user'], 
    fn($name) => stripos($name, 'validate') !== false);
print_r($validateFuncs);
?>
Array
(
    [1] => validateEmail
)
Сравнение доступных функций до и после включения модуля
Пример php
<?php
$before = get_defined_functions()['internal'];
// Предполагаем, что расширение будет загружено динамически
// dl('some_extension.so'); // Загрузка расширения (недоступно в CLI)
$after = get_defined_functions()['internal'];
$newFuncs = array_diff($after, $before);
echo "Новые функции после загрузки расширения:\n";
print_r($newFuncs);
?>
Построение дерева функций по префиксам
Пример php
<?php
$functions = get_defined_functions();
$internal = $functions['internal'];
$grouped = [];
foreach ($internal as $func) {
    $prefix = explode('_', $func)[0];
    $grouped[$prefix][] = $func;
}
// Вывод групп с количеством функций
foreach ($grouped as $prefix => $list) {
    if (count($list) > 5) {
        echo "$prefix: " . count($list) . " функций\n";
    }
}
?>
array: 83 функций
str: 32 функций
file: 28 функций
stream: 27 функций
... (вывод сокращен)
Проверка конфликтов имен пользовательских и внутренних функций
Пример php
<?php
function array_filter() { // Опасное переопределение
    echo 'Пользовательская версия';
}

$defined = get_defined_functions();
$conflicts = array_intersect($defined['user'], $defined['internal']);
if ($conflicts) {
    echo "Конфликт имен: " . implode(', ', $conflicts);
}
?>
Конфликт имен: array_filter
Аналоги в других языках программирования

Get defined functions в Python

В Python нет прямой аналогии, но можно использовать модуль dir() для инспекции объектов и пространств имен или globals() для получения словаря текущих глобальных символов.

import builtins
# Получение встроенных функций
builtin_funcs = [name for name in dir(builtins) 
                 if callable(getattr(builtins, name))]
print(builtin_funcs[:5])
['ArithmeticError', 'AssertionError', 'AttributeError', 'BaseException', 'BlockingIOError']
JavaScript (Node.js)

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

// Получение глобальных свойств в Node.js
const globalProps = Object.getOwnPropertyNames(global);
const functions = globalProps.filter(prop => 
    typeof global[prop] === 'function');
console.log(functions.slice(0, 5));
[ 'Object', 'Function', 'Array', 'Number', 'parseFloat' ]

Get defined functions в MySQL

В SQL подобная функциональность отсутствует, так как язык не является императивным. Однако можно запрашивать информацию о доступных хранимых процедурах через системные таблицы, например INFORMATION_SCHEMA.ROUTINES.

PHP get_defined_functions function comments

En
Get defined functions Returns an array of all defined functions