Каковы практические и изощренные примеры использования PHP Tokenizer?
Кто-нибудь использовал это?
Каковы практические и изощренные примеры использования PHP Tokenizer?
Кто-нибудь использовал это?
Я использую PHP_CodeSniffer для соответствия стиля кодирования, который построен на токенизаторе. Кроме того, некоторые структуры (например, Symfony 2) используют токенизатор для генерации файлов кеша или файлов промежуточного класса PHP-кода. Также возможно использовать токенизатор для создания форматирования исходного кода или синтаксического ярлыка.
В принципе, везде, где вы используете PHP-код в качестве данных, вы можете использовать токенизатор. Это намного надежнее, если вы пытаетесь разобрать PHP-код с регулярными выражениями или другими функциями обработки строк.
Я лично использовал его для создания изолированной программной среды PHP, которая пытается создать более безопасную среду для выполнения PHP-скриптов.
Кроме того, я сделал множество экспериментов для препроцессора PHP, например. У меня есть (неполный) эмулятор PHP 5.3 для PHP 5.2, называемый prephp.
И многие другие подобные инструменты, такие как анализаторы исходного кода (для аудита безопасности, code style,...) также используйте Tokenizer.
Но даже для небольших вещей Tokenizer может быть удобен. Не только крупномасштабные анализаторы кода. Например, если вы принимаете массив PHP и хотите проверить, что он не злонамерен, вы можете сделать это с помощью Tokenizer.
PS: В настоящее время я перехожу к фактическому анализу PHP, а не просто к его токенированию, используя PHP-парсер, написанный на PHP. Недавно (он работает, но пока еще практически не используется).
Интересный вопрос.
Я еще не использовал токенизатор в каких-либо производственных проектах, но есть несколько вопросов о переполнении стека, для которых токенизатор является (или, по крайней мере, одним) правильным ответом.
Автоматический синтаксический разбор PHP для разделения PHP-кода из HTML - извлечение комментариев из PHP-кода, например. для сборки документации (phpDocumentor работает таким образом)
Класс существует во внешнем файле - анализ кода, видя, существует ли класс внутри файла (например, для системы управления плагинами)
Постоянно записывать переменные в php файл с php - изменять файлы исходного кода PHP, например. для заполнения конфигурационных переменных. Использование токенизатора будет первым шагом для этого на уровне анализатора.
Как создать список всех встроенных функций PHP, которые использует проект? - анализ того, какие функции используются в проекте PHP
Довольно простое использование подсветки синтаксиса.
foreach(token_get_all($source) as $token) {
if (is_array($token))
{
$map = "token_name";
echo "<span class={$map($token[0])}>$token[1]</span>";
}
else {
echo "<span class=T_RAW>$token</span>";
}
}
Номера маркеров обычно преобразуются в более удобные имена классов CSS, но вы можете просто создать таблицу стилей только с тегами .T_COMMENT,.T_ARRAY,.T_ELSEIF,.T_FUNCTION....
Я использовал токенизатор для поиска числа циклической сложности и некоторых других кодовых показателей обратного вызова:
if ((isset($reflection) === true) && ($reflection->getFileName() !== false))
{
if (($source = file($reflection->getFileName(), FILE_IGNORE_NEW_LINES)) !== false)
{
$source = implode("\n", array_slice($source, $reflection->getStartLine() - 1, $reflection->getEndLine() - ($reflection->getStartLine() - 1)));
$result[$key]['source'] = array
(
'ccn' => 1,
'statements' => 0,
'lines' => array
(
'logical' => array(),
'physical' => substr_count($source, "\n"),
),
);
if (is_array($tokens = token_get_all(sprintf('<?php %s ?>', $source))) === true)
{
$points = array_map('constant', array_filter(array
(
'T_BOOLEAN_AND',
'T_BOOLEAN_OR',
'T_CASE',
'T_CATCH',
'T_ELSEIF',
'T_FINALLY',
'T_FOR',
'T_FOREACH',
'T_GOTO',
'T_IF',
'T_LOGICAL_AND',
'T_LOGICAL_OR',
'T_LOGICAL_XOR',
'T_WHILE',
), 'defined'));
foreach ($tokens as $token)
{
if (is_array($token) === true)
{
if ((in_array($token[0], array(T_CLOSE_TAG, T_COMMENT, T_DOC_COMMENT, T_INLINE_HTML, T_OPEN_TAG), true) !== true) && (strlen(trim($token[1])) > 0))
{
if (in_array($token[0], $points, true) === true)
{
++$result[$key]['source']['ccn'];
}
array_push($result[$key]['source']['lines']['logical'], $token[2]);
}
}
else if (strncmp($token, '?', 1) === 0)
{
++$result[$key]['source']['ccn'];
}
else if (strncmp($token, ';', 1) === 0)
{
++$result[$key]['source']['statements'];
}
}
$result[$key]['source']['lines']['logical'] = max(0, count(array_unique($result[$key]['source']['lines']['logical'])) - 1);
}
}
}
Мой друг написал Überloader (автозагрузчик грубой силы для PHP5.), который использует этот самый метод, когда он индексирует файлы классов. Метод _check_file()
из него будет представлять для вас особый интерес.
Überloader предназначен для устаревших проектов, которые не планировали или не думали об их соглашениях об именах или файловых структурах.
Я использую класс каждый день в старых проектах, которые я исправляю или обновляю.
Из комментария в руководстве по PHP:
Функции токенизатора довольно мощный. Например, вы можете получить все методы в заданном класс с использованием алгоритма, подобного:
для каждого токена: если токен T_FUNCTION затем запустить буфер, если буфер запущен затем добавьте текущую строку в буфер, если токен (стоп-буфер
И самое главное, что класс методы будут иметь правильный случай, поэтому это хороший способ обойти ограничения с помощью get_class_methods возвращает имена нижнего регистра. Также так как с помощью аналогичного алгоритма вы может читать аргументы функции вы можете реализовать Reflections-like функциональность в PHP4.
Наконец, вы можете использовать его как более простой метод извлечения Javadoc из для создания документации. Класс util/MethodTable.php в AMFPHP (http://www.amfphp.org) использует функции токенизатора для создания таблицу методов со всеми аргументы, описание, тип возврата, и т.д., и из этой таблицы методов он может генерировать ActionScript, который соответствует PHP, но он также может быть генерировать JavaScript, документацию файлы или в основном все, что вы ставите ваш ум. Я также вижу, что это может быть базой для класса → WSDL файловый генератор.
Вы можете использовать для сбора различной информации о каком-либо php-коде, например, о всех определенных классах, методах, переменных, генерации документации и подобных задачах.
Я работаю над устаревшим приложением Symfony 1.2, и я использую токенизатор для получения всех вызовов sfConfig::get()
и sfConfig::set()
.
Итак, в основном я документирую все параметры конфигурации своего приложения.