Start · Sprachen · PHP · Referenz · token_get_all

token_get_all

Funktion

Zerlegt einen PHP-Quelltext-String in ein Array von PHP-Token (Lexer-Token).

seit PHP 4.2.0 Kategorie: misc

Signatur

token_get_all(string $code, int $flags = 0): array

Beschreibung

token_get_all() ist der Einstiegspunkt in PHPs integrierten Tokenizer. Die Funktion übergibt den Quelltext an den Zend-Lexer und liefert alle erkannten Token als Array zurück. Jeder Eintrag ist entweder ein dreidimensionales Array [TOKEN_ID, Wert, Zeilennummer] für bekannte Token oder ein einzelnes Zeichen-String für Interpunktions-/Operator-Zeichen, die keinen eigenen Token-Typ besitzen.

Typische Anwendungsfälle sind statische Code-Analyse, Linting, Refactoring-Werkzeuge, Dokumentationsgeneratoren oder Taint-Analysen. Statt eigene Regex-Parser zu schreiben, kann man so auf den selben Lexer zurückgreifen, den PHP selbst verwendet.

Mit dem Flag TOKEN_PARSE (verfügbar ab PHP 7.0) wird sichergestellt, dass token_get_all() die gleiche Tokenisierung wie der eigentliche Parse-Schritt durchführt; insbesondere bei Schlüsselwörtern im Namespace-Kontext kann dies zu abweichenden Token-IDs führen.

Token-IDs können mit token_name() in lesbare Namen wie T_ECHO, T_VARIABLE usw. umgewandelt werden. Ab PHP 8.0 steht alternativ die objektorientierte PhpToken-Klasse zur Verfügung, die eine ergonomischere API bietet.

Parameter

Name Typ Default Beschreibung
$code Pflicht string Vollständiger PHP-Quelltext inklusive öffnendem <?php-Tag. Ohne gültiges PHP-Tag wird der gesamte Text als T_INLINE_HTML-Token behandelt.
$flags int 0 Optionale Flags. Aktuell wird nur TOKEN_PARSE unterstützt, das den Tokenizer in den Parse-Modus versetzt und etwa Schlüsselwörter in Namespaces korrekt klassifiziert.

Rückgabewert

Typ
array
Beschreibung
Array von Token. Jedes Element ist entweder ein array der Form [int $id, string $text, int $line] (für bekannte Token) oder ein einzelner string (für einzelne Zeichen wie ;, {, } usw.).

Beispiele

Alle Token eines kleinen PHP-Snippets ausgeben

<?php
$code = '<?php echo "Hallo Welt"; ?>';

$tokens = token_get_all($code);

foreach ($tokens as $token) {
    if (is_array($token)) {
        [$id, $text, $line] = $token;
        printf("Zeile %d: %-20s => %s\n", $line, token_name($id), var_export($text, true));
    } else {
        printf("         %-20s => %s\n", 'LITERAL', var_export($token, true));
    }
}
Zeile 1: T_OPEN_TAG => '<?php ' Zeile 1: T_ECHO => 'echo' Zeile 1: T_WHITESPACE => ' ' Zeile 1: T_CONSTANT_ENCAPSED_STRING => '"Hallo Welt"' LITERAL => ';' Zeile 1: T_WHITESPACE => ' ' Zeile 1: T_CLOSE_TAG => '?>'

Alle Variablen-Namen in einem Quelltext extrahieren

<?php
$source = <<<'PHP'
<?php
$name = 'Alice';
$age  = 30;
echo $name . ' ist ' . $age . ' Jahre alt.';
PHP;

$tokens = token_get_all($source);
$variables = [];

foreach ($tokens as $token) {
    if (is_array($token) && $token[0] === T_VARIABLE) {
        $variables[] = $token[1];
    }
}

$variables = array_unique($variables);
echo implode(', ', $variables);
$name, $age

TOKEN_PARSE-Flag für korrekte Namespace-Schlüsselwort-Erkennung

<?php
// Ohne FLAG wird 'list' als T_LIST erkannt, mit FLAG ggf. anders im Namespace-Kontext
$code = '<?php namespace App\\List;';

$tokensNormal = token_get_all($code);
$tokensParse  = token_get_all($code, TOKEN_PARSE);

echo 'Ohne FLAG:' . PHP_EOL;
foreach ($tokensNormal as $t) {
    echo is_array($t) ? token_name($t[0]) . ' ' : $t . ' ';
}

echo PHP_EOL . 'Mit TOKEN_PARSE:' . PHP_EOL;
foreach ($tokensParse as $t) {
    echo is_array($t) ? token_name($t[0]) . ' ' : $t . ' ';
}

// Wichtig · Fallstricke

Sicherheit: token_get_all() führt den Code nicht aus — es findet lediglich eine lexikalische Analyse statt. Es besteht daher keine Gefahr durch Code-Injection über den $code-Parameter selbst. Dennoch sollte Benutzereingaben, die als Quelltext analysiert werden, grundsätzlich misstraut werden.

Encoding: Die Funktion erwartet UTF-8-kodierten oder zumindest Latin-1-kompatiblen Code. Mehrbyte-Strings können die Zeilennummern-Berechnung beeinflussen.

Empfehlung ab PHP 8.0: Für neue Projekte empfiehlt sich die objektorientierte PhpToken-Klasse, die eine homogenere Ausgabe (ausschließlich Objekte statt gemischtes Array/String) und eine komfortablere API bietet.

Performance: Bei sehr großen Dateien (z. B. tausende LOC) kann token_get_all() nennenswert Speicher verbrauchen. Für hochperformante Analyse empfehlen sich externe Tools wie nikic/PHP-Parser.

Siehe auch