php - परिभाषित() बनाम कॉन्स




const constants (7)

बहुत सरल सवाल: PHP में, आप कब उपयोग करते हैं

define('FOO', 1);

और आप कब उपयोग करते हैं

const FOO = 1;

उन दोनों के बीच मुख्य मतभेद क्या हैं?


NikiC का जवाब सबसे अच्छा है, लेकिन नामस्थानों का उपयोग करते समय मुझे एक गैर-स्पष्ट चेतावनी जोड़ने दें ताकि आप अप्रत्याशित व्यवहार से पकड़े न जाएं। याद रखने की बात यह है कि परिभाषाएं हमेशा वैश्विक नामस्थान में होती हैं जब तक आप परिभाषित पहचानकर्ता के हिस्से के रूप में नामस्थान को स्पष्ट रूप से जोड़ते हैं। इसके बारे में स्पष्ट नहीं है कि नामित पहचानकर्ता वैश्विक पहचानकर्ता को टंप करता है। इसलिए :

<?php
namespace foo
{
  // Note: when referenced in this file or namespace, the const masks the defined version
  // this may not be what you want/expect
  const BAR = 'cheers';
  define('BAR', 'wonka');

  printf("What kind of bar is a %s bar?\n", BAR);

  // To get to the define in the global namespace you need to explicitely reference it
  printf("What kind of bar is a %s bar?\n", \BAR);
}

namespace foo2
{
  // But now in another namespace (like in the default) the same syntax calls up the 
  // the defined version!
  printf("Willy %s\n", BAR);
  printf("three %s\n", \foo\BAR);  
}
?>

पैदा करता है:

What kind of bar is a cheers bar? 
What kind of bar is a wonka bar?
willy wonka 
three cheers

जो कि मेरे लिए दर्जनों अन्य भाषाओं में एक कॉन्स के विचार के बाद से पूरी तरह से उलझन में पूरी तरह से भ्रमित हो जाता है, यह है कि जहां भी आप अपने कोड में रहते हैं, वही हमेशा होता है, और PHP वास्तव में इसकी गारंटी नहीं देता है।


NikiC के जवाब पर जोड़ने के लिए। निम्नानुसार कक्षाओं में const का उपयोग किया जा सकता है:

class Foo {
    const BAR = 1;

    public function myMethod() {
        return self::BAR;
    }
}

आप define() साथ ऐसा नहीं कर सकते हैं।


PHP 5.3 तक, वैश्विक दायरे में const उपयोग नहीं किया जा सका। आप इसे केवल कक्षा के भीतर से ही उपयोग कर सकते हैं। इसका उपयोग तब किया जाना चाहिए जब आप उस वर्ग से संबंधित किसी प्रकार का निरंतर विकल्प या सेटिंग सेट करना चाहते हैं। या शायद आप किसी तरह का enum बनाना चाहते हैं।

define का उपयोग उसी उद्देश्य के लिए किया जा सकता है, लेकिन इसका उपयोग केवल वैश्विक दायरे में ही किया जा सकता है। इसका उपयोग केवल वैश्विक सेटिंग्स के लिए किया जाना चाहिए जो पूरे एप्लिकेशन को प्रभावित करते हैं।

अच्छा const उपयोग का एक उदाहरण जादू संख्याओं से छुटकारा पाने के लिए है। पीडीओ के स्थिरांक पर एक नज़र डालें। जब आपको एक fetch प्रकार निर्दिष्ट करने की आवश्यकता होती है, तो आप उदाहरण के लिए PDO::FETCH_ASSOC टाइप करेंगे। यदि कॉन्स का उपयोग नहीं किया गया था, तो आप 35 तरह कुछ टाइप करना समाप्त कर देंगे (या जो भी FETCH_ASSOC परिभाषित किया गया है)। यह पाठक को कोई समझ नहीं आता है।

अच्छा define उपयोग का एक उदाहरण शायद आपके एप्लिकेशन के रूट पथ या लाइब्रेरी का संस्करण संख्या निर्दिष्ट कर रहा है।


इनमें से अधिकतर जवाब गलत हैं या केवल कहानी की आधा कह रहे हैं।

  1. आप नेमस्पेस का उपयोग करके अपने स्थिरांक को गुंजाइश कर सकते हैं।
  2. आप वर्ग परिभाषाओं के बाहर "const" कीवर्ड का उपयोग कर सकते हैं। हालांकि, कक्षाओं की तरह ही "const" कीवर्ड का उपयोग करके आवंटित मान निरंतर अभिव्यक्ति होना चाहिए।

उदाहरण के लिए:

const AWESOME = 'Bob'; // Valid

खराब उदाहरण:

const AWESOME = whatIsMyName(); // Invalid (Function call)
const WEAKNESS = 4+5+6; // Invalid (Arithmetic) 
const FOO = BAR . OF . SOAP; // Invalid (Concatenation)

परिवर्तनीय स्थिरांक बनाने के लिए परिभाषित करें () जैसे:

define('AWESOME', whatIsMyName()); // Valid
define('WEAKNESS', 4 + 5 + 6); // Valid
define('FOO', BAR . OF . SOAP); // Valid

मुझे पता है कि यह पहले से ही उत्तर दिया गया है, लेकिन मौजूदा उत्तरों में से कोई भी नामस्थान का कोई उल्लेख नहीं करता है और यह कैसे स्थिरांक को परिभाषित करता है और परिभाषित करता है।

PHP 5.3 के रूप में, कॉन्स्ट और परिभाषा अधिकांश मामलों में समान होती है। हालांकि, अभी भी कुछ महत्वपूर्ण अंतर हैं:

  • कॉन्स्ट को अभिव्यक्ति से परिभाषित नहीं किया जा सकता है। const FOO = 4 * 3; काम नहीं करता है, लेकिन define('CONST', 4 * 3); कर देता है।
  • define करने के लिए पारित नाम में उस नामस्थान के भीतर नामस्थान को define जाना चाहिए।

नीचे दिए गए कोड को मतभेदों को चित्रित करना चाहिए।

namespace foo 
{
    const BAR = 1;
    define('BAZ', 2);
    define(__NAMESPACE__ . '\\BAZ', 3);
}

namespace {
    var_dump(get_defined_constants(true));
}

उपयोगकर्ता उप-सरणी की सामग्री ['foo\\BAR' => 1, 'BAZ' => 2, 'foo\\BAZ' => 3]

=== अद्यतन ===

आगामी PHP 5.6 const साथ थोड़ा अधिक लचीलापन की अनुमति देगा। अब आप अभिव्यक्तियों के संदर्भ में कॉन्स्ट को परिभाषित करने में सक्षम होंगे, बशर्ते कि वे अभिव्यक्ति अन्य संविधान या शाब्दिक से बने हों। इसका मतलब है कि निम्नलिखित 5.6 के रूप में मान्य होना चाहिए:

const FOOBAR = 'foo ' . 'bar';
const FORTY_TWO = 6 * 9; // For future editors: THIS IS DELIBERATE! Read the answer comments below for more details
const ULTIMATE_ANSWER = 'The ultimate answer to life, the universe and everything is ' . FORTY_TWO;

आप अभी भी चर या फ़ंक्शन रिटर्न के संदर्भ में कॉन्स्ट को परिभाषित करने में सक्षम नहीं होंगे, इसलिए

const RND = mt_rand();
const CONSTVAR = $var;

अभी भी बाहर हो जाएगा।


मेरा मानना ​​है कि PHP 5.3 के रूप में, आप कक्षाओं के बाहर const उपयोग कर सकते हैं, जैसा कि दूसरे उदाहरण में दिखाया गया है:

http://www.php.net/manual/en/language.constants.syntax.php

<?php
// Works as of PHP 5.3.0
const CONSTANT = 'Hello World';

echo CONSTANT;
?>

define मैं वैश्विक स्थिरांक के लिए उपयोग define हूं।

मैं कक्षा स्थिरांक के लिए उपयोग करते हैं।

आप कक्षा के दायरे में define नहीं कर सकते हैं, और साथ ही आप कर सकते हैं। कहने की जरूरत नहीं है, आप कक्षा के दायरे के बाहर const उपयोग नहीं कर सकते हैं

इसके अलावा, const साथ, यह वास्तव में वर्ग के सदस्य बन जाता है, define साथ, इसे वैश्विक दायरे में धकेल दिया जाएगा।







constants