সংজ্ঞায়িত () বনাম


658

পিএইচপি-তে, আপনি কখন ব্যবহার করবেন

define('FOO', 1);

এবং আপনি কখন ব্যবহার করবেন?

const FOO = 1;

?

এই দুজনের মধ্যে প্রধান পার্থক্য কী?


4
কর্মক্ষমতা সম্পর্কে (আমার হিসাবে মাইক্রো-অপ্টিমাইজেশানের সাথে সময়ের অপচয়), এই উত্তরটি দেখুন : এর constচেয়ে দ্বিগুণ দ্রুত define। পৃষ্ঠা লোড সময় এবং মেমরির ব্যবহার সম্পর্কে: এই প্রশ্নটি এবং এই নিবন্ধটি দেখুন ... অপকোড ক্যাশে সম্পর্কেও এখানে দেখুন
পিটার ক্রাউস

2
শুধুমাত্র বর্তমান গৃহীত উত্তর তাকান না, কিন্তু দয়া করে করার জন্য একটি কটাক্ষপাত stackoverflow.com/a/3193704/1412157 গৃহীত উত্তর যেমন হওয়া উচিত ছিল
LucaM

1
সবেমাত্র আপনার মন্তব্যের জন্য বিজ্ঞপ্তিটি দেখেছেন। আমি গৃহীত উত্তর আপডেট করেছি।
দাঞ্জারভিস

উত্তর:


1038

পিএইচপি 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()কোনো অভিব্যক্তি লাগে। যেহেতু পিএইচপি 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);
    }
    
  • constগুলি সর্বদা ক্ষেত্রে সংবেদনশীল থাকে, তবে তৃতীয় যুক্তি হিসাবে define()পাস করে আপনি কেস সংবেদনশীল ধ্রুবককে সংজ্ঞায়িত করতে দেয় true(দ্রষ্টব্য: কেস-সংবেদনশীল ধ্রুবকগুলির সংজ্ঞা পিএইচপি 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');
    
  • যেহেতু পিএইচপি 5.6 constধ্রুবকগুলিও অ্যারে হতে পারে, তবে define()এখনও অ্যারে সমর্থন করে না। তবে, পিএইচপি 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()s এর পরিবর্তে s ব্যবহার করুন - কেবল পঠনযোগ্যতার জন্য!


1
আমি পিএইচপি 5.6 সঙ্গে কি জানেন আপনি এমনকি সহজ স্কালে এক্সপ্রেশন ব্যবহার করতে সম্ভাবনা পাবেন constভাষা কনস্ট্রাক্ট - দেখুন wiki.php.net/rfc/const_scalar_exprs
mabe.berlin

6
ব্যবহারের আরেকটি সুবিধা constহ'ল উদ্ধৃতিগুলির অভাব, যার অর্থ এটি যেখানে আপনার আইডিইতে ব্যবহৃত হয় সেখানে একই ফর্ম্যাট করা হয়।
rybo111

3
এটি পিএইচপি ডক্সে থাকা উচিত। এটি আমি দেখেছি সেরা ব্যাখ্যা, বিশেষত যে অংশটি বেশিরভাগ লোক ভুলে যায় (বনাম রানটাইম সংকলন)।
জেমস

4
define('a', $_GET['param']);, const b = a;পুরোপুরি কাজ করে এবং const c = $_GET['param'];অবৈধ থাকাকালীন মানটি পায় । কি constসত্যিই কম্পাইল সময়? আমি খুব কমই মনে করি ... (পিএইচপি 7.0.7 এ পরীক্ষিত)
এমসিসেরেপ

1
wiki.php.net/rfc/ কেস_ সংবেদনশীল_ কনস্ট্যান্ট_ড্রেসেকশন " পিএইচপি ৮.০-তে: কেস-সংবেদনশীল স্থিরতা ঘোষণা করার সম্ভাবনাটি সরিয়ে দিন। " কেস সংবেদনশীলতার ক্ষেত্রে ভবিষ্যতে অন্য কারও পক্ষে এই
উদ্যোগ ঘটাচ্ছেন

196

পিএইচপি 5.3 অবধি constবিশ্বব্যাপী সুযোগে ব্যবহার করা যায়নি। আপনি কেবল এটি ক্লাসের মধ্যে থেকেই ব্যবহার করতে পারেন। আপনি যখন কোনও ধরণের ধ্রুবক বিকল্প সেট করতে চান বা শ্রেণীর সাথে সম্পর্কিত সেটিংস সেট করতে চান তখন এটি ব্যবহার করা উচিত। অথবা হতে পারে আপনি কোনও রকম এনাম তৈরি করতে চান।

defineএকই উদ্দেশ্যে ব্যবহার করা যেতে পারে, তবে এটি কেবল বৈশ্বিক সুযোগে ব্যবহার করা যেতে পারে। এটি কেবলমাত্র বিশ্বব্যাপী সেটিংসের জন্য ব্যবহার করা উচিত যা পুরো অ্যাপ্লিকেশনকে প্রভাবিত করে।

constজাদু সংখ্যা থেকে মুক্তি পাওয়া ভাল ব্যবহারের একটি উদাহরণ । কটাক্ষপাত PDO এর ধ্রুবক । যখন আপনাকে একটি ফেচ প্রকার নির্দিষ্ট করতে হবে, আপনি PDO::FETCH_ASSOCউদাহরণস্বরূপ টাইপ করবেন । কনসেন্ট ব্যবহার না করা হলে আপনি কিছু 35(বা যা FETCH_ASSOCহিসাবে সংজ্ঞায়িত করা হয়েছে) টাইপ করে শেষ করবেন । এটি পাঠকের কাছে কোনও ধারণা রাখে না।

ভাল defineব্যবহারের একটি উদাহরণ সম্ভবত আপনার অ্যাপ্লিকেশনটির মূল পাথ বা একটি লাইব্রেরির সংস্করণ নম্বর উল্লেখ করছে।


12
এটি constনেমস্পেসের সাথে ব্যবহারের উল্লেখযোগ্য হতে পারে ।
সালাতে

31
এটিও লক্ষ করা উচিত যে পিএইচপি 5.3 বিশ্বব্যাপী সুযোগগুলিতে খুব বেশি ব্যবহার করতে পারে।
গর্ডন 19

5.2 পাশাপাশি করতে পারেন। বনাম বনাম সংজ্ঞায়িত করা সৌন্দর্যটি হ'ল আপনাকে অবশ্যই তাদের শ্রেণির নামের সাথে উপসর্গ করতে হবে। এগুলি ব্যবহার করা কোডকে আরও পঠনযোগ্য এবং সুন্দর করে তোলে। এবং এটি আমার জন্য বোনাস।
লাভজনক

1
@ryeguy তবে পিএইচপি 5.3 এর পরে কী হবে যেখানে বিশ্বব্যাপী কনস্ট সংজ্ঞায়নের মতো ব্যবহার করা যায়?
andho

1
@ এবং, পিএইচপি নাচকে আরও এক পদে এগিয়ে চলো, এক ধাপ এগিয়ে, "উন্নতি" এর নৃত্য to তিনি। :)
অধ্যাপক ফ্যালকেন চুক্তি

37

আমি জানি এটি ইতিমধ্যে উত্তর দেওয়া হয়েছে, তবে বর্তমানের উত্তরগুলির কোনওরই নামস্পেসিংয়ের কোনও উল্লেখ করা হয়নি এবং কীভাবে এটি ধ্রুবকগুলিকে প্রভাবিত করে এবং সংজ্ঞায়িত করে।

পিএইচপি 5.3 হিসাবে, কনসেট এবং সংজ্ঞা বেশিরভাগ ক্ষেত্রে একই রকম similar এখনও কিছু গুরুত্বপূর্ণ পার্থক্য রয়েছে:

  • অনুভূতিগুলি কোনও অভিব্যক্তি থেকে সংজ্ঞায়িত করা যায় না। 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]

=== আপডেট ===

আসন্ন পিএইচপি 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;

এখনও বাইরে থাকবে।


8
আমি জিজ্ঞাসা করতে বাধা দিতে পারিনি: আপনি কি সচেতনভাবে FORTY_TWO54 হিসাবে সংজ্ঞায়িত করেছেন?
পাঁচলনার্ন

9
"ছয় বাই নয়? বাহাত্তর? আমি সর্বদা বলেছিলাম মহাবিশ্বের সাথে মূলত কিছু ভুল ছিল" আপনার যদি পূর্ণ বিবরণ প্রয়োজন হয় তবে ডগলাস অ্যাডামসের কাজগুলি দেখুন।
গর্ডনএম

2
উহু. আমি অবগত ছিলাম যে 42 উত্তর জীবন, মহাবিশ্ব এবং সমস্ত কিছুই কিন্তু আমি ছয়টি নয়টি অংশকে মিস করেছি। ব্যাখ্যার জন্য ধন্যবাদ!
পাঁচলনার্ন

22

আমি বিশ্বাস করি যে পিএইচপি 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
অন্যান্য
উত্তরে

নাম ধীরে ধীরে ধীরে ধীরে তৈরি করতে কেবল কনস্টের শব্দটিই ব্যবহার করা যেতে পারে, কেবল
ক্লাসই

16

নিকিসির উত্তরটি সর্বোত্তম, তবে নেমস্পেসগুলি ব্যবহার করার সময় আমাকে একটি অ-স্পষ্টত ক্যাভিয়েট যুক্ত করতে দিন যাতে আপনি অপ্রত্যাশিত আচরণের সাথে আবদ্ধ না হন। মনে রাখার বিষয়টি হ'ল সংজ্ঞাটি সর্বদা বিশ্বব্যাপী নেমস্পেসে থাকে যদি না আপনি সংজ্ঞায়িত শনাক্তকারীর অংশ হিসাবে স্পষ্টভাবে নেমস্পেস যোগ করেন। যা সম্পর্কে স্পষ্ট নয় তা হ'ল নেমস্পিড শনাক্তকারী গ্লোবাল সনাক্তকারীকে ট্রাম্প করে। সুতরাং:

<?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

আমার কাছে কোনটি সম্পূর্ণ কনস্টিটিউশনকে অযৌক্তিকভাবে বিভ্রান্ত করে তোলে যেহেতু কয়েক ডজন অন্যান্য ভাষায় কনস্টের ধারণাটি হ'ল আপনি নিজের কোডটিতে যেখানেই থাকুন না কেন সর্বদা একই থাকে এবং পিএইচপি সত্যিই এর নিশ্চয়তা দেয় না।


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
পিএইচপি> = 5.6 জেন্ড ইঞ্জিন সংকলকটিতে কিছু পরিবর্তন করা হয়েছে এবং কনস্টকে এখন অন্যভাবে আচরণ করা হচ্ছে।
অঙ্কিত বিশ্বকর্মা

6

হ্যাঁ, কমপাইলটি সংকলন-সময়ে সংজ্ঞায়িত করা হয়েছে এবং নিকিক রাজ্যগুলিকে একটি এক্সপ্রেশন নির্ধারণ করা যাবে না, যেমন () এর সংজ্ঞা দেওয়া যেতে পারে। তবে কনস্টের শর্তসাপেক্ষে ঘোষণা করা যাবে না (একই কারণে)। অর্থাত। আপনি এটা করতে পারেন না:

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

পিএইচপি-ডক সম্পর্কে কেউ কিছু বলে না, তবে আমার পক্ষে এটিও পছন্দটির পক্ষে খুব গুরুত্বপূর্ণ যুক্তি 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
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.