CONST를 PHP 클래스에서 정의 할 수 있습니까?


140

일부 클래스에 여러 개의 CONST가 정의되어 있으며 해당 목록을 얻고 싶습니다. 예를 들면 다음과 같습니다.

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

Profile클래스에 정의 된 CONST 목록을 얻는 방법이 있습니까? 내가 알 수있는 한 가장 가까운 옵션 ( 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')

reflection을 사용하여이 작업을 수행 할 수 있습니다 . 해당 페이지에서 "인쇄 클래스 상수"를 검색하여 예제를보십시오.
n3rd

Cl에서 Reflection과 ReflectionClass를 사용하면 getConstants nz.php.net/manual/en/class.reflectionclass.php
Tim Ebenezer

답변:


245

이것을 위해 Reflection 을 사용할 수 있습니다 . 이 작업을 많이 수행하면 결과 캐싱을보고 싶을 수 있습니다.

<?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입니다 전용으로 언급 문서화 .)
벤지 XVI

11
@Benji XVI 5.3에서 알림을 설정 한 경우 Profile다음 오류가 표시되므로 따옴표없이 사용할 수 없습니다 . 알림 : 정의되지 않은 상수 프로필 사용- '프로파일'이라고 가정합니다. 그래서 따옴표를 유지하는 것이 좋습니다'Profile'
toneplex

10
클래스 내부에 상수 관련 논리를 정의하는 것이 좋으므로 생성자 인수를 하드 코딩 할 필요가 없지만 __CLASS__대신 사용하십시오.
Luke Adamczewski

7
new ReflectionClass(Profile::class)잘 작동
mtizziani

@mtizziani true이지만 네임 스페이스를 알고 있어야합니다! 하자 당신이 네임 스페이스가 있다고 City클래스와 B이 - B::class잘 작동,하지만 당신은 예를 들어, 이름 공간에서 그 사용하려는 경우 Jungle- 전화 B::class로를 포함하지 않고 거기를 use초래할 것 Jungle\B(! 정글 전혀 B를 가지고 있지 않더라도)
jave.web

22

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

1
+1 이것은 클래스 상수를 얻기위한 내장 된 절차 적 PHP 함수를 찾을 수 없기 때문에 가능합니다.
BoltClock

1
아마도 거의 필요하지 않기 때문일 것입니다. 영업 이익은 설정하여 메타 구성 작업을 수행 할 수 있습니다 types와 같은 all constants this class has대부분의 경우, 내 허가 제한 의견으로는, 아마 더 나은 다른 의미를 가진 상수 방을 떠날 유형 (와 중 상속 또는 정적 배열 변수와 함께 제공되는 / 사용하다).
Wrikken

16

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"

1
+1, 다른 포스터에서 언급 한 것처럼 리플렉션을 사용하기에 가장 좋은시기라고 말하지만, "사후"의 작업을 이해하고 필요하지 않은 경우 작업없이 복제하거나 복제 할 수 있어야합니다. 좋은 공연.
2009

1
클래스를 메모리에로드하지 않으려면 token_get_all이 환상적인 대안입니다. 리플렉션보다 훨씬 빠르며 많은 클래스 에서이 작업을 수행 해야하는 경우 프로세스 메모리를 어지럽히 지 않습니다.
Harold

토큰 기반 솔루션 +1! 토큰 기반 구문 분석을 이해하는 것은 성능을 고려하는 즐거움입니다 ... 항상 그렇듯이 token_get_all ()을 통해 상수를 구문 분석하는 방법을 보여주는 훌륭한 사람이 있습니다. 대단히 감사합니다!
mwatzer

아마도 이것은 단일 파일에서만 작동하며 부모 클래스에서 상수를 상속하지 않습니다. 실제로이 기법은 클래스에 신경 쓰지 않아도됩니다. 심지어 전역 범위에서도 파일의 모든 상수를 제공합니다. 그래도 탐색하기에 좋은 도구입니다.
Jason


13

ReflectionClass (PHP 5)를 사용할 수 있다면 PHP 문서 주석에 따라 :

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

소스가 여기 있습니다.


9

ReflectionClass를 사용하여 getConstants()원하는 것을 정확하게 제공합니다.

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

산출:

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

6

정적 방법으로 구조-구조

클래스 기능을 확장하기 위해 정적 함수와 함께 특성을 사용하기에 좋은 곳인 것 같습니다. 또한 특성을 통해 동일한 코드를 반복해서 다시 작성하지 않고도 다른 클래스에서이 기능을 구현할 수 있습니다 (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
)

5

예, 반사 를 사용 합니다 . 의 출력을 봐

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

그것은 당신이보고있는 것에 대한 아이디어를 줄 것입니다.


4

클래스 내부에 자체 상수를 반환하는 메서드를 사용하는 것이 편리합니다.
이 방법으로 할 수 있습니다 :

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

3

왜 클래스 변수에 배열로 넣어서 시작하지 않습니까? 통해 더 쉽게 루프합니다.

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

2
배열이 상수가 아니기 때문에? 변수로 일정 해야하는 것을 구현하면 실수로 변경되거나 설정되지 않을 위험이 있습니다. 다시 말해 일정하게 유지되는 것에 의존 할 수 없습니다.
GordonM

3

결국 네임 스페이스와 함께 :

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

1
class Qwerty 
{
    const __COOKIE_LANG_NAME__ = "zxc";
    const __UPDATE_COOKIE__ = 30000;

    // [1]
    public function getConstants_(){

        return ['__COOKIE_LANG_NAME__' => self::__COOKIE_LANG_NAME__, 
                '__UPDATE_COOKIE__' => self::__UPDATE_COOKIE__]; 
    }    

    // [2]
    static function getConstantsStatic_(){

        return ['__COOKIE_LANG_NAME__' => self::__COOKIE_LANG_NAME__, 
                '__UPDATE_COOKIE__' => self::__UPDATE_COOKIE__]; 
    } 
}

// [1]
$objC = new Qwerty();
var_dump($objC->getConstants_());

// [2]
var_dump(Qwerty::getConstantsStatic_());
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.