Каковы практические применения токенайзера PHP? - PullRequest
22 голосов
/ 20 апреля 2011

Каковы практические и повседневные примеры использования PHP Tokenizer ?

Кто-нибудь использовал это?

Ответы [ 8 ]

17 голосов
/ 20 апреля 2011

Я использую PHP_CodeSniffer для соответствия стилю кодирования, который построен на токенизаторе.Кроме того, некоторые фреймворки (например, Symfony 2) используют токенизатор для генерации файлов кэша или файлов промежуточного класса кода PHP.Также можно использовать токенизер для создания средства форматирования исходного кода или подсветки синтаксиса.

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

16 голосов
/ 20 апреля 2011

Лично я уже использовал его для создания песочницы PHP , которая пытается создать более безопасную среду для выполнения сценариев PHP.

Кроме того, я провел множество экспериментов по предварительной обработке PHP, например, У меня есть (не полный) эмулятор PHP 5.3 для PHP 5.2, который называется prephp .

И многие другие подобные инструменты, такие как анализаторы исходного кода (для аудит безопасности , стиль кода анализ, ...) также используют Tokenizer.

Но даже для небольших вещей токенизатор может быть полезен. Не только крупномасштабные анализаторы кода. Например, если вы принимаете массив PHP и хотите убедиться, что он не является вредоносным, вы можете сделать это, используя Tokenizer .

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

11 голосов
/ 20 апреля 2011

Интересный вопрос.

Я еще не использовал токенизатор в каких-либо производственных проектах, но есть несколько вопросов по переполнению стека, на которые токенизатор является (или, по крайней мере, одним) правильным ответом.

3 голосов
/ 08 июня 2013

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

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);
        }
    }
}
3 голосов
/ 20 апреля 2011

Довольно простое использование - для подсветки синтаксиса.

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 ... классы.

2 голосов
/ 20 апреля 2011

Из комментария в руководстве по PHP :

Функции токенизатора довольно мощный. Например, вы можете извлечь все методы в данном класс с использованием алгоритма вроде:

для каждого токена: если токен T_FUNCTION затем запустить буфер, если буфер запущен затем добавьте текущую строку в буфер, если токен (стоп-буфер

И самое замечательное, что класс методы будут иметь правильный случай, поэтому это хороший способ обойти ограничения с get_class_methods возвращение строчных имен методов Также так как используя подобный алгоритм вы может прочитать аргументы функции Вы можете реализовать Reflections-как функциональность в PHP4.

Наконец, вы можете использовать его как более простой метод извлечения Javadoc из файл класса для генерации документации. Класс util / MethodTable.php в AMFPHP (http://www.amfphp.org) использует функции токенизатора для создания таблица методов со всеми аргументы, описание, тип возвращаемого значения, и т.д., и из этой таблицы методов это может создать ActionScript, соответствующий PHP, но он также может быть приспособлен к генерировать JavaScript, документация файлы, или в основном все, что вы положили ваш разум Я также вижу, что это может быть основой для класса -> WSDL генератор файлов.

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

2 голосов
/ 20 апреля 2011

Мой друг написал Überloader (автозагрузчик с перебором для PHP5.), Который использует эту самую технику при индексации файлов классов.Метод _check_file() от него будет особенно интересен для вас.

Überloader предназначен для устаревших проектов, которые не планировали или не думали об их соглашениях об именах классов или структурах файлов.

Я использую этот класс каждый день в старых проектах, которые я ремонтирую или ремонтирую.

0 голосов
/ 21 декабря 2016

Я работаю над унаследованным приложением Symfony 1.2 и использую токенизатор для получения всех вызовов sfConfig::get() и sfConfig::set().

Таким образом, в основном я документирую все параметры конфигурации моего приложения.

...