switch - ¿Cuáles son algunos usos prácticos de PHP tokenizer?
tokenizer switch (8)
¿Cuáles son los ejemplos prácticos y de uso diario de PHP Tokenizer ?
¿Alguien ha usado esto?
De un comentario en el manual de PHP :
Las funciones de tokenizer son bastante potentes. Por ejemplo, puede recuperar todos los métodos en una clase dada usando un algoritmo como:
para cada token: si el token es T_FUNCTION, entonces inicie el búfer si se inicia el búfer, luego agregue la cadena actual al búfer si el token es (detener el búfer
Y lo mejor es que los métodos de clase tendrán el caso correcto, por lo que es una buena manera de sortear las limitaciones con get_class_methods que devuelven nombres de método en minúscula. Además, dado que con un algoritmo similar puede leer los argumentos de una función, puede implementar la funcionalidad similar a Reflections en PHP4.
Finalmente, puede usarlo como un método más simple para extraer Javadoc de un archivo de clase para generar documentación. La clase util / MethodTable.php en AMFPHP (http://www.amfphp.org) usa las funciones de tokenizer para crear una tabla de métodos con todos los argumentos, una descripción, tipo de retorno, etc. y desde esa tabla de métodos puede genere ActionScript que coincida con el PHP, pero también se puede adaptar para generar JavaScript, archivos de documentación o básicamente cualquier cosa que se proponga. También puedo ver que esto podría ser la base para un generador de archivos WSDL de clase ->.
Puede utilizar para recopilar diversas informaciones sobre algún código de PHP, como por ejemplo, todas las clases definidas, métodos, variables, generación de documentación y tareas similares.
Estoy trabajando en una aplicación heredada de Symfony 1.2 y uso el tokenizador para obtener todas las llamadas de sfConfig::get()
y sfConfig::set()
.
Básicamente documento todos los parámetros de configuración de mi aplicación.
He utilizado tokenizer para encontrar el número de complejidad cyclomatic y algunas otras métricas de código de una devolución de llamada:
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);
}
}
}
Interesante pregunta.
No he usado el tokenizer en ningún proyecto de producción todavía, pero hay varias preguntas sobre para las cuales el tokenizer es la respuesta correcta (o al menos una).
Analizando automáticamente PHP para separar el código PHP del HTML , extrayendo comentarios del código PHP, por ejemplo, para compilar documentación ( phpDocumentor funciona de esta manera)
La clase existe en un archivo externo : analiza el código y observa si una clase existe dentro de un archivo (por ejemplo, para un sistema de administración de complementos)
Escriba de forma permanente las variables en un archivo php con php , modificando los archivos de código fuente de PHP, por ejemplo, para completar las variables de configuración. Usar el tokenizador sería el primer paso para hacer esto en un nivel de analizador.
¿Cómo crear una lista de todas las funciones PHP incorporadas que utiliza un proyecto? - Analizar qué funciones se utilizan en un proyecto PHP.
Personalmente ya lo he usado para construir un recinto de seguridad PHP , que intenta crear un entorno más seguro para ejecutar scripts PHP.
Además, realicé muchos experimentos para preprocesar PHP, por ejemplo, tengo un emulador de PHP 5.3 (incompleto) para PHP 5.2 llamado prephp .
Y muchas otras herramientas similares, como los analizadores de código fuente (para auditorías de seguridad , análisis de estilo de código , ...) también usan el Tokenizer.
Pero incluso para cosas más pequeñas, el Tokenizer puede ser útil. No solo analizadores de código a gran escala. Por ejemplo, si está aceptando una matriz de PHP y quiere comprobar que no es malicioso, puede hacerlo utilizando el Tokenizer .
PD: Actualmente estoy cambiando para analizar el PHP en realidad, en lugar de solo simbolizarlo, usando un analizador PHP escrito en PHP que publiqué recientemente (funciona, pero aún no es prácticamente utilizable).
Un amigo mío ha escrito Überloader (Un autoloader de fuerza bruta para PHP5.) Que utiliza esta misma técnica cuando indexa los archivos de clase. El método _check_file()
de él será de particular interés para usted.
Überloader está diseñado para proyectos heredados que no han planificado o pensado en sus convenciones de nomenclatura de clase o estructuras de archivos.
Uso la clase todos los días en proyectos heredados que estoy arreglando o renovando.
Un uso bastante básico es para el resaltado de sintaxis.
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>";
}
}
Los números de token generalmente se convierten en nombres de clase CSS más agradables, por supuesto, pero puede crear una hoja de estilo con solo las clases .T_COMMENT, .T_ARRAY, .T_ELSEIF, .T_FUNCTION ...
Uso PHP_CodeSniffer para el cumplimiento del estilo de codificación, que se basa en el tokeniser. Además, algunos marcos (por ejemplo, Symfony 2) utilizan el tokeniser para generar archivos de caché o archivos de clase intermedia de código PHP. También es posible utilizar el tokeniser para crear un formateador de código fuente o un resaltador de sintaxis.
Básicamente, en cualquier lugar que utilice el código PHP como datos, puede usar el tokeniser. Es mucho más confiable que tratar de analizar código PHP con expresiones regulares u otras funciones de procesamiento de cadenas.