পিএইচপি-তে স্থির স্থির বাইন্ডিংগুলি আসলে কী?


উত্তর:


198

আপনাকে অবশ্যই পিএইচপি ম্যানুয়ালটিতে লেট স্ট্যাটিক বাইন্ডিংগুলি পড়তে হবে । তবে, আমি আপনাকে একটি দ্রুত সংক্ষিপ্তসার দেওয়ার চেষ্টা করব।

মূলত, এটি মূলত উত্সাহিত করে যে মূল selfশব্দটি উত্তরাধিকারের একই নিয়ম অনুসরণ করে না। selfসর্বদা এটি ব্যবহৃত ক্লাসে সমাধান হয়। এর অর্থ হ'ল আপনি যদি পিতামাতা ক্লাসে কোনও পদ্ধতি তৈরি করেন এবং শিশু শ্রেণি থেকে কল করেন তবে selfআপনার প্রত্যাশার সাথে সন্তানের উল্লেখ করা হবে না।

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

এর পিছনে দুটি মূল ধারণা। পথ self, parentএবং staticঅপারেট যখন staticখেলা হয় সূক্ষ্ম, তাই বদলে আরো বিস্তারিত কাছে যাও হতে পারে, আমি দৃঢ়ভাবে বলতে চাই যে আপনি যদি ম্যানুয়াল পৃষ্ঠা উদাহরণ অধ্যয়ন। একবার আপনি প্রতিটি কীওয়ার্ডের বেসিকগুলি বুঝতে পারলে, আপনি কী ধরণের ফলাফল পেতে চলেছেন তা উদাহরণগুলি দেখতে বেশ প্রয়োজনীয়।


আমি এই নিবন্ধটি সত্যিই দরকারী এবং বর্ণনামূলক পেয়েছি, এটি [লিংক] দেখুন ( টেকফ্লার্ট / টিউটোরিয়ালস / আওপ-ইন- php / late-static-b बाइंड। html )
সাদেঘ শাইখি

"... selfকীওয়ার্ড উত্তরাধিকারের নিয়মগুলি অনুসরণ করে না selfalways সর্বদা এটি ব্যবহৃত ক্লাসে সমাধান হয়" " - যার অর্থ এই নয় যে আপনি স্থির selfনন-স্ট্যাটিক পদ্ধতিগুলির মতো বাচ্চাদের কোনও আইটেমের মাধ্যমে পিতামাতার স্ট্যাটিক পদ্ধতিতে কল করতে পারবেন না । আপনি সম্ভবত সঠিক জিনিসটি বোঝাতে চাইছেন তবে আপনার এটি পুনরায় বাক্যটি বলা উচিত। একবার শিশু অভিন্নরুপে সদস্যদের নামে আছে যেহেতু আপনি তারপর সিদ্ধান্ত নিতে পারেন কোনটি ব্যবহার করে উল্লেখ করতে এটা সব শুধুমাত্র সত্যিই গুরুত্বপূর্ণ static::পরিবর্তে।
ড্যানম্যান

81

পিএইচপি থেকে : লেট স্ট্যাটিক বাইন্ডিংস - ম্যানুয়াল :

পিএইচপি 5.3.0 হিসাবে, পিএইচপি স্থির স্থায়ী বাঁধন নামে একটি বৈশিষ্ট্য প্রয়োগ করে যা স্থির উত্তরাধিকারের প্রেক্ষাপটে তথাকথিত শ্রেণিকে রেফারেন্স করতে ব্যবহার করা যেতে পারে।

দেরীতে স্ট্যাটিক বাঁধাই রান টাইমে প্রাথমিকভাবে ডাকা ক্লাসটি উল্লেখ করে এমন একটি কীওয়ার্ড প্রবর্তন করে সেই সীমাবদ্ধতা সমাধানের চেষ্টা করে। ... একটি নতুন কীওয়ার্ড প্রবর্তন না করার সিদ্ধান্ত নেওয়া হয়েছিল, বরং staticইতিমধ্যে সংরক্ষিত ছিল এমনটি ব্যবহার করুন ।

আসুন একটি উদাহরণ দেখুন:

<?php
    class Car
    {
        public static function run()
        {
            return static::getName();
        }

        private static function getName()
        {
            return 'Car';
        }
    }

    class Toyota extends Car
    {
        public static function getName()
        {
            return 'Toyota';
        }
    }

    echo Car::run(); // Output: Car
    echo Toyota::run(); // Output: Toyota
?>

শেষ "অ-ফরোয়ার্ডিং কল" নামক শ্রেণিটি সংরক্ষণ করে দেরীতে স্থির বাইন্ডিং কাজ করে। স্থির পদ্ধতি কলগুলির ক্ষেত্রে, এটি পরিষ্কারভাবে নামকরণ করা শ্রেণি (সাধারণত ::অপারেটরের বাম দিকে একটি ); স্থিতিশীল পদ্ধতি কলগুলির ক্ষেত্রে এটি অবজেক্টের শ্রেণি। একটি "ফরওয়ার্ডিং কল" একটি স্ট্যাটিক এক যে চালু হয় self::, parent::, static::, বা, যদি বর্গ শ্রেণীবিন্যাসে ঊর্ধ্বগামী, forward_static_call()। ফাংশনটি get_called_class()ডাকা শ্রেণীর নামের সাথে একটি স্ট্রিং পুনরুদ্ধার করতে ব্যবহৃত হতে পারে এবং static::এর ব্যাপ্তিটি প্রবর্তন করে।


1
এই পোস্টটি উদ্ধৃতি চিহ্ন ছাড়াই পিএইচপি.এন.টি. নিবন্ধটির একটি ভারব্যাটিম অনুলিপি ~ 80% ।
উড্রোশিগেরু

22

খুব সুস্পষ্ট আচরণ নেই:

নিম্নলিখিত কোডটি 'বর্ণমালা' উত্পাদন করে।

class alpha {

    function classname(){
        return __CLASS__;
    }

    function selfname(){
        return self::classname();
    }

    function staticname(){
        return static::classname();
    }
}

class beta extends alpha {

    function classname(){
        return __CLASS__;
    }
}

$beta = new beta();
echo $beta->selfname(); // Output: alpha
echo $beta->staticname(); // Output: beta

তবে, আমরা যদি বিটা ক্লাস থেকে ক্লাসের নাম কার্যের ঘোষণাটি সরিয়ে ফেলি, ফলস্বরূপ আমরা 'আলফালফা' পাই।


1
খুব সুন্দর. পিএইচপি ম্যানুয়ালটিতে একই জিনিসটি দেখানো হয়েছে তবে এটি আরও পরিষ্কার। রেফারেন্সের জন্য: php.net/manual/en/language.oop5.late-static-bindings.php (দেখুন প্রাক্তন 4)
musicin3d

11

আমি বইটি থেকে উদ্ধৃত করছি: "পিএইচপি মাস্টার লেখার কাটিং-এজ কোড"।

লেট স্ট্যাটিক বাইন্ডিং পিএইচপি 5.3 এর সাথে প্রবর্তিত একটি বৈশিষ্ট্য ছিল। এটি আমাদের পিতামাতাদের ক্লাস থেকে স্থিতিশীল পদ্ধতিগুলি উত্তরাধিকারী করতে এবং শিশু শ্রেণীর নাম্বার আহ্বান জানাতে সহায়তা করে।

এর অর্থ আপনার স্ট্যাটিক পদ্ধতি সহ একটি বিমূর্ত শ্রেণি থাকতে পারে এবং স্ব :: :: পদ্ধতি () এর পরিবর্তে স্থির :: পদ্ধতি () স্বরলিপি ব্যবহার করে শিশু শ্রেণির কংক্রিট বাস্তবায়নগুলি উল্লেখ করতে পারেন ।

অফিসিয়াল পিএইচপি ডকুমেন্টেশনটিও নির্দ্বিধায় দেখুন: http://php.net/manual/en/language.oop5.late-static-bindings.php


লেট স্ট্যাটিক বাইন্ডিংকে ব্যাখ্যা করার সবচেয়ে সুস্পষ্ট উপায় হ'ল একটি সাধারণ উদাহরণ। নীচের দুটি শ্রেণীর সংজ্ঞাটি দেখুন এবং পড়ুন।

class Vehicle {
    public static function invokeDriveByStatic() {
        return static::drive(); // Late Static Binding
    }
    public static function invokeStopBySelf() {
        return self::stop(); // NOT Late Static Binding
    }
    private static function drive(){
        return "I'm driving a VEHICLE";
    }
    private static function stop(){
        return "I'm stopping a VEHICLE";
    }
}

class Car extends Vehicle  {
    protected static function drive(){
        return "I'm driving a CAR";
    }
    private static function stop(){
        return "I'm stopping a CAR";
    }
}

আমরা একটি প্যারেন্ট ক্লাস (যানবাহন) এবং একটি শিশু শ্রেণি (গাড়ি) দেখি। অভিভাবক শ্রেণীর ২ টি সর্বজনীন পদ্ধতি রয়েছে:

  • invokeDriveByStatic
  • invokeStopBySelf

অভিভাবক শ্রেণীর 2 টি ব্যক্তিগত পদ্ধতি রয়েছে:

  • drive
  • stop

শিশু শ্রেণি 2 পদ্ধতিকে ওভাররাইড করে:

  • drive
  • stop

এখন আসুন জনসাধারণের পদ্ধতিগুলি:

  • invokeDriveByStatic
  • invokeStopBySelf

নিজেকে জিজ্ঞাসা করুন: কোন শ্রেণি invokeDriveByStatic/ প্রার্থনা করে invokeStopBySelf? অভিভাবক বা শিশু শ্রেণি?

নীচে একবার দেখুন:

// This is NOT Late Static Binding
// Parent class invokes from Parent. In this case Vehicle.
echo Vehicle::invokeDriveByStatic(); // I'm driving a VEHICLE
echo Vehicle::invokeStopBySelf(); // I'm stopping a VEHICLE

// !!! This is Late Static Binding !!!!
// Child class invokes an inherited method from Parent.
// Child class = Car, Inherited method = invokeDriveByStatic().
// The inherited method invokes a method that is overridden by the Child class.
// Overridden method = drive()
echo Car::invokeDriveByStatic(); // I'm driving a CAR

// This is NOT Late Static Binding
// Child class invokes an inherited method from Parent.
// The inherited method invokes a method inside the Vehicle context.
echo Car::invokeStopBySelf(); // I'm stopping a VEHICLE

staticশব্দ একটি একক নকশা প্যাটার্ন ব্যবহার করা হয়। লিঙ্কটি দেখুন: https://refactoring.guru/design-patterns/singleton/php/example


7

পার্থক্যটি দেখানোর সহজতম উদাহরণ।
দ্রষ্টব্য, স্ব :: $ সি

class A
{
    static $c = 7;

    public static function getVal()
    {
        return self::$c;
    }
}

class B extends A
{
    static $c = 8;
}

B::getVal(); // 7

দেরীতে স্ট্যাটিক বাঁধাই, নোট স্ট্যাটিক :: $ সি

class A
{
    static $c = 7;

    public static function getVal()
    {
        return static::$c;
    }
}

class B extends A
{
    static $c = 8;
}

B::getVal(); // 8

4

উদাহরণ স্বরূপ:

abstract class Builder {
    public static function build() {
        return new static;
    }
}

class Member extends Builder {
    public function who_am_i() {
         echo 'Member';
    }
}

Member::build()->who_am_i();

4

এটি "কেন আমি এটি ব্যবহার করব?" থেকে এটিকে দেখছেন? দৃষ্টিকোণ, এটি মূলত প্রসঙ্গটি পরিবর্তনের একটি উপায় যা থেকে স্থির পদ্ধতিটি ব্যাখ্যা করা / চালানো হচ্ছে।

এর সাথে self, প্রসঙ্গটি হ'ল আপনি যেখানে পদ্ধতিটি মূলত সংজ্ঞায়িত করেছেন। এর সাথে static, আপনি এটি থেকে কল করছেন।


1

এছাড়াও, আপনি শিশু শ্রেণিতে স্থিতিশীল ভেরিয়েবলগুলি আপডেট করেন কিনা তা দেখুন। আমি এটি (কিছুটা) অপ্রত্যাশিত ফলাফল পেয়েছি যেখানে শিশু বি শিশু সি আপডেট করে:

class A{
    protected static $things;
}

class B extends A {
    public static function things(){
        static::$things[1] = 'Thing B';
        return static::$things; 
    }
}

class C extends A{
    public static function things(){
        static::$things[2] = 'Thing C';
        return static::$things;        
    }
}

print_r(C::things());
// Array (
//   [2] => Thing C
// )

B::things();

print_r(C::things()); 
// Array (
//    [2] => Thing C
//    [1] => Thing B
// )

আপনি প্রতিটি শিশু শ্রেণিতে একই পরিবর্তনশীল ঘোষণা করে এটি ঠিক করতে পারেন, উদাহরণস্বরূপ:

class C extends A{
    protected static $things; // add this and B will not interfere!

    public static function things(){
        static::$things[2] = 'Thing C';
        return static::$things;        
    }
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.