2009-06-05 7 views
109

Tengo varias CONST definidas en algunas clases, y quiero obtener una lista de ellas. Por ejemplo:¿Puedo obtener CONST definido en una clase de PHP?

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

¿Hay alguna manera de obtener una lista de las Constituciones de la clase definida en el Profile? Por lo que puedo decir, la opción más cercana (get_defined_constants()) no hará el truco.

Lo que realmente necesito es una lista de los nombres de constantes - algo como esto:

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

O:

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

O incluso:

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

utilizando la reflexión, y una ReflectionClass en Cl, puede utilizar las getConstants función http://nz.php.net/manual /es/class.reflectionclass.php –

+0

[La reflexión será tu salvador] (http://se2.php.net/manual/en/reflectionclass.getconstants.php). –

+0

Puede hacer esto usando [reflection] (http://nz.php.net/oop5.reflection). Busque "Imprimir constantes de clase" en esa página para ver un ejemplo. – n3rd

Respuesta

191

Puede utilizar para esto. Tenga en cuenta que si está haciendo esto mucho, es posible que desee buscar en el almacenamiento en caché del resultado.

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

Salida:

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

Dos NB menores: primero, en 5.3, 'Profile' se puede usar como argumento para el constructor del reflector, sin comillas (un nombre de clase simple); segundo, para ser completamente claro, las claves de la matriz resultante son cadenas, no constantes, ya que se podría sugerir el formato aquí. (Vale la pena mencionar solo como el fn es [indocumentado] (http://www.php.net/manual/en/reflectionclass.getconstants.php).) –

+11

@Benji XVI En 5.3 si tienes los avisos activados, no ganaste ' t podrá usar 'Perfil' sin las comillas, ya que mostrará el siguiente error: Aviso: Uso de perfil constante indefinido - asumido 'Perfil'. Así que sugiero mantener las citas ''Profile'' – toneplex

+9

Es bueno definir constantes relacionadas con la lógica dentro de la clase, por lo que no es necesario codificar el argumento del constructor, sino usar' __CLASS__' en su lugar. –

4

Sí, se utiliza reflection. Mira la salida de

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

Eso debería darte la idea de lo que estarás viendo.

14

Uso token_get_all(). A saber:

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

Salida:

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

token_get_all es genial –

+1

+1, aunque diría que este es un excelente momento para usar Reflection como lo mencionan otros carteles, también es importante entender el funcionamiento "bajo la capucha" y poder prescindir de ellos o replicarlos si es necesario. Buen espectaculo. – Dereleased

+1

Si no desea que su clase se cargue en la memoria, token_get_all es una alternativa fantástica. Es MUCHO más rápido que Reflection y no satura la memoria del proceso si necesita hacer esto con muchas clases. – Harold

7

Usando ReflectionClass y getConstants() da exactamente lo que quiere:

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

Salida:

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

por la documentación de PHP comentarios, si eres capaz de utilizar el ReflectionClass (PHP 5):

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

Source is here.

2

Por qué no los pusieron en una variable de clase como una matriz para empezar? Hace que sea más fácil hacer loop through.

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

en conjunto, no verá sugerencias de finalización de código ... –

+1

Porque las matrices no son constantes? Si implementa algo que se supone que es una constante como variable, corre el riesgo de que se modifique o desactive inadvertidamente. En otras palabras, no puedes depender de que permanezcan constantes. – GordonM

18

This

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

+1 Esto sería así ya que no puedo encontrar ninguna función PHP de procedimiento incorporada para obtener las constantes de clase, lo cual es un poco vergonzoso. – BoltClock

+1

Probablemente porque hay poca necesidad de eso. El OP podría querer hacer una metaconfiguración al configurar 'types' como' todas las constantes que tiene esta clase', que en la mayoría de los casos, y en mi opinión limitada otorgada, probablemente sean más útiles con herencia o con una variable de matriz estática con el tipos (dejando espacio para constantes con otros significados/uso). – Wrikken

2

Eventualmente con espacios de nombres:

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

Es útil tener un método dentro de la clase para devolver sus propias constantes.
Puede hacerlo de esta manera:

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

Rasgo con método estático - al rescate

parece que es un buen lugar para utilizar rasgos con una función estática para ampliar la funcionalidad de clase. Los rasgos también nos permitirán implementar esta funcionalidad en cualquier otra clase sin reescribir el mismo código una y otra vez (permanecer en modo SECO).

Utilice nuestro Rasgo 'ConstantExport' personalizado en la clase de Perfil. Hazlo para cada clase que necesites esta funcionalidad.

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

} 

ejemplo de uso

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

print_r($constList); // TEST 

SALIDAS:

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