PHP에서 동적으로 선택된 클래스 상수 값 가져 오기


114

다음과 같이 할 수 있기를 바랍니다.

class ThingIDs
{
    const Something = 1;
    const AnotherThing = 2;
}

$thing = 'Something';
$id = ThingIDs::$thing;

이것은 작동하지 않습니다. 동등한 것을 수행하는 간단한 방법이 있습니까? 나는 수업에 갇혀 있습니다. 다시 쓸 수없는 라이브러리에 있습니다. 나는 명령 행에서 인수를 코드를 쓰고 있어요, 나는 것이 정말 맘 기호 이름 대신 ID 번호를 취할 수 있습니다.


시도해 볼 수 있습니까 ThingIDs::{$thing}?
David Rodrigues

이미 시도했습니다. 치명적인 런타임 오류 대신 구문 분석 오류가 발생합니다.
Ben

답변:


182

$id = constant("ThingIDs::$thing");

http://php.net/manual/en/function.constant.php


1
사이드 참고 : 상수가 정의되어 있는지 여부를 먼저 확인하고 싶다면, 그건defined("ThingIDs::$thing");
패리스 바니

3
또는 $ id = constant ( "self :: $ thing");
Line

3
이와 유사하게,$id = constant(sprintf('%s::%s', ThingIDs::class, $thing));
데이비드 Baucum

4
@DavidBaucum 왜 이것을 지나치게 복잡하게 만들고 싶습니까? 요청은 매우 간단하며 사용자가 조작 할 수있는 외부 입력이 필요하지 않습니다. 그 외에도 다른 함수를 호출하고 있습니다. 왜냐하면 구분 기호로 문자열을 연결하는 것을 좋아하지 않기 때문입니다.
ReSpawN

5
사용 사례에 따라 내 솔루션이 덜 복잡합니다. 특히 PSR-4 자동로드를 사용하는 경우 코드에서 FQDN을 모든 곳에서 사용하는 것이 추악 할 수 있습니다. 사용하여 use파일의 맨 위에 다음 사용 ::class마술 FQDN은 가독성을 향상 얻을 방법을.
David Baucum 2016

27

반사 사용

$r = new ReflectionClass('ThingIDs');
$id = $r->getConstant($thing);

3
리플렉션은 클래스, 메서드 등에 대한 많은 통찰력을 제공하며 많은 사람들이이를 이해하기 위해 그 단계를 밟는 것을 두려워하는 것 같습니다. 좋은 대답입니다.
Mike Mackintosh 2012

2
@mikemackintosh 나는 그것들을 이해하기 위해 조치를 취했지만 성능에 미치는 영향과 허용되는 대답의 측면에서 많이 보지 못했습니다. 그게 제가 알고 싶은 것입니다. 새 클래스를 인스턴스화하는 것은 단순히 상수를 정적으로 호출하는 것보다 더 큰 성능 저하를 가져 오는 것처럼 보입니다. 그것에 대한 당신의 생각은 무엇입니까?
dudewad 2013 년

13

네임 스페이스를 사용하는 경우 클래스에 네임 스페이스를 포함해야합니다.

echo constant('My\Application\ThingClass::ThingConstant'); 

3
<?php

class Dude {
    const TEST = 'howdy';
}

function symbol_to_value($symbol, $class){
    $refl = new ReflectionClass($class);
    $enum = $refl->getConstants();
    return isset($enum[$symbol])?$enum[$symbol]:false;
}

// print 'howdy'
echo symbol_to_value('TEST', 'Dude');

3

도우미 기능

다음과 같은 기능을 사용할 수 있습니다.

function class_constant($class, $constant)
{
    if ( ! is_string($class)) {
        $class = get_class($class);
    }

    return constant($class . '::' . $constant);
}

두 가지 인수가 필요합니다.

  • 클래스 이름 또는 개체 인스턴스
  • 클래스 상수 이름

객체 인스턴스가 전달되면 해당 클래스 이름이 유추됩니다. PHP 7을 사용하는 경우 ::class네임 스페이스에 대해 생각할 필요없이 적절한 클래스 이름을 전달할 수 있습니다 .

class MyClass
{
    const MY_CONSTANT = 'value';
}

class_constant('MyClass', 'MY_CONSTANT'); # 'value'
class_constant(MyClass::class, 'MY_CONSTANT'); # 'value' (PHP 7 only)

$myInstance = new MyClass;
class_constant($myInstance, 'MY_CONSTANT'); # 'value'

0

클래스 자체에 대한 참조가있는 경우 다음을 수행 할 수 있습니다.

if (defined(get_class($course). '::COURSES_PER_INSTANCE')) {
   // class constant is defined
}

0

내 문제는이 주제와 비슷했습니다. 객체는 있지만 클래스 이름은없는 경우 다음을 사용할 수 있습니다.

$class_name = get_class($class_object);
$class_const = 'My_Constant';

$constant_value = constant($class_name.'::'.$class_const);
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.