2009-09-12 19 views
5

Voglio creare una funzione che riceve un singolo argomento che contiene il percorso di un file PHP e quindi analizza il file data e restituisce qualcosa di simile:Classi l'analisi, Funzioni e argomenti in PHP

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) 

Questo la funzione dovrebbe restituire tutte le classi, i metodi e le funzioni esistenti nel file specificato con tutti gli identificatori definiti (astratti, pubblici, privati, protetti, statici, estesi, interfacce, ...).

Il mio primo pensiero era usare le espressioni regolari per farlo, ma questi si comportano piuttosto male con i commenti, ovvero:/* questa funzione restituisce (max (salario)) */e diventa piuttosto complessa se voglio supportare correttamente gli ambiti .

Un'altra possibile soluzione era quella di utilizzare le seguenti funzioni PHP built-in:

get_declared_classes 
get_declared_interfaces 
get_defined_functions 
get_class_methods 

Tuttavia queste funzioni non mi permettono di vedere il file in cui sono definite le classi/metodi/funzioni, quindi non è molto utile.

Credo che l'estensione Tokenizer sia la soluzione per il mio problema, tuttavia non ho mai usato questa estensione prima.

risposta

8

Se si utilizza PHP 5, lo strumento Reflection API è lo strumento.

Esempio:

$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(); 
     } 
} 
+0

Questo praticamente copre tutte le mie esigenze, ancora una domanda difficile: per quanto riguarda le funzioni (non i metodi)? –

+1

È possibile utilizzare get_defined_functions() per ottenere tutte le funzioni definite dall'utente, oltre alla classe ReflectionFunction (http://www.php.net/manual/en/class.reflectionfunction.php) per analizzarle. –

1

Come hai scoperto te stesso, espressione regolare non sono abbastanza lo strumento giusto per il lavoro, qui ^^

E, come hai detto tu, il built-in funzioni proposte non sono che utile sia - unica cosa che potrebbe essere utile è che ti permettono di sapere quale classe esiste ... Ma restituiranno anche le classi incorporate :-(

L'utilizzo dell'estensione Tokenizer mi sembra un po 'eccessivo/difficile per me, probabilmente non andrei in questo modo, in realtà: troppo "di basso livello", suppongo.


Invece, io wou Diamo un'occhiata a PHP Reflection API: esiste esattamente per decodificare classi, interfacce, funzioni, ...

Quindi, suppongo che sarebbe abbastanza adatto per quello che stai cercando di fare.


Edit: ecco un breve esempio:

In primo luogo, cerchiamo di fare la riflessione su una classe:

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

È ora possibile scoprire in quale file è stato dichiarato, e che metodi sono in essa:

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

che vi consentiranno di:

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) 


E ora, per avere informazioni su ciascun metodo:

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

Otterrete:

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) 


Da lì, si dovrebbe essere in grado di scavare un po 'più ; e si arriva a quello che prima chiesto ;-)


Come sidenote: c'è una cosa che non ho idea circa è: "come trovare quali classi/metodi sono dichiarati in un dato file": - (

Se qualcuno ha un'idea, sarà il benvenuto!

+0

Grazie, sembra l'API Reflection è un candidato forte per risolvere il mio problema. Sai dove posso vedere un esempio di un'implementazione simile al mio problema? Inoltre, l'API di Reflection mi consente di distinguere in quali file sono i metodi/le classi trovati? –

+0

Ciao! Ho modificato la mia risposta per fornire un esempio :-) Spero che questo aiuti! –

0

non posso aiutare con la vostra domanda particolare, come non ho mai usato Tokenizer neanche.

non accennate per cosa stai usando questo, ma qualcosa di simile a phpDoc fa quello che vuoi Ed?

+0

Quello di cui ho bisogno è fondamentalmente una versione ridotta di phpDoc senza il problema di phpDoc, in pratica voglio solo dare un'occhiata a tutti i metodi e gli argomenti disponibili per ogni file dato - che sarebbe più che sufficiente per me. –

1

suggerisco la seguente procedura:

  1. negozio l'uscita in corrente di get_declared_classes, get_declared_interfaces e get_defined_functions (se si ha realmente bisogno di sostenerli)
  2. includere il file
  3. confrontare get_declared_classes, get_declared_interfaces e g et_defined_functions con quelli che memorizzati per vedere cosa c'è di nuovo
  4. uso riflessione per analizzarli
  5. goto passaggio 2 per il file successivo