define () बनाम const


658

PHP में, आप कब उपयोग करते हैं

define('FOO', 1);

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

const FOO = 1;

?

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


4
प्रदर्शन के बारे में (मेरे अनुसार माइक्रो-ऑप्टिमाइज़ेशन के साथ समय की बर्बादी), इस उत्तर को देखें : constकी तुलना में दो गुना तेज है define। पृष्ठ लोड समय और मेमोरी उपयोग के बारे में: इस प्रश्न और इस लेख को देखें ... यहाँ भी opcode कैश के बारे में कुछ देखें ।
पीटर क्रूस

2
केवल वर्तमान स्वीकार किए गए उत्तर को न देखें, लेकिन कृपया stackoverflow.com/a/3193704/1412157 पर एक नज़र डालें क्योंकि यह स्वीकृत उत्तर होना चाहिए था
LucaM

1
बस अपनी टिप्पणी के लिए अधिसूचना देखी। मैंने स्वीकृत उत्तर को अपडेट कर दिया है।
danjarvis 20-30 पर

जवाबों:


1038

PHP 5.3 के अनुसार स्थिरांक को परिभाषित करने के दो तरीके हैं : या तो constकीवर्ड का उपयोग करना या define()फ़ंक्शन का उपयोग करना:

const FOO = 'BAR';
define('FOO', 'BAR');

उन दो तरीकों के बीच मूलभूत अंतर यह है कि constलगातार समय पर स्थिरांक को परिभाषित करता है, जबकि defineउन्हें रन समय पर परिभाषित करता है। यह सबसे अधिक constनुकसान का कारण बनता है । इसके कुछ नुकसान constहैं:

  • constस्थैतिक रूप से परिभाषित करने के लिए उपयोग नहीं किया जा सकता है। एक वैश्विक स्थिरांक को परिभाषित करने के लिए, इसका उपयोग सबसे बाहरी क्षेत्र में किया जाना है:

    if (...) {
        const FOO = 'BAR';    // Invalid
    }
    // but
    if (...) {
        define('FOO', 'BAR'); // Valid
    }

    आप ऐसा क्यों करना चाहेंगे? एक सामान्य अनुप्रयोग यह जांचना है कि क्या स्थिरांक पहले से परिभाषित है:

    if (!defined('FOO')) {
        define('FOO', 'BAR');
    }
  • constएक स्थिर अदिश (संख्या, स्ट्रिंग या जैसे अन्य निरंतर स्वीकार करता है true, false, null, __FILE__), जबकि define()किसी भी अभिव्यक्ति लेता है। चूंकि PHP 5.6 स्थिर अभिव्यक्ति की अनुमति है const:

    const BIT_5 = 1 << 5;    // Valid since PHP 5.6 and invalid previously
    define('BIT_5', 1 << 5); // Always valid
  • constएक सादा स्थिर नाम लेता है, जबकि define()किसी भी अभिव्यक्ति को नाम के रूप में स्वीकार करता है। यह इस तरह से काम करने की अनुमति देता है:

    for ($i = 0; $i < 32; ++$i) {
        define('BIT_' . $i, 1 << $i);
    }
  • consts हमेशा केस संवेदनशील होते हैं, जबकि define()आप trueतीसरे तर्क के रूप में पास होकर केस असंवेदनशील स्थिरांक को परिभाषित करने की अनुमति देते हैं (नोट: केस-असंवेदनशील स्थिरांक को परिभाषित करते हुए PHP 7.3.0 के रूप में दर्शाया गया है।)।

    define('FOO', 'BAR', true);
    echo FOO; // BAR
    echo foo; // BAR

तो, यह चीजों का बुरा पक्ष था। अब आइए इस कारण को देखें कि मैं व्यक्तिगत रूप से हमेशा उपयोग करता हूं constजब तक कि उपरोक्त स्थितियों में से एक न हो:

  • constबस अच्छे से पढ़ता है। यह एक फ़ंक्शन के बजाय एक भाषा निर्माण है और यह भी संगत है कि आप कक्षाओं में स्थिरांक कैसे परिभाषित करते हैं।
  • constएक भाषा निर्माण होने के नाते, स्वचालित टूलिंग द्वारा सांख्यिकीय रूप से विश्लेषण किया जा सकता है।
  • constवर्तमान नामस्थान में एक स्थिरांक को परिभाषित करता है, जबकि define()पूरा नामस्थान नाम पास करना होता है:

    namespace A\B\C;
    // To define the constant A\B\C\FOO:
    const FOO = 'BAR';
    define('A\B\C\FOO', 'BAR');
  • चूंकि PHP 5.6 constस्थिरांक भी सरणियाँ हो सकती हैं, जबकि define()अभी तक सरणियों का समर्थन नहीं करता है। हालांकि, PHP 7 में दोनों मामलों के लिए सरणियों का समर्थन किया जाएगा।

    const FOO = [1, 2, 3];    // Valid in PHP 5.6
    define('FOO', [1, 2, 3]); // Invalid in PHP 5.6 and valid in PHP 7.0

अंत में, ध्यान दें कि constएक वर्ग निरंतर या इंटरफ़ेस को परिभाषित करने के लिए एक वर्ग या इंटरफ़ेस के भीतर भी उपयोग किया जा सकता है। defineइस उद्देश्य के लिए इस्तेमाल नहीं किया जा सकता है:

class Foo {
    const BAR = 2; // Valid
}
// But
class Baz {
    define('QUX', 2); // Invalid
}

सारांश

जब तक आपको किसी भी प्रकार की सशर्त या अभिव्यंजक परिभाषा की आवश्यकता नहीं है, तब तक constएस के बजाय एस का उपयोग करें define()- केवल पठनीयता के लिए!


1
जैसा कि मैं PHP 5.6 के साथ जानता हूं कि आपको constभाषा के निर्माण के साथ भी सरल स्केलर अभिव्यक्ति का उपयोग करने की संभावना मिलेगी
mabe.berlin

6
उपयोग करने का एक और लाभ constउद्धरणों की कमी है, जिसका अर्थ है कि यह वही स्वरूपित है जहां इसका उपयोग आपके आईडीई में किया जाता है।
rybo111

3
यह होना चाहिए क्या PHP डॉक्स में है। यह मैंने देखा सबसे अच्छा विवरण है, विशेष रूप से ज्यादातर लोग भूल जाते हैं (संकलन बनाम रनटाइम)।
जेम्स

4
define('a', $_GET['param']);, const b = a;पूरी तरह से काम करता है और मूल्य हो जाता है, जबकि const c = $_GET['param'];अवैध है। क्या constवास्तव में संकलन समय है? मुझे शायद ही ऐसा लगता है ... (PHP 7.0.7 पर परीक्षण किया गया)
mcserep

1
wiki.php.net/rfc/case_insensitive_constant_deprecation " PHP 8.0 में: केस सेंसिटिव कॉन्स्टेंट घोषित करने की संभावना को दूर करें। " केस सेंसिटिविटी के संबंध में भविष्य में यहां आने वाले किसी अन्य व्यक्ति के लिए
Scuzzy

196

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

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

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

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


12
यह constनामस्थान के साथ उपयोग के लायक हो सकता है ।
सलातो

31
यह भी ध्यान दिया जाना चाहिए कि PHP5.3 वैश्विक दायरे में बहुत अधिक उपयोग कर सकता है।
गॉर्डन

5.2 के रूप में अच्छी तरह से कर सकते हैं। संधि बनाम परिभाषित की सुंदरता यह है कि आपको उन्हें कक्षा के नाम के साथ उपसर्ग करना चाहिए। इनका उपयोग कोड को अधिक पठनीय और सुंदर बनाता है। और यह मेरे लिए एक बोनस है।
आकर्षक

1
@ryeguy लेकिन PHP 5.3 के बाद के बारे में क्या है जहाँ कॉन्स्ट को परिभाषित की तरह ही विश्व स्तर पर इस्तेमाल किया जा सकता है?
औरो

1
@andho, एक-कदम-आगे, एक-कदम-पिछड़े, "सुधार" के नृत्य के PHP नृत्य के लिए एक और चाक करें। वह। :)
प्रो। फालकेन अनुबंध

37

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

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

  • कास्ट को एक अभिव्यक्ति से परिभाषित नहीं किया जा सकता है। const FOO = 4 * 3;काम नहीं करता है, लेकिन define('CONST', 4 * 3);करता है।
  • उस नाम 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। आप अब अभिव्यक्तियों के संदर्भ में const को परिभाषित करने में सक्षम होंगे, बशर्ते कि वे भाव अन्य 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;

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


8
मैं पूछ नहीं सका: क्या आपने जानबूझकर FORTY_TWO54 के रूप में परिभाषित किया है?
पंचलैर्न जूल

9
"सिक्स बाई नौ? फोर्टी टू? मैंने हमेशा कहा कि ब्रह्मांड में मूलभूत रूप से कुछ गड़बड़ थी" डगलस एडम्स के कामों की जाँच करें यदि आपको पूर्ण स्पष्टीकरण की आवश्यकता है।
गॉर्डन

2
ओह। मुझे पता था कि 42 उत्तर जीवन, ब्रह्मांड और सब कुछ है, लेकिन मैंने छह को नौ-भाग से याद किया। स्पष्टीकरण के लिए धन्यवाद!
पंचलैनर्न

22

मेरा मानना ​​है कि 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;
?>

20

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

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

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

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


8
जैसा कि अन्य उत्तरों में कहा गया है, कॉन्स्ट का इस्तेमाल PHP 5.3+
MrWhite

केवल कॉन्स्टेबल कीवर्ड का उपयोग एक नामांकित स्थिरांक बनाने के लिए किया जा सकता है, न केवल कक्षाओं में
अलिर्ज़ा रहमानी खलीली

16

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 वास्तव में इसकी गारंटी नहीं देता है।


1
हाँ, लेकिन BARऔर \foo\BARबस कर रहे हैं नहीं एक ही स्थिरांक। मैं यह वास्तव में भ्रमित कर रहा है इस बात से सहमत है, लेकिन अगर आप भी तरह नेमस्पेसिंग तर्क संगत किया जा रहा है इस तरह बातों पर विचार, और न कि constऔर न ही define()एक सी की तरह है मैक्रो ( #define), तो पीएचपी कोई बहाना हो सकता है।
एस.जे.

1
कास्ट धारणा बिल्कुल वैसा ही है जैसा कि उसे व्यवहार करना चाहिए - आप एक नाम स्थान पर हैं! आप इसे नाम स्थान पहचानकर्ता के बिना चाहते हैं, फिर इसे नामस्थान के बाहर बनाएं .. यह इसे वर्ग में परिभाषित किए जा रहे कॉन्स्टेंट के अनुरूप भी बनाता है, भले ही यह अलग-अलग वाक्यविन्यास का उपयोग करता हो। हां, परिभाषित एक अलग तरीके से भी संगत है।
गेरार्ड ओनिल

12

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

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

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

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

1
PHP> = 5.6 Zend Engine Compiler में कुछ बदलाव किए गए हैं और अब एक अन्य तरीके से const का इलाज किया जा रहा है।
अंकित विश्वकर्मा

6

हां, कॉन्स्टाइल को कंपाइल-टाइम पर परिभाषित किया गया है और जैसा कि nicic स्टेट्स को एक एक्सप्रेशन नहीं दिया जा सकता है, जैसा कि परिभाषित () हो सकता है। लेकिन कॉन्स्टेबल को भी सशर्त घोषित नहीं किया जा सकता (उसी कारण से)। अर्थात। तुम यह नहीं कर सकते:

if (/* some condition */) {
  const WHIZZ = true;  // CANNOT DO THIS!
}

जबकि आप एक परिभाषित () के साथ कर सकते थे। इसलिए, यह वास्तव में व्यक्तिगत पसंद में नहीं आता है, दोनों का उपयोग करने का एक सही और गलत तरीका है।

एक तरफ के रूप में ... मैं कुछ प्रकार के वर्ग कांस्ट देखना चाहूंगा जिसे अभिव्यक्ति प्रदान की जा सकती है, एक प्रकार का परिभाषित () जो कक्षाओं में अलग-थलग किया जा सकता है?


5

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

class Foo {
    const BAR = 1;

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

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


4

Php-doc के बारे में कोई भी कुछ नहीं कहता है, लेकिन मेरे लिए यह प्राथमिकता के लिए एक बहुत महत्वपूर्ण तर्क है const:

/**
 * My foo-bar const
 * @var string
 */
const FOO = 'BAR';

0

परिभाषित कीवर्ड स्थिरांक के साथ, आपको मामले की सुविधाएं असंवेदनशील मिलेंगी लेकिन कॉन्स्टेबल कीवर्ड के साथ आपने नहीं किया।

define("FOO", 1, true);
echo foo; //1
echo "<br/>";
echo FOO; //1
echo "<br/>";

class A {
  const FOO = 1;
}

echo A::FOO; //valid
echo "<br/>";

//but

class B {
  define FOO = 1; //syntax error, unexpected 'define'
}

echo B::FOO; //invalid
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.