একটি ক্লাসের ভিতরে একটি স্ট্যাটিক পদ্ধতি কল?


166

একই শ্রেণীর অভ্যন্তরে অন্য পদ্ধতি থেকে আমি একটি স্থিতিশীল পদ্ধতিটি কীভাবে কল করব?

$this->staticMethod();

অথবা

$this::staticMethod();

13
আপনার এটি আগ্রহী হতে পারে ( selfবনাম $this): স্ট্যাকওভারফ্লো
ফেলিক্স ক্লিং

কেবলমাত্র একটি এফওয়াইআই, আপনার প্রথম উদাহরণটি হ'ল একটি স্থিতিশীল পদ্ধতিটিকে কল করা উদাহরণস্বরূপ ভেরিয়েবল যা কোনও স্ট্যাটিক পদ্ধতি শ্রেণীর অংশ এবং একটি উদাহরণ ভেরিয়েবলের মাধ্যমে অ্যাক্সেসযোগ্য নয় possible
জোজেসন

আপনি এটি মুছে ফেলতে পারেন now এটি এখন কাজ করে না যদি কেবল স্থির পদ্ধতি ব্যবহার করে এবং কোনও উদাহরণ উপস্থিত না থাকে।
মালহাল

উত্তর:


321

...কিন্তু কেন? $ এটি-> স্ট্যাটিকমেথড ()ও কাজ করে। আপনি কী ব্যাখ্যা করতে পারেন যে স্ব :: স্ট্যাটিক মেথড () আরও সঠিক (যদি তা হয়)?
আয়ান ডান

29
@ আইয়ান ডান পুট কেবলমাত্র $thisতখনই উপস্থিত থাকে যদি কোনও বস্তু তাত্ক্ষণিকভাবে চালিত হয়ে থাকে এবং আপনি কেবলমাত্র $this->methodবিদ্যমান অবজেক্টের মধ্যে থেকে ব্যবহার করতে পারেন । আপনার যদি কোনও অবজেক্ট না থাকে তবে কেবল একটি স্ট্যাটিক পদ্ধতি কল করুন এবং সেই পদ্ধতিতে আপনি একই শ্রেণিতে অন্য স্ট্যাটিক পদ্ধতিতে কল করতে চান, আপনাকে ব্যবহার করতে হবে self::। সুতরাং সম্ভাব্য ত্রুটিগুলি এড়াতে (এবং কঠোর সতর্কতা) ব্যবহার করা ভাল self
jeroen

1
ধন্যবাদ! লারাভেলে, আমি দেখতে পেলাম যে আমি দুর্ঘটনাক্রমে একটি বর্ধিত নিয়ামক ব্যবহার করে স্থির পদ্ধতিটি কল করে যাচ্ছিলাম $this, তবে কোডটি ধাক্কা না দেওয়া পর্যন্ত সমস্যাটি তলিয়ে গেল না stage। কোনও ত্রুটি ফিরে আসেনি, মানটি ছিল ঠিক 0self::
এটির

44

ধরে নেওয়া যাক এটি আপনার শ্রেণি:

class Test
{
    private $baz = 1;

    public function foo() { ... }

    public function bar() 
    {
        printf("baz = %d\n", $this->baz);
    }

    public static function staticMethod() { echo "static method\n"; }
}

foo()পদ্ধতির মধ্যে থেকে , আসুন বিভিন্ন বিকল্পগুলি দেখুন:

$this->staticMethod();

সুতরাং যে staticMethod()একটি উদাহরণ পদ্ধতি হিসাবে কল , ডান? এটা না. এটি হ'ল কারণ পদ্ধতিটি public staticদোভাষী হিসাবে ঘোষিত হয়েছে এটি এটিকে একটি স্ট্যাটিক পদ্ধতি হিসাবে ডাকে তাই এটি প্রত্যাশার মতো কাজ করবে। এটি যুক্তিযুক্ত হতে পারে যে এটি করা কোড থেকে স্ট্যাটিক পদ্ধতি কলটি ঘটছে তা কম স্পষ্ট হয়।

$this::staticMethod();

পিএইচপি 5.3 যেহেতু $var::method()আপনি অর্থ ব্যবহার করতে পারেন <class-of-$var>::; এটি বেশ সুবিধাজনক, যদিও উপরের ব্যবহার-কেসটি এখনও বেশ প্রচলিত। সুতরাং এটি আমাদের কাছে স্থিতিশীল পদ্ধতি কল করার সর্বাধিক সাধারণ উপায়ে নিয়ে আসে:

self::staticMethod();

এখন, আগে আপনি চিন্তা যে শুরু ::হয় স্ট্যাটিক কল অপারেটর, আমাকে আপনি অন্য একটি উদাহরণ দিতে যাক:

self::bar();

এটি মুদ্রণ করবে baz = 1, যার অর্থ $this->bar()এবং self::bar()ঠিক একই জিনিসটি করা; কারণ ::এটি কেবল একটি স্কোপ রেজোলিউশন অপারেটর। কিন্তু সেখানে করতে এর parent::, self::এবং static::কাজ করতে এবং আপনার স্ট্যাটিক ভেরিয়েবল অ্যাক্সেস দিতে; কীভাবে একটি পদ্ধতি বলা হয় তার স্বাক্ষর এবং কীভাবে কলকারীকে ডাকা হত তার উপর নির্ভর করে।

এই সমস্ত কর্মে দেখতে, এই 3v4l.org আউটপুটটি দেখুন


self::bar()বিভ্রান্তিকর বলে মনে হচ্ছে - এটি কি এখন অবহেলিত? ( self::স্থির পদ্ধতির চেয়ে ইনস্ট্যান্স পদ্ধতিতে কল করতে ব্যবহার করে )।
টুলমেকারস্টেভ

@ টুলমেকারস্টেভ কীভাবে আপনি বলবেন যে এটি বিভ্রান্তিকর?
জ্যাক

যৌক্তিকভাবে বলতে গেলে, কোনও selfস্থির পদ্ধতি চালু করার সময় কোনও কিছুই নেই । সংজ্ঞা অনুসারে: স্থির পদ্ধতিটি যে কোনও জায়গা থেকে কলযোগ্য এবং কোনও "স্ব" পরামিতি গ্রহণ করে না। তবুও, আমি সেই phpবাক্য গঠনটির সুবিধার্থটি দেখছি , যাতে আপনাকে লিখতে না হয় MyClassName::। আমি স্ট্যাটিকালি-টাইপ করা ভাষাগুলিতে অভ্যস্ত, যেখানে সংকলকটি বর্তমান স্কোপগুলিতে উপলব্ধ সমস্ত ভেরিয়েবলগুলি দিতে হবে, যাতে (সমতুল্য) self::বাদ দেওয়া যায়। তাই একজন কেবল বলেছিলেন self instanceMethod; বলার কোন কারণ নেই self staticMethod
টুলমেকারস্টেভ

15

এটি খুব দেরিতে প্রতিক্রিয়া, তবে পূর্ববর্তী উত্তরগুলিতে কিছু বিশদ যুক্ত করেছে

যখন একই ক্লাসের অন্য স্ট্যাটিক পদ্ধতি থেকে পিএইচপি-তে স্থিতিশীল পদ্ধতিগুলি কল করার কথা আসে, selfতখন শ্রেণীর নাম এবং শ্রেণীর নামের মধ্যে পার্থক্য করা গুরুত্বপূর্ণ ।

উদাহরণস্বরূপ এই কোডটি নিন:

class static_test_class {
    public static function test() {
        echo "Original class\n";
    }

    public static function run($use_self) {
        if($use_self) {
            self::test();
        } else {
            $class = get_called_class();
            $class::test(); 
        }
    }
}

class extended_static_test_class extends static_test_class {
    public static function test() {
        echo "Extended class\n";
    }
}

extended_static_test_class::run(true);
extended_static_test_class::run(false);

এই কোডের আউটপুট হল:

আসল ক্লাস

বর্ধিত শ্রেণি

selfকোডটি যে শ্রেণীর কোড থেকে কল করা হচ্ছে তার পরিবর্তে কোডটি শ্রেণিতে থাকে বলে বোঝানো হয়।

আপনি যদি ক্লাসে সংজ্ঞায়িত পদ্ধতিটি ব্যবহার করতে চান যা মূল শ্রেণীর উত্তরাধিকার সূত্রে আসে, আপনার এমন কিছু ব্যবহার করা দরকার:

$class = get_called_class();
$class::function_name(); 

2
আমি এই তথ্যপূর্ণ খুঁজে পেয়েছি। একটি ছোট্ট নাইট, আমি এটি বলব না যে অন্যান্য উত্তরগুলি "বিভ্রান্তিমূলক"। আরও সঠিকভাবে বলা যায় যে তারা "অসম্পূর্ণ"; তারা self::(বিরল) ক্ষেত্রে কী করে সে বিষয়ে (অনস্ক্রিত) প্রশ্নের সমাধান করে না যেখানে কোনও স্ট্যাটিক পদ্ধতি এটিকে অন্য স্ট্যাটিক পদ্ধতি বি বলে, এবং বি একটি সাবক্লাসে ওভাররাইড করা হয়েছে। আইএমএইচও, "উদাহরণস্বরূপ" পদ্ধতিগুলিতে মেথড্রাইটিং পদ্ধতি সীমাবদ্ধ করা কম বিভ্রান্তিকর; স্থিতিশীল পর্যায়ে অল্প পরিমাণে সেই ক্ষমতাটি ব্যবহার করুন। এটিকে অন্য উপায়ে দিন, আপনার কোডের পাঠকরা উদাহরণের পদ্ধতিগুলির ওভাররাইডিং পদ্ধতিটি প্রত্যাশা করেন (এটি ওও কোডিংয়ের মূল বিষয়) তবে স্থির নয়।
টুলমেকারস্টেভ

1
খুব সহায়ক এবং এটি বোধগম্য হয় যে ক্লাসের একটি বর্ধন মূল ক্লাস নয়। সুতরাং এটি যুক্তিতে দাঁড়িয়েছে যে selfসেই ক্ষেত্রে ব্যবহৃত হবে না। আপনি প্রথম শ্রেণিতে এক্সটেনশন হিসাবে একটি পৃথক শ্রেণির ঘোষণা করেছেন। selfবর্ধিত শ্রেণীর মধ্যে ব্যবহার করে বর্ধিত শ্রেণীর উল্লেখ করা হবে। এটি অন্যান্য উত্তরগুলির সাথে বিরোধিতা করে না, তবে এটি অবশ্যই এর ব্যাপ্তি প্রদর্শন করতে সহায়তা করে self
আইরিন

2

পরবর্তী পিএইচপি সংস্করণেও self::staticMethod();কাজ করবে না। এটি কঠোর স্ট্যান্ডার্ড ত্রুটি নিক্ষেপ করবে।

এই ক্ষেত্রে, আমরা একই শ্রেণীর অবজেক্ট তৈরি করতে পারি এবং বস্তুর মাধ্যমে কল করতে পারি

এখানে উদাহরণ

class Foo {

    public function fun1() {
        echo 'non-static';   
    }

    public static function fun2() {
        echo (new self)->fun1();
    }
}

আপনি এটি করতে পারেন, যদিও এটি fun1ব্যবহার না করে থাকলেও selfএটি একটি উদাহরণ পদ্ধতি তৈরি করা যৌক্তিক নয়। পিএইচপি এই কাজ করতে সঠিক ভাবে ঘোষণা করা হয় public static function fun1, তারপর বর্গ নির্দিষ্ট করে কল: Foo::fun1। আমি নিশ্চিত যে কঠোর স্ট্যান্ডার্ড ত্রুটিটি ঠিক করার উদ্দেশ্যে এটি way
টুলমেকারস্টেভ
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.