Question

Je souhaite créer une fonction qui reçoit un seul argument contenant le chemin d'accès à un fichier PHP, puis analyse le fichier donné et renvoie un résultat semblable à celui-ci:

class NameOfTheClass
   function Method1($arg1, $arg2, $arg2)
   private function Method2($arg1, $arg2, $arg2)
   public function Method2($arg1, $arg2, $arg2)

abstract class AnotherClass
   function Method1($arg1, $arg2, $arg2)
   private function Method2($arg1, $arg2, $arg2)
   public function Method2($arg1, $arg2, $arg2)

function SomeFunction($arg1, $arg2, $arg3)

Cette fonction doit renvoyer toutes les classes, méthodes et fonctions présentes dans le fichier donné avec tous les identificateurs définis (abstraits, publics, privés, protégés, statiques, étendues, interfaces, ...).

Ma première idée était d'utiliser des expressions régulières pour le faire, mais elles se comportent mal avec les commentaires, par exemple: / * cette fonction retourne (max (salaire)) * / et devient assez complexe si je veux bien supporter les portées.

Une autre solution possible consistait à utiliser les fonctions PHP suivantes:

get_declared_classes
get_declared_interfaces
get_defined_functions
get_class_methods

Cependant, ces fonctions ne me permettent pas de voir le fichier dans lequel les classes / méthodes / fonctions sont définies. Ce n'est donc pas très utile.

Je pense que l'extension Tokenizer est la solution à mon problème, mais je n'ai jamais utilisé cette extension auparavant.

Était-ce utile?

La solution

Si vous utilisez PHP 5, votre API Reflection est votre outil.

Exemple:

$class = new ReflectionClass("NameOfTheClass");
$methods = $class->getMethods();
foreach($methods as $m) {
    print $m->name;
    $m->isPrivate() ? print "Private" : print "";
    $m->isPublic() ? print "Public" : print "";
    $params = $m->getParameters();
    foreach($params as $p) {
        print $p->getName();
        }
}

Autres conseils

Je suggère la procédure suivante:

  1. stocke la sortie actuelle de get_declared_classes , get_declared_interfaces et get_defined_functions (si vous avez vraiment besoin de les prendre en charge)
  2. inclure le fichier
  3. comparez get_declared_classes , get_declared_interfaces et g et_defined_functions avec ceux que vous avez stockés pour voir les nouveautés
  4. utilisez la réflexion pour les analyser
  5. allez à l'étape 2 pour le fichier suivant

Comme vous l’avez découvert vous-même, les regex ne sont vraiment pas le bon outil pour ce travail, ici ^^

Et, comme vous l'avez dit, les fonctions intégrées que vous avez proposées ne sont pas non plus utiles. La seule chose qui pourrait vous être utile est qu'elles vous permettent de savoir quelle classe existe ... Mais elles renverront également des classes intégrées. : - (

Utiliser l'extension Tokenizer semble un peu excessif / difficile pour moi; En fait, je n’irais probablement pas de cette façon: trop "à bas niveau", je suppose.


Au lieu de cela, je jetterais un coup d'œil à API Reflection de PHP: elle existe exactement désosser des classes, des interfaces, des fonctions, ...

Donc, je suppose que cela conviendrait très bien à ce que vous essayez de faire.


Edit: voici un exemple rapide:

Tout d'abord, essayons de faire une réflexion sur une classe:

include dirname(__FILE__) . '/temp-2.php';
$rC = new ReflectionClass('MyFirstClass');

Vous pouvez maintenant savoir dans quel fichier il a été déclaré et quelles méthodes y figurent:

var_dump($rC->getFileName());
var_dump($rC->getMethods());

Ce qui vous donnera:

string '/home/squale/developpement/tests/temp/temp-2.php' (length=48)

array
  0 => &
    object(ReflectionMethod)[2]
      public 'name' => string '__construct' (length=11)
      public 'class' => string 'MyFirstClass' (length=12)
  1 => &
    object(ReflectionMethod)[3]
      public 'name' => string 'glop' (length=4)
      public 'class' => string 'MyFirstClass' (length=12)


Et maintenant, pour avoir des informations sur chaque méthode:

foreach ($rC->getMethods() as $rM) {
    var_dump($rM, $rM->getParameters());
    echo '-----';
}

Vous obtiendrez:

object(ReflectionMethod)[3]
  public 'name' => string '__construct' (length=11)
  public 'class' => string 'MyFirstClass' (length=12)

array
  0 => &
    object(ReflectionParameter)[4]
      public 'name' => string 'arg1' (length=4)
  1 => &
    object(ReflectionParameter)[5]
      public 'name' => string 'arg2' (length=4)

-----

object(ReflectionMethod)[2]
  public 'name' => string 'glop' (length=4)
  public 'class' => string 'MyFirstClass' (length=12)

array
  0 => &
    object(ReflectionParameter)[5]
      public 'name' => string 'a' (length=1)


À partir de là, vous devriez pouvoir creuser un peu plus; et arriver à ce que vous avez demandé en premier ;-)


En résumé, il y a une chose que je ne sais pas: "" pour savoir quelles classes / méthodes sont déclarées dans un fichier donné ". : - (

Si quelqu'un a une idée, ce sera la bienvenue!

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top