2009-06-05 21 views
109

J'ai plusieurs CONST définis sur certaines classes, et je veux en obtenir une liste. Par exemple:Puis-je obtenir CONST défini sur une classe PHP?

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

Est-il possible d'obtenir une liste de la CONST définie de la classe Profile? Pour autant que je sache, l'option la plus proche (get_defined_constants()) ne fera pas l'affaire.

Ce que je dois en fait une liste des noms des constantes - quelque chose comme ceci:

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

Ou:

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

Ou encore:

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

aide de la réflexion, et un ReflectionClass sur Cl, vous pouvez utiliser la fonction getConstants http://nz.php.net/manual /fr/class.reflectionclass.php –

+0

[La réflexion sera votre sauveur] (http://se2.php.net/manual/fr/reflectionclass.getconstants.php). –

+0

Vous pouvez le faire en utilisant [reflection] (http://nz.php.net/oop5.reflection). Recherchez "Imprimer les constantes de classe" sur cette page pour voir un exemple. – n3rd

Répondre

191

Vous pouvez utiliser pour ça. Notez que si vous le faites souvent, vous pouvez envisager de mettre en cache le résultat.

<?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()); 

Sortie:

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

Deux NBs mineurs: d'abord, en 5.3, 'Profile' peut être utilisé comme argument pour le constructeur du réflecteur, sans guillemets (un simple nom de classe); deuxièmement, pour être tout à fait clair, les clés du tableau qui en résulte sont des chaînes, et non des constantes, comme on pourrait le supposer ici. (Il vaut la peine de mentionner seulement que le fn est [document non documenté] (http://www.php.net/manual/fr/reflectionclass.getconstants.php).) –

+11

@Benji XVI En 5.3 si vous avez des avis activés, vous avez gagné ' t être capable d'utiliser 'Profile' sans les guillemets, car il montrera l'erreur suivante: Remarque: Utilisation de la constante non définie Profile - supposé 'Profile'. Donc, je suggère de garder les guillemets ''Profile'' – toneplex

+9

Il est bon de définir la logique liée aux constantes à l'intérieur de la classe, donc vous n'avez pas besoin de coder en dur l'argument constructeur mais d'utiliser' __CLASS__' à la place. –

4

Oui, vous utilisez reflection. Regardez la sortie de

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

Cela devrait vous donner l'idée de ce que vous regarderez.

14

Utilisez token_get_all(). A savoir:

<?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"; 
} 
?> 

Sortie:

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

token_get_all est super –

+1

+1, même si je dirais que c'est un excellent moment pour utiliser Reflection comme mentionné par d'autres affiches, il est également important de comprendre le fonctionnement "sous le capot" et être capable de s'en passer ou de les reproduire si nécessaire. Bon spectacle. – Dereleased

+1

Si vous ne voulez pas que votre classe soit chargée en mémoire, token_get_all est une alternative fantastique. C'est BEAUCOUP plus rapide que Reflection et n'encombre pas la mémoire de processus si vous devez le faire avec beaucoup de classes. – Harold

7

En utilisant ReflectionClass et getConstants() donne exactement ce que vous voulez:

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

Sortie:

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

par les commentaires docs PHP, si vous êtes capable d'utiliser le ReflectionClass (PHP 5):

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

Source is here.

2

Pourquoi ne pas les mettre dans une variable de classe comme un tableau pour commencer? Facilite la boucle à travers.

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

dans le tableau vous ne verrez pas les conseils de complétion de code ... –

+1

Parce que les tableaux ne sont pas des constantes? Si vous implémentez quelque chose qui est supposé être une constante en tant que variable, vous risquez de la modifier ou de la désactiver par inadvertance. En d'autres termes, vous ne pouvez pas dépendre de leur maintien constant. – GordonM

18

This

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

+1 Cela serait dû au fait que je ne trouve pas de fonctions PHP procédurales intégrées pour obtenir des constantes de classe, ce qui est un peu dommage. – BoltClock

+1

Probablement parce qu'il y en a peu besoin. L'OP peut vouloir faire une méta-configuration en définissant 'types' comme toutes les constantes de cette classe, qui dans la plupart des cas, et dans mon opinion limitée accordée, sont probablement mieux servis soit avec l'héritage soit avec une variable de tableau statique avec le types (en laissant la place aux constantes avec d'autres significations/utilisation). – Wrikken

2

Finalement, avec les espaces de noms:

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

Il est pratique d'avoir une méthode dans la classe pour renvoyer ses propres constantes.
Vous pouvez le faire de cette façon:

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

avec méthode statique trait - à la rescousse

On dirait qu'il est un endroit agréable à utiliser avec une fonction caractères statique pour étendre la fonctionnalité de classe. Traits nous permettra également d'implémenter cette fonctionnalité dans n'importe quelle classe sans réécrire le même code encore et encore (restez DRY).

Utilisez notre trait 'ConstantExport' personnalisé avec la classe Profile. Faites-le pour chaque classe dont vous avez besoin de cette fonctionnalité.

/** 
* 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; 

} 

Exemple d'utilisation

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

print_r($constList); // TEST 

SORTIES:

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