PHP में, आप कब उपयोग करते हैं
define('FOO', 1);
और आप कब उपयोग करते हैं
const FOO = 1;
?
उन दो के बीच मुख्य अंतर क्या हैं?
PHP में, आप कब उपयोग करते हैं
define('FOO', 1);
और आप कब उपयोग करते हैं
const FOO = 1;
?
उन दो के बीच मुख्य अंतर क्या हैं?
जवाबों:
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 validconstएक सादा स्थिर नाम लेता है, जबकि 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()- केवल पठनीयता के लिए!
constभाषा के निर्माण के साथ भी सरल स्केलर अभिव्यक्ति का उपयोग करने की संभावना मिलेगी
constउद्धरणों की कमी है, जिसका अर्थ है कि यह वही स्वरूपित है जहां इसका उपयोग आपके आईडीई में किया जाता है।
define('a', $_GET['param']);, const b = a;पूरी तरह से काम करता है और मूल्य हो जाता है, जबकि const c = $_GET['param'];अवैध है। क्या constवास्तव में संकलन समय है? मुझे शायद ही ऐसा लगता है ... (PHP 7.0.7 पर परीक्षण किया गया)
PHP 5.3 तक, constवैश्विक दायरे में उपयोग नहीं किया जा सकता था। आप इसे केवल एक वर्ग के भीतर से ही उपयोग कर सकते हैं। इसका उपयोग तब किया जाना चाहिए जब आप किसी प्रकार का निरंतर विकल्प सेट करना चाहते हैं या उस वर्ग से संबंधित होते हैं। या हो सकता है कि आप किसी तरह का एनम बनाना चाहते हों।
defineएक ही उद्देश्य के लिए इस्तेमाल किया जा सकता है, लेकिन यह केवल वैश्विक दायरे में इस्तेमाल किया जा सकता है। इसका उपयोग केवल वैश्विक सेटिंग्स के लिए किया जाना चाहिए जो संपूर्ण एप्लिकेशन को प्रभावित करते हैं।
अच्छे constउपयोग का एक उदाहरण जादू की संख्या से छुटकारा पाना है। पीडीओ के स्थिरांक पर एक नज़र डालें । जब आपको एक भ्रूण प्रकार निर्दिष्ट करने की आवश्यकता होती है, तो आप PDO::FETCH_ASSOCउदाहरण के लिए टाइप करेंगे । यदि const का उपयोग नहीं किया गया था, तो आप कुछ टाइप करना चाहेंगे 35(या जो कुछ भी FETCH_ASSOCपरिभाषित किया गया है)। इससे पाठक को कोई मतलब नहीं है।
अच्छे defineउपयोग का एक उदाहरण शायद आपके एप्लिकेशन के रूट पथ या लाइब्रेरी के संस्करण नंबर को निर्दिष्ट कर रहा है।
constनामस्थान के साथ उपयोग के लायक हो सकता है ।
मुझे पता है कि यह पहले से ही उत्तर दिया गया है, लेकिन वर्तमान उत्तरों में से कोई भी नाम स्थान का कोई उल्लेख नहीं करता है और यह कैसे स्थिरांक और परिभाषित को प्रभावित करता है।
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;
अभी भी बाहर हो जाएगा।
FORTY_TWO54 के रूप में परिभाषित किया है?
मेरा मानना है कि 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 मैं वैश्विक स्थिरांक के लिए उपयोग करता हूं।
const मैं कक्षा स्थिरांक के लिए उपयोग करता हूं।
आप defineवर्ग के दायरे में नहीं आ सकते , और constआप कर सकते हैं। कहने की जरूरत नहीं है, आप constबाहरी वर्ग के दायरे का उपयोग नहीं कर सकते ।
इसके साथ const, यह वास्तव में वर्ग का सदस्य बन जाता है, और इसके साथ define, इसे वैश्विक दायरे में धकेल दिया जाएगा।
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 वास्तव में इसकी गारंटी नहीं देता है।
BARऔर \foo\BARबस कर रहे हैं नहीं एक ही स्थिरांक। मैं यह वास्तव में भ्रमित कर रहा है इस बात से सहमत है, लेकिन अगर आप भी तरह नेमस्पेसिंग तर्क संगत किया जा रहा है इस तरह बातों पर विचार, और न कि constऔर न ही define()एक सी की तरह है मैक्रो ( #define), तो पीएचपी कोई बहाना हो सकता है।
इनमें से अधिकांश उत्तर गलत हैं या केवल आधी कहानी कह रहे हैं।
उदाहरण के लिए:
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
हां, कॉन्स्टाइल को कंपाइल-टाइम पर परिभाषित किया गया है और जैसा कि nicic स्टेट्स को एक एक्सप्रेशन नहीं दिया जा सकता है, जैसा कि परिभाषित () हो सकता है। लेकिन कॉन्स्टेबल को भी सशर्त घोषित नहीं किया जा सकता (उसी कारण से)। अर्थात। तुम यह नहीं कर सकते:
if (/* some condition */) {
const WHIZZ = true; // CANNOT DO THIS!
}
जबकि आप एक परिभाषित () के साथ कर सकते थे। इसलिए, यह वास्तव में व्यक्तिगत पसंद में नहीं आता है, दोनों का उपयोग करने का एक सही और गलत तरीका है।
एक तरफ के रूप में ... मैं कुछ प्रकार के वर्ग कांस्ट देखना चाहूंगा जिसे अभिव्यक्ति प्रदान की जा सकती है, एक प्रकार का परिभाषित () जो कक्षाओं में अलग-थलग किया जा सकता है?
NikiC के उत्तर पर जोड़ने के लिए। constनिम्न तरीकों से कक्षाओं के भीतर इस्तेमाल किया जा सकता है:
class Foo {
const BAR = 1;
public function myMethod() {
return self::BAR;
}
}
आप इसके साथ नहीं कर सकते define()।
Php-doc के बारे में कोई भी कुछ नहीं कहता है, लेकिन मेरे लिए यह प्राथमिकता के लिए एक बहुत महत्वपूर्ण तर्क है const:
/**
* My foo-bar const
* @var string
*/
const FOO = 'BAR';
परिभाषित कीवर्ड स्थिरांक के साथ, आपको मामले की सुविधाएं असंवेदनशील मिलेंगी लेकिन कॉन्स्टेबल कीवर्ड के साथ आपने नहीं किया।
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
constकी तुलना में दो गुना तेज हैdefine। पृष्ठ लोड समय और मेमोरी उपयोग के बारे में: इस प्रश्न और इस लेख को देखें ... यहाँ भी opcode कैश के बारे में कुछ देखें ।