নতুন স্ব কী করে (); পিএইচপি মানে?


110

আমি এর মতো কোডটি কখনও দেখিনি:

public static function getInstance()
{
    if ( ! isset(self::$_instance)) {
        self::$_instance = new self();
    }
    return self::$_instance;
}

এটি কি হিসাবে একই new className()?

সম্পাদনা

শ্রেণি যদি উত্তরাধিকারী হয় তবে এটি কোন শ্রেণিকে নির্দেশ করবে?



@ স্টিরিওফ্রোগ, আপনার মানে কি সিঙ্গেলটন প্যাটার্নটি পরিত্যাগ করা উচিত? তবে সমস্ত কিছুর কারণ রয়েছে, তাই না?
ব্যবহারকারী 198729

ওহ, আমি এই
বিষয়টির

@ স্টিরিফ্রোগ সিঙ্গলটন হ'ল ইউনিট-টেস্টিংয়ের পক্ষে বিষ, এমন কোনও কিছুর ক্ষেত্রে অপরিবর্তনীয় পরীক্ষা করা অত্যন্ত কঠিন যা একটি কল থেকে পরের কলকে রাষ্ট্র পরিবর্তন করে।
ডেভিড

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

উত্তর:


211

self এটি যে শ্রেণিতে লেখা আছে তা নির্দেশ করে।

সুতরাং, যদি আপনার getInstance পদ্ধতিটি কোনও শ্রেণীর নামে থাকে MyClassতবে নিম্নলিখিত লাইনে:

self::$_instance = new self();

যেমনটি করবে:

self::$_instance = new MyClass();



সম্পাদনা করুন: মন্তব্য পরে আরও কয়েকটি তথ্য।

আপনার যদি দুটি ক্লাস থাকে যা একে অপরকে প্রসারিত করে, আপনার দুটি পরিস্থিতি রয়েছে:

  • getInstance শিশু শ্রেণিতে সংজ্ঞায়িত করা হয়
  • getInstance অভিভাবক শ্রেণিতে সংজ্ঞায়িত করা হয়

প্রথম পরিস্থিতিটি এর মতো দেখাবে (আমি সমস্ত অপ্রয়োজনীয় কোড মুছে ফেলেছি, উদাহরণস্বরূপ - একক আচরণের জন্য আপনাকে এটিকে আবার যুক্ত করতে হবে) *:

class MyParentClass {

}
class MyChildClass extends MyParentClass {
    public static function getInstance() {
        return new self();
    }
}

$a = MyChildClass::getInstance();
var_dump($a);

এখানে, আপনি পাবেন:

object(MyChildClass)#1 (0) { } 

যার অর্থ selfঅর্থ MyChildClass- অর্থাৎ যে শ্রেণিতে এটি লেখা আছে।


দ্বিতীয় অবস্থার জন্য কোডটি দেখতে এমন হবে:

class MyParentClass {
    public static function getInstance() {
        return new self();
    }
}
class MyChildClass extends MyParentClass {

}

$a = MyChildClass::getInstance();
var_dump($a);

এবং আপনি এই ধরণের আউটপুট পেতে চাই:

object(MyParentClass)#1 (0) { }

যার অর্থ এর selfঅর্থ MyParentClass- অর্থাত এখানেও, এটি ক্লাস যেখানে এটি লেখা আছে




পিএইচপি <5.3 এর সাথে, "যে শ্রেণিতে এটি লেখা আছে" গুরুত্বপূর্ণ - এবং কখনও কখনও সমস্যা তৈরি করতে পারে।

এই কারণেই পিএইচপি 5.3 staticকীওয়ার্ডের জন্য একটি নতুন ব্যবহারের প্রবর্তন করে : এটি এখন যেখানে আমরা selfসেই উদাহরণগুলিতে ব্যবহার করেছি ঠিক সেখানে ব্যবহার করা যেতে পারে :

class MyParentClass {
    public static function getInstance() {
        return new static();
    }
}
class MyChildClass extends MyParentClass {

}

$a = MyChildClass::getInstance();
var_dump($a);

তবে এর staticপরিবর্তে self, আপনি এখন পাবেন:

object(MyChildClass)#1 (0) { } 

যার অর্থ যে শ্রেণিটি ব্যবহৃতstatic হয় সেই শ্রেণীর পয়েন্টগুলি (আমরা ব্যবহার করিMyChildClass::getInstance() ), এবং এতে লেখা হয় না এমন is

অবশ্যই, selfবিদ্যমান অ্যাপ্লিকেশনগুলি না ভাঙার জন্য, আচরণটি পরিবর্তন করা হয়নি - পিএইচপি 5.3 মাত্র staticকীওয়ার্ডটি পুনর্ব্যবহার করে একটি নতুন আচরণ যুক্ত করেছে ।


এবং, পিএইচপি 5.3 সম্পর্কে বলতে গিয়ে, আপনি পিএইচপি ম্যানুয়ালটির লেট স্ট্যাটিক বাইন্ডিংস পৃষ্ঠাটি একবার দেখে নিতে পারেন ।


@ পল: হিউ ... এর অর্থ "স্বরূপে একটি উপাধি হিসাবে কাজ করে", বা "স্বতঃ বিন্দুতে বিন্দু" - ফরাসি ভাষায় "ডিজাইনার" ক্রিয়াটি ব্যবহার করা যেতে পারে - আমি মনে করি এটি পরিস্থিতিগুলির মধ্যে একটি ইংরেজিতে একই শব্দটি ব্যবহার করা ভাল ধারণা নয় ;-( আমি এই উত্তরটি ঠিক করার জন্য আমার উত্তরটি সম্পাদনা করব; ধন্যবাদ :-)
পাস্কাল মার্টিন

যদি সেখানে থাকে baseclass, classকোনটি এটি নির্দেশ করে?
ব্যবহারকারী198729

@ ব্যবহারকারী: আমি আমার উত্তর সম্পাদনা করেছি selfএবং উত্তরাধিকার সম্পর্কে কিছুটা আরও তথ্য দিতে ; এবং আমি staticপিএইচপি 5.3; এ সম্পর্কে কিছু তথ্য অন্তর্ভুক্ত করেছি ; আশা করি এটি সহায়তা করে :-)
পাস্কাল মার্টিন

10

এটি সিঙ্গলটন প্যাটার্নের একটি বাস্তবায়ন বলে মনে হচ্ছে । ফাংশনটি স্ট্যাটিকভাবে বলা হয় এবং স্থির শ্রেণীর চলক রয়েছে কিনা তা যাচাই করে$_instance সেট ।

যদি তা না হয় তবে এটি নিজের একটি দৃষ্টান্ত শুরু করে ( new self()) এবং এতে সঞ্চয় করে$_instance

আপনি কল করলে className::getInstance()আপনি এক এবং একই পাবেন শ্রেণীর উদাহরণ পাবেন যা সিঙ্গলটন প্যাটার্নের বিন্দু।

যদিও আমি এটি কখনও এইভাবে এটি করতে দেখিনি, এবং সত্যই এটি সম্ভব ছিল জানি না। $_instanceক্লাস হিসাবে ঘোষণা করা হয় কি ?


1
$_instanceহিসাবে ঘোষণা করা হয়েছেpublic static $_instance;
আতিফ

7

এটি সম্ভবত সিঙ্গেলটন ডিজাইনের ধরণে ব্যবহৃত হয়, যেখানে কনস্ট্রাক্টরটিকে ব্যক্তিগত হিসাবে সংজ্ঞায়িত করা হয় যাতে তাত্ক্ষণিক এড়ানোর জন্য ডাবল কোলন (::)অপারেটর শ্রেণীর অভ্যন্তরে স্থির ঘোষিত সদস্যদের অ্যাক্সেস করতে পারে, সুতরাং যদি স্থির সদস্য থাকে তবে সিউডো ভেরিয়েবল $ এটি ব্যবহার করা যাবে না, সুতরাং কোড পরিবর্তে স্ব ব্যবহার করা হয়েছে, সিঙ্গলেটগুলি হ'ল ভাল প্রোগ্রামিং অনুশীলন যা কেবলমাত্র 1 টি ডাটাবেস সংযোগকারী হ্যান্ডলারের মতো কোনও বস্তুর উদাহরণ দেয়। ক্লায়েন্ট কোড থেকে, উদাহরণটি অ্যাক্সেস করে একটি একক অ্যাক্সেস পয়েন্ট তৈরি করা হবে getInstance(), এক্ষেত্রে তিনি তার নাম রেখেছিলেন, গেটইনস্ট্যান্স নিজেই সেই ফাংশনটি তৈরি করেছিল যা মূলত নতুন কীওয়ার্ড ব্যবহার করে অবজেক্ট তৈরির জন্য কনস্ট্রাক্টর পদ্ধতির অর্থ ছিল বলা.

লাইনটি if(!isset(self::instance))পরীক্ষা করে যদি কোনও বস্তু ইতিমধ্যে তৈরি করা হয়েছে, আপনি বুঝতে পারবেন না এই কোডটি কেবল একটি খণ্ড, শীর্ষে কোথাও, সম্ভবত স্থির সদস্য থাকতে হবে

private static $_instance = NULL; 

সাধারণ ক্লাসে আমরা এই সদস্যটিকে সহজভাবে ব্যবহার করতে পারতাম

$this->_instance = 'something';

তবে এটি ঘোষিত স্থিতিশীল এবং তাই আমরা এর পরিবর্তে এই কোডটি ব্যবহার করতে পারি না

self::$_instance

এই স্থিতিশীল শ্রেণীর ভেরিয়েবলে কোনও বস্তু সঞ্চিত আছে কিনা তা যাচাই করে, ক্লাসটি তখন কোনও একক উদাহরণ তৈরি বা না করার সিদ্ধান্ত নিতে পারে, সুতরাং যদি সেট না করা হয়, সেটসেট, মানে স্থির সদস্যের উপর কোনও অবজেক্ট নেই in _সত্ত্বেও, এটি একটি নতুন অবজেক্ট উত্পন্ন $_instanceকরে, এটি কমান্ড দ্বারা স্থির সদস্যের মধ্যে সংরক্ষণ করে

self::$_instance = new self();

এবং এটি ক্লায়েন্ট কোডে ফিরিয়ে দিয়েছে। ক্লায়েন্ট কোডটি তখন আনন্দের সাথে তার সর্বজনীন পদ্ধতিগুলির সাথে অবজেক্টের একক উদাহরণ ব্যবহার করতে পারে, তবে ক্লায়েন্ট কোডে একক অ্যাক্সেস পয়েন্টকে কল করে, getInstance()পদ্ধতিটিটিও কৌশলপূর্ণ, এটিকে এই জাতীয় কল করতে হবে

$thisObject = className::getInstance();

কারণ, নিজের মধ্যে ফাংশন স্থির ঘোষণা করা হয়।


2

হ্যাঁ, এটি এর মতো new className()(সেই পদ্ধতিযুক্ত ক্লাসের কথা উল্লেখ করে) সম্ভবত একা একা প্যাটার্নে ব্যবহৃত হয় যেখানে নির্মাতা ব্যক্তিগত private


কেন কেউ পিএইচপি-তে সিঙ্গলটন প্যাটার্ন ব্যবহার করবে? ডেমন-এর মতো প্রোগ্রামে ব্যবহার না করা হলে, স্ক্রিপ্টটি চলাকালীন সিঙ্গলটন কেবলমাত্র লাইভ থাকবে এবং তারপরে প্রোগ্রামটি সহ অদৃশ্য হয়ে যাবে।
ILikeTacos

4
বৈশ্বিক পরিবর্তনশীল অ্যাক্সেসের জন্য জ্বালাময়ীভাবে বিশ্বব্যাপী ঘোষণা এড়াতে
স্যাম আদমশ

0

যদি শ্রেণিটি উত্তরাধিকার সূত্রে প্রাপ্ত হয় তবে সন্তানের কাছ থেকে getInstance () কল করা আপনাকে সন্তানের উদাহরণ দেয় না। এটি কেবল পিতামাতার দৃষ্টান্তের উদাহরণ দেয়। এটি কারণ আমরা নতুন স্ব () বলি।

যদি আপনি চান যে শিশু শ্রেণি শিশু শ্রেণির একটি উদাহরণ ফিরিয়ে দেবে তবে getInstance () এ নতুন স্ট্যাটিক () ব্যবহার করুন এবং এটি চাইল্ড ক্লাসের উদাহরণটি ফিরিয়ে দেবে। একে বলা হয় দেরী বন্ধন !!

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.