2009-12-10 29 views

उत्तर

48

आप उन्हें reflection API

मैं तुम्हें लगातार अपने चर (निरंतर की चर == मूल्य के मूल्य) के मूल्य के आधार के नाम पर प्राप्त करना चाहते हैं यह सोचते कर रहा हूँ के साथ मिल सकता है। कक्षा में परिभाषित सभी स्थिरांक प्राप्त करें, उन पर लूप करें और अपने चर के मूल्य के साथ उन स्थिरांक के मानों की तुलना करें। ध्यान दें कि इस दृष्टिकोण के साथ आपको कुछ अन्य स्थिरता मिल सकती है जो आप चाहते हैं, यदि समान मूल्य वाले दो स्थिरांक हैं।

उदाहरण:

class Foo { 
    const ERR_SOME_CONST = 6001; 
    const ERR_SOME_OTHER_CONST = 5001; 

    function bar() { 
     $x = 6001; 
     $fooClass = new ReflectionClass ('Foo'); 
     $constants = $fooClass->getConstants(); 

     $constName = null; 
     foreach ($constants as $name => $value) 
     { 
      if ($value == $x) 
      { 
       $constName = $name; 
       break; 
      } 
     } 

     echo $constName; 
    } 
} 

पुनश्च:

$class = new ReflectionClass("Foo"); 
$constants = $class->getConstants(); 

$constants एक सरणी है: प्रतिबिंब के साथ आप कह क्यों आप इस की जरूरत है, के रूप में यह बहुत ही असामान्य लगता है मन कर ...

+1

कुछ भी नहीं है गंभीर, वास्तव में। क्लास फ़ंक्शन से त्रुटि कोड पास करने के तरीके के बारे में सोचें। मेरे लिए const ERR_SOME_ERROR = 'ERR_SOME_ERROR' अजीब लग रहा है, मैंने सोचा कि मेरा getLastError() फ़ंक्शन सरणी (5003 => 'ERR_SOME_ERROR', 5002 => 'ERR_SOME_ERR2') जैसे कुछ वापस कर सकता है। बस त्रुटि कोड और त्रुटि नाम लौटा है। खैर, जितना अधिक मैं इसके बारे में सोचता हूं, मैं शायद इसका उपयोग नहीं करूंगा (जैसा आपने बताया था असामान्य वाक्यविन्यास के लिए) :) –

+0

को CURLE_ * निरंतर समर्थन के लिए भी इसकी आवश्यकता है जहां 'curl_multi_strerror' उपलब्ध नहीं था –

+2

मुझे कुछ चाहिए " इस तरह को लिखने के बिना एक अच्छा त्रुटि आउटपुट प्रदान करने के लिए इस तरह हम स्थिरांक कोड के रूप में संग्रहीत कुछ त्रुटि कोड ट्रैक करते हैं। – Frug

12

जिसमें कक्षा फू में परिभाषित स्थिरांक के सभी नाम और मूल्य हैं।

1

सभी फ़ंक्शन को इस फ़ंक्शन का उपयोग करके सरणी को असाइन किया जा सकता है।

$const = get_defined_constants(); 

फिर निम्न फ़ंक्शन का उपयोग कर आप सरणी संरचना

echo "<pre>"; 

print_r($const); 

मुद्रित कर सकते हैं और आप अधिक विवरण देख सकते हैं यहाँ www.sugunan.com

20

यहाँ मैं क्या इसे प्राप्त करने के लिए किया था है। जन हंसीक से प्रेरित

class ErrorCode 
{ 
    const COMMENT_NEWCOMMENT_DISABLED = -4; 
    const COMMENT_TIMEBETWEENPOST_ERROR = -3; 
    /** 
    * Get error message of a value. It's actually the constant's name 
    * @param integer $value 
    * 
    * @return string 
    */ 
    public static function getErrorMessage($value) 
    { 
     $class = new ReflectionClass(__CLASS__); 
     $constants = array_flip($class->getConstants()); 

     return $constants[$value]; 
    } 
} 
+3

बस यह कहना चाहते हैं कि यदि स्थिरांक के समान मूल्य हो तो यह काम नहीं करेगा। अधिकांश समय में कोई समस्या नहीं होनी चाहिए, लेकिन हाँ ... – Populus

7

मुझे पता है कि यह एक पुराना प्रश्न है और सब कुछ है, लेकिन मुझे अभी भी लगता है कि मेरे पास कुछ उपयोगी इनपुट है। मैंने इसे एक अमूर्त वर्ग का उपयोग करके कार्यान्वित किया है जो मेरे सभी enums विस्तारित है। अमूर्त वर्ग में एक सामान्य toString() विधि होती है;

abstract class BaseEnum{ 
    private final function __construct(){ } 

    public static function toString($val){ 
     $tmp = new ReflectionClass(get_called_class()); 
     $a = $tmp->getConstants(); 
     $b = array_flip($a); 

     return ucfirst(strtolower($b[$val])); 
    } 
} 

//actual enum 
final class UserType extends BaseEnum { 
    const ADMIN = 10; 
    const USER = 5; 
    const VIEWER = 0; 
} 

इस तरह आप आउटपुट में उपयोग करने के लिए मानव पठनीय स्ट्रिंग प्राप्त कर सकते हैं, जो प्रत्येक enum पर आधारित है। इसके अलावा, enum के आपके कार्यान्वयन, final होने के कारण, विस्तारित नहीं किया जा सकता है और क्योंकि BaseEnum में कन्स्ट्रक्टर private है, इसे कभी भी तत्काल नहीं किया जा सकता है।

तो उदाहरण के लिए, यदि आप अपने प्रकार के साथ सभी उपयोगकर्ता नाम की एक सूची दिखाने के लिए आप की तरह

foreach($users as $user){ 
    echo "<li>{$user->name}, ".UserType::toString($user->usertype)."</li>"; 
} 
2

कुछ करता है, तो आप एक ही कक्षा की एक विधि पर निरंतर मूल्य प्राप्त करने की आवश्यकता कर सकते हैं, तो आप सिर्फ जरूरत है स्वयं ऑपरेटर का उपयोग करने के लिए। आप प्रतिबिंब का उपयोग आप अन्य वर्ग

class Foo { 
    const ERR_SOME_CONST = 6001; 

    function bar() { 
     self::ERR_SOME_CONST; 
    } 
} 
3

चेतावनी पर स्थिरांक उपयोग करना चाहते हैं कर सकते हैं: इस तरह से आप कार्यक्रम नहीं करना चाहिए ...(यदि आप सुनिश्चित नहीं आप क्या कर :))

मैं 1 पंक्ति जो CATEGORY_

इसलिए यहाँ की अपनी पसंद से स्थिरांक और उनके संख्यात्मक मान echos लिखा CATEGORY_ ERR_ की

foreach(get_defined_constants() as $key => $value) if(strlen($key)>5) if(substr($key, 0,5)=="ERR_") echo"<br>Found an php ERR_ constant! : ".$key."=>".$value; 

सूची है

//input parameters: CATEGORYNAME_ , #constantNumber 
function getConstantName($category,$constantNumber){foreach(get_defined_constants() as $key => $value) if(strlen($key)>strlen($category)) if(substr($key, 0,strlen($category))==$category) if($value==$constantNumber) return $key; return "No constant found.";} 
उदाहरण som के लिए

तो: और अगर आप सिर्फ एक आप संख्या से की तलाश में चाहते हैं => मैं 1row समारोह बनाया ई जानकारी संख्या 64 के साथ लगातार:

echo "NameOfConstant: ".getConstantName("INFO_",64); 

इच्छा उत्पादन कुछ की तरह: NameOfConstant: INFO_LICENSE

5

सभी अन्य उत्तर आवश्यक अंक कवर किया। लेकिन, अगर पागल एक लाइनर्स अपने बात है, तो यह है:

:

function getConstantName($class, $value) 
{ 
    return array_flip((new \ReflectionClass($class))->getConstants())[$value]; 
} 

आप इस मामले में जहां मूल्य वास्तव में स्थिरांक में से एक हो नहीं हो सकता है संभाल करने की जरूरत है, तो आप एक अतिरिक्त पंक्ति दे सकते हैं

function getConstantName($class, $value) 
{ 
    $map = array_flip((new \ReflectionClass($class))->getConstants()); 
    return (array_key_exists($value, $map) ? $map[$value] : null); 
} 
+1

यह आसान और त्वरित समाधान है। ऐरे फ्लिप करें और कुंजी की जांच करें। –

2

ठीक है, ठीक है, मुझे पता है कि सबकुछ पहले ही कवर हो चुका है :) लेकिन जन हनसीक ने उपयोग के मामले के लिए कहा, इसलिए मैं अपना हिस्सा साझा करूंगा। इसके अलावा: हर कोई array_flip() का उपयोग करता प्रतीत होता है। Array_search() क्यों नहीं?

मुझे इसे एक कक्षा में चाहिए जो \ अपवाद बढ़ाता है और मेरे ठोस अपवादों के छोटे सेट का आधार वर्ग है। उन ठोस अपवाद वर्गों में से प्रत्येक एक व्यापक अपवाद डोमेन को शामिल करता है और कई सटीक अपवाद कारणों को परिभाषित करता है। कारण? मैं बनाए रखने और याद रखने के लिए अपवादों की भीड़ नहीं लेना चाहता हूं। इसके अलावा, अपवाद हैंडलर सेट है जो अपवाद को लॉग फ़ाइल में गड़बड़ कर देता है - और यह यहां है कि मुझे निरंतर नाम प्राप्त करने की आवश्यकता है क्योंकि काफी दर्दनाक स्थिति में अपवाद कारण को समझने की कोशिश की जा रही है। मेरी CLI स्क्रिप्ट से

उदाहरण:

class AbstractException extends Exception { 
    public function getName() { 
     return array_search($this->getCode(), (new ReflectionClass($this))->getConstants()); 
    } 
} 

class SyntaxException extends AbstractException { 
    const BAD_SYNTAX = 90; 
    const REQUIRED_PARAM = 91; 
    const REQUIRED_VALUE = 92; 
    const VALUE_TYPE = 93; 
    const VALUE_OUT_OF_BOUNDS = 94; 

    public function __construct ($message = "", $code = self::BAD_SYNTAX, Exception $previous = NULL) { 
     $script = basename($GLOBALS['argv'][0]); 

     echo "Invalid syntax: $message \nSee: `$script --help` for more information\n"; 
     parent::__construct($message, $code, $previous); 
    } 
} 

// in autoload include 
set_exception_handler(function(Exception $e) { 
    error_log(basename($GLOBALS['argv'][0]) . ';'. date('Y-m-d H:i:s') .';'. $e->getName() .';'. $e->getMessage() .';'. $e->getFile() .';'. $e->getLine() ."\n", 3, 'error.log'); 
    exit ($e->getCode()); 
}); 
संबंधित मुद्दे