क्या मैं एक PHP वर्ग पर CONST को परिभाषित कर सकता हूँ?


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')

आप प्रतिबिंब का उपयोग करके ऐसा कर सकते हैं । एक उदाहरण देखने के लिए उस पृष्ठ पर "प्रिंट क्लास कॉन्स्टेंट" खोजें।
n3rd

प्रतिबिंब का उपयोग करना, और Cl पर एक ReflectionClass, आप फ़ंक्शन का उपयोग कर सकते हैं getConstants nz.php.net/manual/en/class.reflectionclass.php
टिम Ebenezer

जवाबों:


245

आप इसके लिए रिफ्लेक्शन का उपयोग कर सकते हैं । ध्यान दें कि यदि आप ऐसा कर रहे हैं तो आप परिणाम को देखना चाहते हैं।

<?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
दो मामूली एनबी: पहले, 5.3 में, Profileरिफ्लेक्टर कंस्ट्रक्टर के तर्क के रूप में इस्तेमाल किया जा सकता है, बिना उद्धरण (एक साधारण वर्ग का नाम); दूसरा, पूरी तरह से स्पष्ट होने के लिए, परिणामस्वरूप सरणी की कुंजी तार हैं, न कि स्थिरांक के रूप में यहां प्रारूपण करने के लिए सुझाव दिया जा सकता है। (केवल उल्लेख के रूप में fn undocumented है ।)
बेनजी XVI

11
@Benji XVI 5.3 में यदि आपने नोटिस किया है, तो आप Profileउद्धरणों के बिना उपयोग नहीं कर पाएंगे , क्योंकि यह निम्नलिखित त्रुटि दिखाएगा: सूचना: अपरिभाषित निरंतर प्रोफ़ाइल का उपयोग - 'प्रोफाइल' मान लिया गया। इसलिए मैं 'Profile'
टोनप्लेक्स

10
कक्षा के अंदर स्थिरांक संबंधी तर्क को परिभाषित करना अच्छा है, इसलिए आपको कंस्ट्रक्टर के तर्क को हार्डकोड करने की आवश्यकता नहीं है, बल्कि इसका उपयोग करें __CLASS__
ल्यूक एडमच्यूस्की

7
new ReflectionClass(Profile::class)ठीक भी काम करता है
mtizziani

@mtizziani सच है, लेकिन नाम स्थान से अवगत रहें! मान लीजिए कि आपके पास Cityकक्षा के साथ नाम स्थान है B- B::classठीक काम करेगा, लेकिन यदि आप उदाहरण के नामस्थान में उन का उपयोग करेंगे Jungle- तो B::classइसके साथ इसमें शामिल किए बिना कॉल करने पर भी useपरिणाम होगा Jungle\B(भले ही जंगल में बी बिल्कुल न हो!)
jave.web

22

यह

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

1
+1 यह तब से होगा क्योंकि मुझे क्लास कॉन्स्टेंट पाने के लिए कोई अंतर्निहित प्रक्रियात्मक PHP फ़ंक्शन नहीं मिल सकता है, जो थोड़ा शर्म की बात है।
BoltClock

1
शायद इसलिए क्योंकि इसकी बहुत कम जरूरत है। ओपी के typesरूप में स्थापित करके एक मेटा-कॉन्फ़िगरेशन करना चाहते हो सकता है all constants this class has, जो ज्यादातर मामलों में, और मेरी दी गई सीमित राय में, शायद या तो विरासत के साथ या स्थैतिक सरणी चर के साथ बेहतर तरीके से परोसा जाता है (अन्य अर्थों के साथ स्थिरांक के लिए कमरा छोड़कर) उपयोग)।
19

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, भले ही मैं कहूंगा कि अन्य पोस्टरों द्वारा बताए गए प्रतिबिंब का उपयोग करने के लिए यह एक उत्कृष्ट समय है, कामकाज को "अंडर-द-हूड" को समझना और उनके बिना करने में सक्षम होना आवश्यक है या यदि आवश्यक हो तो उन्हें दोहराने में सक्षम होना चाहिए। अच्छा प्रदर्शन।
डेरेलिज्ड

1
यदि आप नहीं चाहते कि आपकी कक्षा को मेमोरी में लोड किया जाए, तो token_get_all एक शानदार विकल्प है। यह प्रतिबिंब की तुलना में बहुत तेज़ है और यदि आपको बहुत सारी कक्षाओं के साथ ऐसा करने की आवश्यकता है तो प्रक्रिया मेमोरी को अव्यवस्थित नहीं करता है।
हेरोल्ड

टोकन आधारित समाधान के लिए +1! टोकन-आधारित पार्सिंग को समझना प्रदर्शन को देखते हुए एक खुशी है ... और हमेशा की तरह एक महान व्यक्ति है जो बताता है कि टोकन toget_get_all () के माध्यम से स्थिरांक कैसे पार्स करें। आपका बहुत बहुत धन्यवाद!
mwatzer

संभवतः यह केवल एकल फ़ाइल पर कार्य करता है, और मूल वर्गों से किसी भी स्थिरांक को प्राप्त नहीं करता है। वास्तव में, यह तकनीक वर्ग की भी परवाह नहीं करती है - यह आपको फ़ाइल में सभी स्थिरांक प्रदान करेगी, यहां तक ​​कि वैश्विक दायरे में भी। हालांकि यह पता लगाने के लिए एक महान उपकरण है।
जेसन


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

स्थैतिक विधि के साथ - बचाव के लिए

ऐसा लगता है कि यह वर्ग कार्यक्षमता का विस्तार करने के लिए स्थैतिक फ़ंक्शन के साथ लक्षण का उपयोग करने के लिए एक अच्छी जगह है। लक्षण हमें इस कार्यक्षमता को किसी भी अन्य वर्ग में एक ही कोड को फिर से लिखे बिना फिर से लागू करने देंगे (डीआरवाई रहें)।

प्रोफ़ाइल वर्ग में हमारे कस्टम 'कॉन्स्टैंटएक्सपोर्ट' विशेषता का उपयोग करें। यह हर वर्ग के लिए करें कि आपको इस कार्यक्षमता की आवश्यकता है।

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


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
क्योंकि सरणियाँ स्थिरांक नहीं हैं? यदि आप किसी ऐसी चीज को कार्यान्वित करते हैं जो एक चर के रूप में एक स्थिर माना जाता है, तो आप इसे अनजाने में परिवर्तित या परेशान होने का जोखिम उठाते हैं। दूसरे शब्दों में, आप उन पर स्थिर नहीं रह सकते।
गॉर्डन 8

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