Quelles sont les utilisations pratiques de PHP tokenizer?

que sont des exemples d'utilisation pratique et quotidienne de Tokenizer PHP ?

quelqu'un a utilisé ça?

21
demandé sur Pekka 웃 2011-04-20 13:08:36

8 réponses

j'utilise PHP_CodeSniffer pour le style de codage de la conformité, qui est construit sur le tokeniser. En outre, certains cadres (par exemple Symfony 2) utilisent le tokeniser pour générer des fichiers de cache ou des fichiers de classe intermédiaire de code PHP. Il est également possible d'utiliser le tokeniser pour construire un formatteur de code source ou un surligneur de syntaxe.

essentiellement, partout où vous utilisez du code PHP comme données, vous pouvez utiliser le tokeniser. Il est beaucoup plus fiable que d'essayer de parser le code PHP avec les expressions régulières, ou d'autres fonctions de traitement de chaîne.

16
répondu Sander Marechal 2011-04-20 09:10:56

personnellement , je l'ai déjà utilisé pour construire un PHP sandbox , qui tente de créer un environnement plus sûr pour l'exécution des scripts PHP.

de plus j'ai fait des charges d'expériences pour préprocéder à PHP, par exemple j'ai un émulateur PHP 5.3 (incomplet) pour PHP 5.2 appelé prephp .

et de nombreux autres outils similaires, comme les analyseurs de code source (pour security auditing , code de style analyse, ...) utiliser le générateur de jetons.

mais même pour les petites choses le Tokenizer peut être pratique. Pas seulement des analyseurs de code à grande échelle. Par exemple, si vous acceptez un tableau PHP et que vous voulez vérifier qu'il n'est pas malveillant, vous pouvez le faire en utilisant le Tokenizer .

PS: actuellement je passe à l'analyse réelle du PHP, au lieu de simplement le tokeniser, en utilisant un PHP parser écrit en PHP j'ai récemment publié (il fonctionne, mais n'est pas encore pratiquement utilisable).

14
répondu NikiC 2017-05-23 12:16:59

question intéressante.

Je n'ai pas encore utilisé le tokenizer dans aucun projet de production, mais il ya plusieurs questions sur le débordement de la pile à laquelle le tokenizer est la (ou au moins, un) réponse correcte.

11
répondu Pekka 웃 2017-05-23 12:09:11

une utilisation assez basique est pour la mise en évidence de syntaxe.

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>";
    }
}

les numéros de token sont généralement convertis en de plus beaux noms de classe CSS bien sûr, mais vous pourriez juste craft une feuille de style avec seulement .T_COMMENT,.T_ARRAY,.T_ELSEIF,.T_FUNCTION ... classe.

3
répondu mario 2011-04-20 09:32:08

j'ai utilisé tokenizer pour trouver le numéro de complexité cyclomatique et d'autres mesures de code d'un rappel:

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
répondu Alix Axel 2013-06-08 12:04:21

un ami à moi a écrit Überloader (un Autoloader de force brute pour PHP5.) qui utilise cette même technique quand il indexe des fichiers de classe. La _check_file() méthode de celui-ci sera d'un intérêt particulier pour vous.

Überloader est conçu pour les projets patrimoniaux qui n'ont pas planifié ou réfléchi à leurs conventions de nommage de classe ou à leurs structures de fichiers.

j'utilise la classe tous les jours dans legacy des projets que je répare ou rénove.

2
répondu Treffynnon 2011-04-20 09:13:04

à Partir d'un commentaire dans le manuel PHP :

les fonctions tokenizer sont tout à fait puissant. Par exemple, vous pouvez récupérer toutes les méthodes dans un Classe utilisant un algorithme comme:

pour chaque token: si le token est T_FUNCTION puis lancer buffer si buffer est lancé puis ajouter une chaîne à la buffer si token est (stop buffer

et la grande chose est que la classe les méthodes le cas, donc c'est une bonne façon de contourner les limites des méthodes get_class_methodes retour des noms de méthode en minuscules. Également car l'utilisation d'un algorithme similaire vous peut lire les arguments d'une fonction vous pouvez mettre en œuvre des Réflexions comme fonctionnalité dans PHP4.

Enfin, vous pouvez l'utiliser comme un simple méthode d'extraction de l'Javadoc d'un fichier de classe pour générer la documentation. L'util / MethodTable.classe php en AMFPHP (http://www.amfphp.org) utilisations les fonctions de tokenizer pour créer un table de méthode avec tous les arguments, une description, type de retour, etc. et à partir de ce tableau, il peut générer ActionScript qui correspond au PHP, mais il pourrait aussi être adapté à générer JavaScript, documentation fichiers, ou fondamentalement tout ce que vous mettez votre esprit d'. Je peux aussi voir que ceci pourrait être la base d'une classe - > WSDL générateur de fichier.

Vous pouvez utiliser pour rassembler diverses informations sur un code php, comme par exemple toutes les classes définies, les méthodes, les variables, la production de documentation et les tâches similaires.

2
répondu KillerX 2011-04-20 09:16:42

je travaille sur une application Symfony 1.2 legacy et j'utilise le tokenizer pour recevoir tous les appels de sfConfig::get() et sfConfig::set() .

donc en gros je documente tous les paramètres de configuration de mon application.

0
répondu B4rb4ross4 2016-12-21 21:46:18