পিএইচপি-তে স্ব :: $ বার এবং স্ট্যাটিক :: $ বারের মধ্যে পার্থক্য কী?


125

ব্যবহার মধ্যে পার্থক্য কি selfএবং staticনীচে দেওয়া উদাহরণে?

class Foo
{
    protected static $bar = 1234;

    public static function instance()
    {
        echo self::$bar;
        echo "\n";
        echo static::$bar;
    }

}

Foo::instance();

উত্পাদন করে

1234
1234

2
@ ডেসেজ: এটি একটি অনুরূপ প্রশ্ন, তবে এটি কোনও সদৃশ নয়। এইটি বৈশিষ্ট্য সহ কীওয়ার্ডগুলি ব্যবহার করার বিষয়ে জিজ্ঞাসা করে, যখন এটি কনস্ট্রাক্টরগুলির সাথে তাদের ব্যবহার সম্পর্কে জিজ্ঞাসা করে।
বোল্টক্লক

উত্তর:


191

আপনি যখন selfকোনও শ্রেণীর সদস্যকে উল্লেখ করতে ব্যবহার করেন, আপনি যে শ্রেণীর মধ্যে কীওয়ার্ডটি ব্যবহার করেন সেটির দিকে আপনি উল্লেখ করছেন। এই ক্ষেত্রে, আপনার Fooশ্রেণি কল করা একটি সুরক্ষিত স্থির সম্পত্তি সংজ্ঞা দেয় $bar। আপনি শ্রেণিটি যখন সম্পত্তিটি উল্লেখ করতে ব্যবহার selfকরেন Fooআপনি একই ক্লাসটি উল্লেখ করছেন।

অতএব আপনি যদি self::$barনিজের Fooশ্রেণিতে অন্য কোথাও ব্যবহার করার চেষ্টা করে Barথাকেন তবে সম্পত্তির জন্য আলাদা মান সহ আপনার একটি শ্রেণি থাকে তবে এটি Foo::$barপরিবর্তে ব্যবহার করবে Bar::$bar, যা আপনার উদ্দেশ্য হতে পারে না:

class Foo
{
    protected static $bar = 1234;
}

class Bar extends Foo
{
    protected static $bar = 4321;
}

আপনি যখন কোনও পদ্ধতির মাধ্যমে কল করবেনstatic , আপনি দেরী স্ট্যাটিক বাইন্ডিংস (পিএইচপি 5.3 তে প্রবর্তিত) নামক কোনও বৈশিষ্ট্যটি আহ্বান করছেন ।

উপরের দৃশ্যে, ব্যবহারের selfফলাফল হবে Foo::$bar(1234)। এবং ব্যবহারের staticফলে Bar::$bar(4321) ফলাফল আসবে কারণ এর সাথে static, দোভাষী দের Barসময়কালীন ক্লাসের মধ্যে পুনঃনির্ধারণ বিবেচনা করে ।

আপনি প্রায়শই সাবক্লাসে বৈশিষ্ট্য পুনর্বিবেচনা করেন না বলে বৈশিষ্ট্যগুলির চেয়ে আপনি সাধারণত পদ্ধতিগুলির জন্য এমনকি ক্লাসের জন্যও দেরী স্ট্যাটিক বাইন্ডিং ব্যবহার করেন; staticদেরীতে আবদ্ধ নির্মাণকারীকে অনুরোধ করার জন্য কীওয়ার্ডটি ব্যবহারের একটি উদাহরণ এই সম্পর্কিত প্রশ্নে পাওয়া যাবে: নতুন স্ব বনাম নতুন স্ট্যাটিক

যাইহোক, এটি staticপাশাপাশি বৈশিষ্ট্যগুলি ব্যবহার করেও বিরত থাকে না ।


আপনি খুব সহজেই শিশু শ্রেণিতে পুনরায় ঘোষনা করতে পারেন, পিতামাত্ত শ্রেণি একটি ডিফল্ট মান হতে পারে যা শিশু শ্রেণি তারা পুনরায় ঘোষণা না করে ব্যবহার করে। আপনি যদি প্যারেন্ট ক্লাসে থাকেন তবে আমার ধারণা এটি স্ব :: ব্যবহার করা নিরাপদ: এবং যদি কোনও শিশু শ্রেণিতে থাকে তবে আপনি দুটি ব্যবহার করার পক্ষে যুক্তি প্রকাশ করতে পারেন তবে স্ব :: :: আপনি যদি আশা না করেন তবে কাজ করবে কখনও ঘোষণা করুন।
অ্যান্ড্রু

3
যেতে phpfiddle.org এবং এই রান<?php class Foo { public static $bar = 1234; public static function a( ) { echo 'static'.static::$bar; echo 'self'.self::$bar; } } class Bar extends Foo { public static $bar = 4321; } (new Bar())->a(); ?>
ইয়েভগেনি Afanasyev

2
প্রথম দুটি অনুচ্ছেদের শব্দটি বিভ্রান্তিকর, একটি দ্ব্যর্থক সর্বনাম, "এটি" রয়েছে এবং এটি আবারও পুনরুত্থান, কারণ পরবর্তী অনুচ্ছেদে একই তথ্য আরও পরিষ্কারভাবে ব্যাখ্যা করা হয়েছে। আমি প্রথম দুটি অনুচ্ছেদের পরিবর্তে উপরের "উপরের দৃশ্যে" দিয়ে শুরু হওয়া পরবর্তী অনুচ্ছেদের সাথে প্রতিস্থাপন করার পরামর্শ দিচ্ছি। এই ভাবে নীচের লাইনটি, কাট-টু-চেজ উত্তরটি শীর্ষে রয়েছে। এটি পরিষ্কার এবং অনুসরণ করা সহজ।
আহ্নবিজক্যাড

আরেকটি উপায় এই চিন্তা করুন: self::$abcপ্রয়োজনে ব্যবহৃত ভিতরে class Fooবলছে হিসাবে একই Foo::$abc। এটি $abcএকটি সাবক্লাসে পুনরায় ঘোষণার দ্বারা প্রভাবিত হবে না । আফাইক, selfশ্রেণীর নাম ব্যবহার করা এড়াতে, সংক্ষিপ্তকরণ হিসাবে ব্যবহারের একমাত্র কারণ, এটি আরও Fooদীর্ঘ হতে পারে। [এর অর্থ হ'ল আপনি এই সমস্ত জায়গাগুলি পরিবর্তন না করেই ক্লাসের নাম পরিবর্তন করতে পারেন - তবে এটি আইএমএইচও-র কারণ হিসাবে খুব বেশি কিছু নয়]] (পিএইচপি-র নাম পছন্দ করা দুর্ভাগ্যজনক এবং পেছনের দিকে মনে হয়; "স্থির" এটিই বদলে যেতে পারে - যা প্রাকৃতিক-ভাষা শব্দের "স্থিতিশীল" শব্দের অর্থের বিপরীতে))
টুলমেকারস্টিভ

4

যেমন উল্লেখ করা হয়েছে তার মধ্যে অন্যতম প্রধান পার্থক্য হ'ল staticদেরিতে স্থির বাইন্ডিংয়ের জন্য অনুমতি দেয়। আমি যে সর্বাধিক দরকারী দৃশ্যের সন্ধান পেয়েছি তা হ'ল সিঙ্গলটন ক্লাসের জন্য বেস ক্লাস তৈরির জন্য:

class A { // Base Class
    protected static $name = '';
    protected static function getName() {
        return static::$name;
    }
}
class B extends A {
    protected static $name = 'MyCustomNameB';
}
class C extends A {
    protected static $name = 'MyCustomNameC';
}

echo B::getName(); // MyCustomNameB
echo C::getName(); // MyCustomNameC

return static::$nameবেস শ্রেণিতে ব্যবহার করে প্রসারিত হওয়ার পরে যা স্থিরভাবে সংযুক্ত ছিল তা ফিরে আসবে। আপনি যদি ব্যবহার করতে চান return self::$nameতবে B::getName()বেস ক্লাসে যেমন ঘোষণা করা হয়েছিল তেমন একটি খালি স্ট্রিং ফিরে আসবে।


0

সঙ্গে selfকল:

class Foo
{
    protected static $var = 123;
    
    public function getVar()
    {
        return self::$var;
    }
}

class Bar extends Foo
{
    protected static $var = 234;
}

// Displays: "123"
echo (new Bar)->getVar();

আপনি উপরে দেখতে পারেন, যদিও আমরা $varআমাদের Barক্লাসটি দিয়ে ওভাররাইড করে দিয়েছি , এটি এখনও ফিরে আসে 123, কারণ আমরা স্পষ্টভাবে পিএইচপি selfভেরিয়েবলের জন্য জিজ্ঞাসা করেছি , যার Fooপরিবর্তে এর পরিবর্তকের জন্য জিজ্ঞাসা করা হয়।

এখন যদি আমরা কলটি অদলবদল করি তবে আমরা এর staticপরিবর্তে Barএর ওভাররাইড মানটি পেয়ে যাব :

সঙ্গে staticকল:

class Foo
{
    protected static $var = 123;
    
    public function getVar()
    {
        return static::$var;
    }
}

class Bar extends Foo
{
    protected static $var = 234;
}

// Displays: "234"
echo (new Bar)->getVar();
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.