2009-06-05 8 views
109

У меня есть несколько CONST, определенных на некоторых классах, и вы хотите получить их список. Например:Могу ли я получить CONST в классе PHP?

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

Есть ли способ, чтобы получить список из ФИКСА, определенные на Profile классе? Насколько я могу судить, ближайший вариант (get_defined_constants()) не будет делать трюк.

То, что я на самом деле нужно, это список имен констант - что-то вроде этого:

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

Или:

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

Или даже:

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

с помощью отражения и ReflectionClass на Cl, вы можете использовать функцию getConstants http://nz.php.net/manual /en/class.reflectionclass.php –

+0

[Отражение будет вашим спасителем] (http://se2.php.net/manual/en/reflectionclass.getconstants.php). –

+0

Вы можете сделать это, используя [отражение] (http://nz.php.net/oop5.reflection). Найдите «Константы класса печати» на этой странице, чтобы увидеть пример. – n3rd

ответ

191

Вы можете использовать для этого. Обратите внимание: если вы делаете это много, вы можете захотеть посмотреть на кеширование результата.

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

Выход:

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

Два младших NB: во-первых, в 5.3, 'Profile' может использоваться как аргумент конструктора рефлектора без кавычек (простое имя класса); во-вторых, чтобы быть полностью ясным, результирующие массивы массива являются строками, а не константами, поскольку здесь можно было бы сделать форматирование. (Стоит упомянуть только о том, что fn [недокументирован] (http://www.php.net/manual/en/reflectionclass.getconstants.php).) –

+11

@Benji XVI В 5.3, если у вас есть уведомления, вы выиграли ' t использовать «Профиль» без кавычек, так как он будет показывать следующую ошибку: Примечание: использование неопределенного константы Профиль - предполагаемый «Профиль». Поэтому я предлагаю хранить цитаты '' Profile'' – toneplex

+9

Хорошо определить константу, связанную с логикой внутри класса, поэтому вам не нужно аргументировать конструктор hardcode, но вместо этого используйте '__CLASS__'. –

4

Да, вы используете reflection. Посмотрите на вывод

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

Это должно дать вам представление о том, что вы будете смотреть.

14

Использование token_get_all(). А именно:

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

Выход:

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

token_get_all is great –

+1

+1, хотя я бы сказал, что это отличное время для использования Reflection, как упоминалось другими плакатами, также важно понимать работу «под капотом» и быть в состоянии обойтись без них или при необходимости повторять их. Хорошее шоу. – Dereleased

+1

Если вы не хотите, чтобы ваш класс загружался в память, token_get_all - фантастическая альтернатива. Это намного быстрее, чем Reflection, и не загромождает память процесса, если вам нужно делать это с большим количеством классов. – Harold

7

Использование ReflectionClass и getConstants() дает именно то, что вы хотите:

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

Выход:

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

За комментариями PHP Docs, если вы возможность использовать ReflectionClass (PHP 5):

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

Source is here.

2

Почему бы не поставить их в переменную класса как массив с самого начала? Делает это легче, чтобы петли через.

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

в массиве вы не увидите подсказки завершения кода ... – 2010-10-06 18:49:41

+1

Поскольку массивы не являются константами? Если вы реализуете что-то, что должно быть константой в качестве переменной, вы рискуете непреднамеренно изменить или отменить ее. Другими словами, вы не можете зависеть от них, оставаясь постоянными. – GordonM

18

This

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

+1 Это было бы так, потому что я не могу найти встроенные процедурные функции PHP для получения констант класса, что немного стыдно. – BoltClock

+1

Наверное, потому что для этого мало потребности. OP может захотеть выполнить мета-конфигурацию, установив «типы» как «все константы этого класса», которые в большинстве случаев и в моем ограниченном мнении, вероятно, лучше обслуживаются либо с наследованием, либо с помощью переменной статического массива с (оставляя место для констант с другими значениями/использованием). – Wrikken

2

В конце концов с пространствами имен:

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

Удобно иметь метод внутри класса для возврата собственных констант.
Вы можете сделать это так:

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

Черту со статическим методом - на помощь

Похоже, это хорошее место, чтобы использовать Traits со статической функцией для расширения функциональных возможностей класса. Черты также позволят нам реализовать эту функциональность в любом другом классе, не переписывая один и тот же код снова и снова (оставайтесь DRY).

Используйте нашу специальную функцию «ConstantExport» с классом профиля. Сделайте это для каждого класса, в котором вам нужны эта функциональность.

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

} 

Пример использования

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

print_r($constList); // TEST 

ВЫХОДЫ:

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

 Смежные вопросы

  • Нет связанных вопросов^_^