2009-06-05 24 views
109

Ho alcune CONST definite su alcune classi e voglio ottenerne una lista. Per esempio:Posso ottenere i CONST definiti su una classe PHP?

class Profile { 
    const LABEL_FIRST_NAME = "First Name"; 
    const LABEL_LAST_NAME = "Last Name"; 
    const LABEL_COMPANY_NAME = "Company"; 
} 

Esiste un modo per ottenere un elenco dei CONST del definita sulla classe Profile? Per quanto posso dire, l'opzione più vicina (get_defined_constants()) non farà il trucco.

Quello che ho veramente bisogno è una lista dei nomi costanti - qualcosa di simile:

array('LABEL_FIRST_NAME', 
    'LABEL_LAST_NAME', 
    'LABEL_COMPANY_NAME') 

Oppure:

array('Profile::LABEL_FIRST_NAME', 
    'Profile::LABEL_LAST_NAME', 
    'Profile::LABEL_COMPANY_NAME') 

O anche:

array('Profile::LABEL_FIRST_NAME'=>'First Name', 
    'Profile::LABEL_LAST_NAME'=>'Last Name', 
    'Profile::LABEL_COMPANY_NAME'=>'Company') 
+0

utilizzando la riflessione, e un ReflectionClass su Cl, è possibile utilizzare le funzioni getConstants http://nz.php.net/manual /en/class.reflectionclass.php –

+0

[Il riflesso sarà il tuo salvatore] (http://se2.php.net/manual/en/reflectionclass.getconstants.php). –

+0

Puoi farlo usando [reflection] (http://nz.php.net/oop5.reflection). Cerca "Stampa costanti di classe" in quella pagina per vedere un esempio. – n3rd

risposta

191

È possibile utilizzare per questo. Nota che se lo fai molto potresti voler guardare il risultato nella cache.

<?php 
class Profile { 
    const LABEL_FIRST_NAME = "First Name"; 
    const LABEL_LAST_NAME = "Last Name"; 
    const LABEL_COMPANY_NAME = "Company"; 
} 


$refl = new ReflectionClass('Profile'); 
print_r($refl->getConstants()); 

uscita:

Array 
(
    ['LABEL_FIRST_NAME'] => First Name 
    ['LABEL_LAST_NAME'] => Last Name 
    ['LABEL_COMPANY_NAME'] => Company 
) 
+4

Due NB secondari: primo, in 5.3, 'Profile' può essere usato come argomento per il costruttore del reflector, senza virgolette (un semplice nome di classe); in secondo luogo, per essere completamente chiari, le chiavi dell'array risultante sono stringhe, non costanti, in quanto la formattazione qui può essere presa per suggerire. (Vale la pena menzionare solo come il fn è [non documentato] (http://www.php.net/manual/en/reflectionclass.getconstants.php).) –

+11

@ Benji XVI In 5.3 se hai avvisi attivati, hai vinto ' essere in grado di usare 'Profilo' senza le virgolette, in quanto mostrerà il seguente errore: Avviso: Uso di profilo costante indefinito - assunto 'Profilo'. Quindi suggerisco di mantenere le virgolette "Profilo" – toneplex

+9

È bene definire la logica relativa alle costanti all'interno della classe, quindi non è necessario l'argomento del costruttore hardcode, ma usare '__CLASS__ '. –

4

Sì, è possibile utilizzare reflection. Guarda l'output di

<? 
Reflection::export(new ReflectionClass('YourClass')); 
?> 

Questo dovrebbe darti l'idea di cosa vedrai.

12

In PHP5 è possibile utilizzare Riflessione: (manual reference)

$class = new ReflectionClass('Profile'); 
$consts = $class->getConstants(); 
14

Usa token_get_all(). Vale a dire:

<?php 
header('Content-Type: text/plain'); 

$file = file_get_contents('Profile.php'); 
$tokens = token_get_all($file); 

$const = false; 
$name = ''; 
$constants = array(); 
foreach ($tokens as $token) { 
    if (is_array($token)) { 
     if ($token[0] != T_WHITESPACE) { 
      if ($token[0] == T_CONST && $token[1] == 'const') { 
       $const = true; 
       $name = ''; 
      } else if ($token[0] == T_STRING && $const) { 
       $const = false; 
       $name = $token[1]; 
      } else if ($token[0] == T_CONSTANT_ENCAPSED_STRING && $name) { 
       $constants[$name] = $token[1]; 
       $name = ''; 
      } 
     } 
    } else if ($token != '=') { 
     $const = false; 
     $name = ''; 
    } 
} 

foreach ($constants as $constant => $value) { 
    echo "$constant = $value\n"; 
} 
?> 

uscita:

LABEL_FIRST_NAME = "First Name" 
LABEL_LAST_NAME = "Last Name" 
LABEL_COMPANY_NAME = "Company" 
+0

token_get_all è ottimo –

+1

+1, anche se direi che questo è un ottimo momento per usare Reflection come menzionato da altri poster, è anche importante capire il funzionamento "sotto il cofano" ed essere in grado di fare a meno di loro o replicarli se necessario. Bello spettacolo. – Dereleased

+1

Se non vuoi che la tua classe sia caricata in memoria, token_get_all è un'alternativa fantastica. È MOLTO più veloce di Reflection e non ingombra la memoria del processo se è necessario farlo con molte classi. – Harold

7

Utilizzando ReflectionClass e getConstants() dà esattamente quello che vuoi:

<?php 
class Cl { 
    const AAA = 1; 
    const BBB = 2; 
} 
$r = new ReflectionClass('Cl'); 
print_r($r->getConstants()); 

uscita:

Array 
(
    [AAA] => 1 
    [BBB] => 2 
) 
12

Per i commenti docs PHP, se tu sei in grado di utilizzare il ReflectionClass (PHP 5):

function GetClassConstants($sClassName) { 
    $oClass = new ReflectionClass($sClassName); 
    return $oClass->getConstants(); 
} 

Source is here.

2

Perché non metterli in una variabile di classe come array per cominciare? Rende più facile il looping.

private $_data = array("production"=>0 ...); 
+3

in array non vedrai suggerimenti sul completamento del codice ... –

+1

Perché gli array non sono costanti? Se implementi qualcosa che dovrebbe essere una costante come variabile, rischi di essere inavvertitamente modificato o disinserito. In altre parole, non si può dipendere dal rimanere costanti. – GordonM

18

This

$reflector = new ReflectionClass('Status'); 
var_dump($reflector->getConstants()); 
+1

+1 Questo sarebbe perché non riesco a trovare alcuna funzione PHP procedurale incorporata per ottenere le costanti di classe, il che è un peccato. – BoltClock

+1

Probabilmente perché non ce n'è bisogno. L'OP potrebbe voler eseguire una meta-configurazione impostando 'types' come' tutte le costanti di questa classe', che nella maggior parte dei casi e nella mia opinione limitata sono probabilmente meglio servite con l'ereditarietà o una variabile di array statica con tipi (lasciando spazio per costanti con altri significati/uso). – Wrikken

2

Alla fine gli spazi dei nomi:

namespaces enums; 
class enumCountries 
{ 
    const CountryAustria   = 1 ; 
    const CountrySweden   = 24; 
    const CountryUnitedKingdom = 25; 
} 

namespace Helpers; 
class Helpers 
{ 
    static function getCountries() 
    { 
    $c = new \ReflectionClass('\enums\enumCountries'); 
    return $c->getConstants(); 
    } 
} 

print_r(\Helpers\Helpers::getCountries()); 
3

È utile avere un metodo all'interno della classe per restituire le proprie costanti.
Si può fare in questo modo:

class Profile { 
    const LABEL_FIRST_NAME = "First Name"; 
    const LABEL_LAST_NAME = "Last Name"; 
    const LABEL_COMPANY_NAME = "Company"; 


    public static function getAllConsts() { 
     return (new ReflectionClass(get_class()))->getConstants(); 
    } 
} 

// test 
print_r(Profile::getAllConsts()); 
0

Trait con metodo statico - in soccorso

sembra che sia un luogo piacevole da usare Tratti con una funzione statica per estendere le funzionalità di classe. I tratti ci permetteranno anche di implementare questa funzionalità in qualsiasi altra classe senza dover riscrivere lo stesso codice più e più volte (resta DRY).

Utilizza il nostro tratto personalizzato 'ConstantExport' con classe Profile. Fallo per ogni classe che ti serve questa funzionalità.

/** 
* ConstantExport Trait implements getConstants() method which allows 
* to return class constant as an assosiative array 
*/ 
Trait ConstantExport 
{ 
    /** 
    * @return [const_name => 'value', ...] 
    */ 
    static function getConstants(){ 
     $refl = new \ReflectionClass(__CLASS__); 
     return $refl->getConstants(); 
    } 
} 

Class Profile 
{ 
    const LABEL_FIRST_NAME = "First Name"; 
    const LABEL_LAST_NAME = "Last Name"; 
    const LABEL_COMPANY_NAME = "Company"; 

    use ConstantExport; 

} 

esempio di uso

// So simple and so clean 
$constList = Profile::getConstants(); 

print_r($constList); // TEST 

USCITE:

Array 
(
    [LABEL_FIRST_NAME] => First Name 
    [LABEL_LAST_NAME] => Last Name 
    [LABEL_COMPANY_NAME] => Company 
)