Page 1 sur 1

Parser un fichier pour récupérer les classes, méthodes...

Posté : 10 sept. 2014, 14:49
par Kal747
Bonjour à tous,

Je fais souvent de la reverse-engineering dans le cadre de mon boulot.
J'essaye de me faire un petit script PHP qui parse un projet pour récupérer toutes les classes avec leurs attributs et méthode.

Voici l'actuel :
define('ROOT', dirname(__FILE__) . '/');
define('PROJECT_PATH', ROOT . 'project/'); // Changer ici le chemin du projet

// Récupération des fichiers PHP
$files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator(PROJECT_PATH), RecursiveIteratorIterator::SELF_FIRST);
$targets = array();
foreach ($files as $name => $object) if (preg_match('/\.(php|php5)$/i', $name)) {
	$targets[] = $object;
}

// On ouvre chaque fichier pour récupérer les classes
$classes = array();
foreach ($targets as $file) {
	$content = file_get_contents($file->getPathName());
	$content = preg_replace('/[ ]{2,}/', ' ', $content);
	$matches = preg_match_all( '/(abstract ){0,1}class ([a-z0-9\_]+) ((extends|implements) ([a-z0-9\_]+))*/im', $content, $result, PREG_SET_ORDER);
	if ($matches) foreach ($result as $match) {
		$def = $match[0];
		$isAbstract = !empty($match[1]);
		$className = $match[2];
		$action = !empty($match[4]) ? $match[4] : null;
		$father = !empty($match[5]) ? $match[5] : null;
		$classes[$className] = array(
			'def' => $def,
			'isAbstract' => $isAbstract,
			'action' => $action,
			'father' => $father,
		);
	}
}
ksort($classes);

echo '<pre>' . print_r($classes, true) . '</pre>';
Qui me donne en retour un truc du genre :

Code : Tout sélectionner

Array ( [BaseCtrl] => Array ( [def] => abstract class BaseCtrl [isAbstract] => 1 [action] => [father] => ) [IndexCtrl] => Array ( [def] => class IndexCtrl extends BaseCtrl [isAbstract] => [action] => extends [father] => BaseCtrl ) [BaseDB] => Array ( [def] => abstract class BaseDB [isAbstract] => 1 [action] => [father] => ) [Mails] => Array ( [def] => class Mails [isAbstract] => [action] => [father] => ) [Objects] => Array ( [def] => Class Objects [isAbstract] => [action] => [father] => ) [PHPMailer] => Array ( [def] => class PHPMailer [isAbstract] => [action] => [father] => ) [SSHException] => Array ( [def] => class SSHException extends Exception [isAbstract] => [action] => extends [father] => Exception ) [SelectHtml] => Array ( [def] => class SelectHtml [isAbstract] => [action] => [father] => ) [Tools] => Array ( [def] => class Tools [isAbstract] => [action] => [father] => ) [User] => Array ( [def] => class User [isAbstract] => [action] => [father] => ) [phpmailerException] => Array ( [def] => class phpmailerException extends Exception [isAbstract] => [action] => extends [father] => Exception ) )
J'aimerais, à cet endrois du code :

Code : Tout sélectionner

$classes[$className] = array( 'def' => $def, 'isAbstract' => $isAbstract, 'action' => $action, 'father' => $father, );
Récupérer aussi la liste des attributs et des méthodes. Je pense qu'il faut que l'améliore la regex '/(abstract ){0,1}class ([a-z0-9\_]+) ((extends|implements) ([a-z0-9\_]+))*/im' pour récupérer derrière le code entre les { } mais comment ne récupérer que les { } de la classe en cours ?
Quelqu'un à une idée pour récupérer un tableau contenant la liste des méthodes et un autre la liste des attributs ?

Sachant qu'un fichier peut contenir plusieurs classes, peut être mélangé avec tout autre code PHP.

Merci par avance pour votre aide.

Bonne journée

EDIT : Je pense que c'est un truc de ce genre : http://php.net/manual/fr/regexp.reference.recursive.php mais je ne connais pas (je ne suis pas sûr). C'est un problème style 'automate à pile.

Re: Parser un fichier pour récupérer les classes, méthodes..

Posté : 10 sept. 2014, 22:07
par moogli
salut,

autre piste l'instropection (reflection).
a partir du moment ou tu as les noms classe (ce qui est le cas avec ton code) tu auras le reste ;)

juste pour info, histoire de rendre ton code plus lisble tu peux te baser sur les recommandation PSR-1 et PSR-2. je leur préfère les conventions java au niveau emplacements des accolades mais cela reste mon avis :)

@+