PHP में गतिशील रूप से चुने हुए वर्ग स्थिर का मूल्य प्राप्त करें


114

मैं ऐसा कुछ करने में सक्षम होना चाहता हूं:

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

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

यह काम नहीं करता है। क्या कुछ समतुल्य करने का सीधा तरीका है? ध्यान दें कि मैं कक्षा के साथ फंस गया हूं; यह एक पुस्तकालय में है जिसे मैं फिर से नहीं लिख सकता। मैं कोड लिख रहा हूं जो कमांड लाइन पर तर्क देता है, और मैं वास्तव में आईडी संख्याओं के बजाय प्रतीकात्मक नाम लेना चाहूंगा।


क्या आप कोशिश कर सकते हैं ThingIDs::{$thing}?
डेविड रॉड्रिग्स

पहले ही कोशिश कर ली है। घातक रनटाइम त्रुटि के बजाय मुझे पार्स त्रुटि मिलती है।
बेन

जवाबों:


182

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

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


1
साइड नोट: यदि आप पहले जांचना चाहते हैं कि स्थिरांक परिभाषित किया गया है या नहीं, यह हैdefined("ThingIDs::$thing");
पैरिस वार्नी

3
या $ आईडी = स्थिर ("स्व :: $ चीज");
लाइन

3
इसके समान है,$id = constant(sprintf('%s::%s', ThingIDs::class, $thing));
डेविड बाउकम

4
@DavidBaucum आप इसे अधिक जटिल क्यों चाहते हैं? अनुरोध काफी सरल है और इसमें कोई बाहर नहीं, उपयोगकर्ता जोड़ तोड़ इनपुट शामिल है। उस के अलावा, आप एक और समारोह कह रहे हैं क्योंकि, मुझे लगता है, आप स्ट्रिंग को सीमांकक के साथ समेटना पसंद नहीं करते हैं?
ReSpawN

5
आपके उपयोग-मामले के आधार पर, मेरा समाधान कम जटिल है। विशेष रूप से यदि आप PSR-4 ऑटोलेडिंग का उपयोग कर रहे हैं, तो यह आपके कोड में बदसूरत हो सकता है कि हर जगह FQDN वर्तनी हो। useफ़ाइल के शीर्ष पर उपयोग करके और फिर ::classFQDN को जादुई तरीके से प्राप्त करने की विधि का उपयोग करके पठनीयता में सुधार होता है।
डेविड बाउकम

27

चिंतन का प्रयोग करें

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

3
प्रतिबिंब वास्तव में कक्षाओं, विधियों और बहुत सारी जानकारी प्रदान करते हैं और ऐसा लगता है कि बहुत से लोग उन्हें समझने के लिए उस कदम को लेने से डरते हैं। बहुत बढ़िया जवाब।
माइक मैकिनटोश

2
@mikemackintosh मैंने उन्हें समझने के लिए कदम उठाए हैं, लेकिन स्वीकार किए गए उत्तर बनाम प्रदर्शन प्रभाव के संदर्भ में ज्यादा नहीं देखा है। यह कुछ ऐसा है जिसे मैं जानने में दिलचस्पी रखता हूं। एक नए वर्ग को तात्कालिक रूप से ऐसा लगता है कि यह केवल एक स्थिर रूप से कॉल करने की तुलना में एक बड़ा प्रदर्शन हिट होगा। इस पर आपके क्या विचार हैं?
दुबेवाद

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);
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.