কখন এটি নিজের উপর ব্যবহার করবেন?


1997

পিএইচপি 5 এ, ব্যবহার selfএবং এর মধ্যে পার্থক্য কী $this?

যখন প্রতিটি উপযুক্ত?



আমি জিজ্ঞাসা করতে যাচ্ছি এর মধ্যে পার্থক্য কি: কনট এ; $ এটি-> এ এবং স্ব :: এ
টিমজ

উত্তর:


1727

সংক্ষিপ্ত উত্তর

$thisবর্তমান অবজেক্টটি উল্লেখ করতে ব্যবহার করুন । selfবর্তমান বর্গ উল্লেখ করতে ব্যবহার করুন । অন্য কথায়, $this->memberঅ স্থির সদস্যদের self::$memberজন্য ব্যবহার করুন, স্থির সদস্যদের জন্য ব্যবহার করুন ।

সম্পূর্ণ উত্তর

স্থিতিশীল এবং স্থিতিশীল সদস্য ভেরিয়েবলগুলির সঠিক ব্যবহারের $thisএবং এর উদাহরণ এখানে রয়েছে self:

<?php
class X {
    private $non_static_member = 1;
    private static $static_member = 2;

    function __construct() {
        echo $this->non_static_member . ' '
           . self::$static_member;
    }
}

new X();
?>

স্থিতিশীল এবং স্থিতিশীল সদস্য ভেরিয়েবলগুলির ভুল ব্যবহারের $thisএবং এর উদাহরণ এখানে রয়েছে self:

<?php
class X {
    private $non_static_member = 1;
    private static $static_member = 2;

    function __construct() {
        echo self::$non_static_member . ' '
           . $this->static_member;
    }
}

new X();
?>

এখানে একটি উদাহরণ পলিমরফিজম সঙ্গে $thisসদস্য কাজকর্মের জন্য:

<?php
class X {
    function foo() {
        echo 'X::foo()';
    }

    function bar() {
        $this->foo();
    }
}

class Y extends X {
    function foo() {
        echo 'Y::foo()';
    }
}

$x = new Y();
$x->bar();
?>

সদস্য ফাংশনগুলির জন্য ব্যবহার করে পলিমারফিক আচরণ দমন করার একটি উদাহরণ এখানে রয়েছে self:

<?php
class X {
    function foo() {
        echo 'X::foo()';
    }

    function bar() {
        self::foo();
    }
}

class Y extends X {
    function foo() {
        echo 'Y::foo()';
    }
}

$x = new Y();
$x->bar();
?>

ধারণাটি হ'ল সদস্যের ফাংশনটিকে বর্তমান অবজেক্টের সঠিক ধরণের যা কিছু বলা হয় $this->foo()calls foo()যদি অবজেক্টটি থাকে তবে type Xএটি কল করে X::foo()। যদি বস্তুটি থাকে তবে type Yএটি কল করে Y::foo()। তবে নিজের সাথে :: foo () X::foo()সর্বদা ডাকা হয়।

Http://www.phpbuilder.com/board/showthread.php?t=10354489 থেকে :

Http://board.phpbuilder.com/member.php?145249- লেজারলাইট দ্বারা


330
এই উত্তর অত্যধিক সরল। অন্যান্য উত্তরে নির্দেশিত হিসাবে, বর্তমান বর্গ উল্লেখ করার জন্য selfস্কোপ রেজোলিউশন অপারেটরের সাথে ব্যবহৃত হয় ::; এটি স্থিতিশীল এবং অ স্থির উভয় প্রসঙ্গেই করা যায়। অতিরিক্ত হিসাবে, $thisস্থিতিশীল পদ্ধতিতে কল করতে ব্যবহার করা পুরোপুরি আইনী (তবে রেফারেন্স ক্ষেত্রে নয়)।
আর্টেফ্যাক্টো

50
আপনি যদি 5.3+ তে থাকেন তবে :: স্ব পরিবর্তে স্থির :: ব্যবহারের কথা বিবেচনা করুন। অন্যথায় এটি আপনাকে অবিরাম মাথাব্যথার কারণ হতে পারে, এর জন্য আমার উত্তরটি নীচে দেখুন।
স্কুউ

25
-1। এই উত্তরটি বিভ্রান্তিকর, আরও তথ্যের জন্য অন্যান্য উত্তরগুলি পড়ুন।
পেসারিয়ার

6
এটি অত্যধিক সরল করা যেতে পারে তবে এটি আমার মাথা বিস্ফোরিত না করে আমার প্রাথমিক স্তরের প্রশ্নের উত্তর দিয়েছে। আমি আরও কিছু তথ্য পেয়েছি যা আমি আরও নীচে সহায়ক বলে খুঁজে পেয়েছি, তবে আপাতত আমি কেন আমার ক্লাসের বৈশিষ্ট্যগুলিকে $ এই-> বৈশিষ্ট্য এবং স্ব :: ধ্রুবক সহ শ্রেণি ধ্রুবকের সাথে আঘাত করলাম তা অনুধাবন করার চেষ্টা করছিলাম। এটি আমাকে আরও ভালভাবে বুঝতে সাহায্য করেছে
মাইডকনাইট

কি হবে $this::?
জেমস

742

মূলশব্দটি কেবল 'বর্তমান শ্রেণি' -কে উল্লেখ করে না , অন্তত এমন কোনও উপায়ে নয় যা আপনাকে স্থির সদস্যদের মধ্যে সীমাবদ্ধ করে। অ-স্থিতিশীল সদস্যের প্রসঙ্গে, বর্তমান অবজেক্টের জন্য selfভিটিবলকে (বাইবেলটিতে উইকি দেখুন ) বাইপাস করার একটি উপায়ও সরবরাহ করে । আপনি যেমন parent::methodName()কোনও ফাংশনের পিতামাতাকে সংস্করণে কল করতে ব্যবহার করতে পারেন , তেমনি আপনি self::methodName()কোনও পদ্ধতির বর্তমান ক্লাসগুলি কল করতে কল করতে পারেন ।

class Person {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }

    public function getTitle() {
        return $this->getName()." the person";
    }

    public function sayHello() {
        echo "Hello, I'm ".$this->getTitle()."<br/>";
    }

    public function sayGoodbye() {
        echo "Goodbye from ".self::getTitle()."<br/>";
    }
}

class Geek extends Person {
    public function __construct($name) {
        parent::__construct($name);
    }

    public function getTitle() {
        return $this->getName()." the geek";
    }
}

$geekObj = new Geek("Ludwig");
$geekObj->sayHello();
$geekObj->sayGoodbye();

এটি আউটপুট দেবে:

হ্যালো, আমি লুডভিগের
কাছ থেকে লুডভিগের লোকটির কাছ থেকে বিদায় নিচ্ছি

sayHello()$thisপয়েন্টারটি ব্যবহার করে , তাই ভিটিবেল কল করতে অনুরোধ জানানো হয় Geek::getTitle()sayGoodbye()ব্যবহার করে self::getTitle(), তাই vtable ব্যবহার করা হয় না, এবং Person::getTitle()বলা হয়। উভয় ক্ষেত্রেই, আমরা একটি তাত্ক্ষণিকভাবে অবজেক্টের পদ্ধতি নিয়ে কাজ করছি, এবং $thisডাকা ফাংশনগুলির মধ্যে পয়েন্টারটিতে অ্যাক্সেস পেয়েছি ।


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

3
@ অ্যাডজুইলি: কেন এই খারাপ স্টাইল? ওপির প্রত্যাশা (থিসিস) প্রথমে অস্বীকৃত (অ্যান্টিথেসিস) এবং তারপরে সংশ্লেষণ হিসাবে ব্যাখ্যাটি দেওয়া হলে তা কি সচেতনতা বাড়ায় না?
hakre

1
আমি "বর্তমান শ্রেণি" সত্যিই সমস্যাযুক্ত বলে মনে করি। যেহেতু এই শব্দের সংমিশ্রণটি উভয়ই বোঝা যায় যে "শ্রেণি যেখানে selfঅবস্থিত" / "শ্রেণি সংজ্ঞা এটি" এর সাথে সাথে "বস্তুর শ্রেণি" (যা আসলে হবে static) এর আক্ষরিক অংশ ।
জাকুমি

কি হবে $this::?
জেমস

1
@ জেমস - ব্যবহার করার কোনও ভাল কারণ নেই $this::; সমস্ত সম্ভাব্য কেস ইতিমধ্যে আরও ব্যবহৃত ব্যবহৃত বাক্য গঠন দ্বারা আচ্ছাদিত। আপনি কি বলতে চাইছেন উপর নির্ভর করে, ব্যবহার $this->, self::বা static::
টুলমেকারস্টেভ

461

ব্যবহার করবেন না self::, ব্যবহার করুনstatic::

স্ব-এর আরেকটি দিক রয়েছে: যা উল্লেখযোগ্য। বিরক্তিকরূপে self::প্রয়োগের বিন্দুতে নয় সংজ্ঞা পয়েন্টে সুযোগকে বোঝায় । দুটি সাধারণ পদ্ধতি সহ এই সাধারণ শ্রেণিটি বিবেচনা করুন:

class Person
{

    public static function status()
    {
        self::getStatus();
    }

    protected static function getStatus()
    {
        echo "Person is alive";
    }

}

আমরা যদি কল Person::status()করি আমরা দেখতে পাব "ব্যক্তি বেঁচে আছেন"। এখন বিবেচনা করুন যখন আমরা একটি ক্লাস তৈরি করি যা এর থেকে উত্তরাধিকার সূত্রে প্রাপ্ত:

class Deceased extends Person
{

    protected static function getStatus()
    {
        echo "Person is deceased";
    }

}

কলিং Deceased::status()আমরা "ব্যক্তি নিহত" দেখতে প্রত্যাশা করব তবে আমরা যা দেখি তা "ব্যক্তি জীবিত" কারণ কলটি self::getStatus()সংজ্ঞায়িত করার সময় সুযোগটিতে মূল পদ্ধতির সংজ্ঞা থাকে ।

পিএইচপি 5.3 এর একটি সমাধান রয়েছে। static::রেজল্যুশন অপারেটর কার্যকরী "প্রয়াত স্ট্যাটিক বাঁধাই" যা বলার অপেক্ষা রাখে না যে এটা বর্গ নামক পরিধি আবদ্ধ একটি অভিনব উপায়। লাইন পরিবর্তন status()করতে static::getStatus()এবং ফলাফল কি আপনি আশা আছে। পিএইচপি-র পুরানো সংস্করণগুলিতে এটি করার জন্য আপনাকে একটি ক্লডজ খুঁজে পেতে হবে।

পিএইচপি ডকুমেন্টেশন দেখুন

সুতরাং প্রশ্নের উত্তর হিসাবে জিজ্ঞাসা করা হয়নি ...

$this->বর্তমান বস্তুকে বোঝায় (শ্রেণীর উদাহরণ), যেখানে static::শ্রেণি বোঝায়


6
শ্রেণীর ধ্রুবকগুলির জন্য কী?
কেভিন বন্ড

53
"ডেসেড :: স্ট্যাটাস () কল করা আমরা" ব্যক্তি নিহত "" আশা করব। না এটি একটি স্থির ফাংশন কল তাই কোনও পলিমারফিজম জড়িত নেই।
cquezel

2
পিএইচপি-র সমস্ত ত্রুটিগুলির মধ্যে আমি কারও পক্ষে এটি মোটেও পাগল বলে মনে করি না। কীভাবে তারা কোডারদের বর্তমান শ্রেণিতে পদ্ধতি নির্ধারণের অনুমতি দেবে (তাদের ভিটিবেলে সন্ধান করার বিপরীতে)? যদি তারা এটির নাম আলাদাভাবে রেখেছিল (সম্ভবত শীর্ষস্থানীয় আন্ডারস্কোর সহ) তবে লোকেরা এই বৈশিষ্ট্যটি কুৎসিত বলে সমালোচনা করবে। অন্যথায়, তারা যে নামকরা নামটি ব্যবহার করতে পারে তা মনে হয় সহজেই বিভ্রান্ত ব্যক্তিরা থাকবেন যারা "পাগল" আচরণের জন্য এটির সমালোচনা করবেন, পদ্ধতি কীভাবে প্রেরণে এমনকি এটি কীভাবে কাজ করে তা সম্পর্কে অবহেলাও বটে।
tne

2
উদাহরণটি আমার কাছে বিভ্রান্তিকর বলে মনে হচ্ছে: আমি getStatusপদ্ধতিটি দেখি যেহেতু আমি ক্লাসের জন্য নয় বরং ক্লাসের উদাহরণের জন্য কল করব।
জনিস এলমারিস

1
@ স্কু - "স্ব ব্যবহার করবেন না :: বলছেন , স্ট্যাটিক :: ব্যবহার করুন" তৈরি করা একটি আজব পয়েন্ট - এটি ইচ্ছাকৃতভাবে একই ক্রিয়াকলাপ নয়। আমি মনে করি বিন্দু আপনি কি সত্যিই উপার্জন হয় "এটা পরিষ্কার হলে আপনি বরং 'স্ব ::' ছাড়া, প্রকৃত বর্গ নাম 'MyClass ::' ব্যবহার । এর মানে, যদি আপনি আচরণকে চান self::, আপনি যে, কম পেতে পারেন confusingly, নির্দিষ্ট বর্গ নাম ব্যবহার করে যেমন দ্বারা MyClass::
ToolmakerSteve

248

selfবনাম সম্পর্কে যখন কথা বলি তখন সত্যই আমরা কী বিষয়ে কথা বলি তা বুঝতে $this, আমাদের আসলে একটি ধারণাগত এবং ব্যবহারিক স্তরে কী চলছে তা খনন করতে হবে। আমি উত্তরগুলির কোনও উত্তরই যথাযথভাবে এটি করতে পারি না বলে আমার চেষ্টা এখানে।

একটি ক্লাস এবং একটি বস্তু কী তা নিয়ে কথা বলে শুরু করা যাক ।

ক্লাস এবং অবজেক্টস, ধারণামূলকভাবে

তো, হয় একটি বর্গ ? অনেক লোক এটিকে কোনও বস্তুর ব্লুপ্রিন্ট বা একটি টেম্পলেট হিসাবে সংজ্ঞায়িত করে । আসলে, আপনি এখানে পিএইচপি ইন ক্লাস সম্পর্কে আরও পড়তে পারেন । এবং কিছুটা হলেও আসলে এটি। একটি ক্লাস তাকান:

class Person {
    public $name = 'my name';
    public function sayHello() {
        echo "Hello";
    }
}

যেমন আপনি বলতে পারেন যে শ্রেণীর নামক একটি সম্পত্তি আছে $nameএবং একটি পদ্ধতি (ফাংশন) বলা হয় sayHello()

এটা খুব খেয়াল করা জরুরী যে গুরুত্বপূর্ণ বর্গ একটি স্ট্যাটিক স্ট্রাকচার। যার অর্থ হল যে ক্লাসটি Person, একবার সংজ্ঞায়িত, আপনি যেখানেই দেখেন না কেন সর্বদা একই থাকে।

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

$bob = new Person;
$adam = new Person;
$bob->name = 'Bob';
echo $adam->name; // "my name"

আমরা অপারেটরটি ব্যবহার করে একটি শ্রেণীর নতুন দৃষ্টান্ত তৈরি করি new

সুতরাং, আমরা বলি যে একটি শ্রেণি একটি বিশ্বব্যাপী কাঠামো, এবং একটি অবজেক্ট একটি স্থানীয় কাঠামো। এই মজার ->সিনট্যাক্স সম্পর্কে চিন্তা করবেন না , আমরা এটি কিছুটা মধ্যে যাব।

আমাদের আরও একটি বিষয় সম্পর্কে কথা বলা উচিত, তা হ'ল আমরা উদাহরণটি কোনও নির্দিষ্ট শ্রেণীর কিনা তা পরীক্ষা করে দেখতে পারি instanceof: $bob instanceof Personযা $bobউদাহরণটি Personক্লাস, বা কোনও শিশু ব্যবহার করে তৈরি করা হলে একটি বুলিয়ান দেয় Person

রাষ্ট্রের সংজ্ঞা দেওয়া হচ্ছে

সুতরাং আসুন একটি ক্লাস আসলে কি রয়েছে সে সম্পর্কে কিছুটা খনন করি। শ্রেণিতে রয়েছে এমন 5 ধরণের "জিনিস" রয়েছে:

  1. বৈশিষ্ট্য - এগুলির প্রতিটি পরিবর্তন হিসাবে ভেরিয়েবল হিসাবে ভাবুন।

    class Foo {
        public $bar = 1;
    }
  2. স্ট্যাটিক প্রোপার্টি - এগুলি শ্রেণি স্তরে ভাগ করা পরিবর্তনশীল হিসাবে ভাবেন। এর অর্থ হ'ল এগুলি প্রতিটি উদাহরণ দ্বারা অনুলিপি করা হয় না।

    class Foo {
        public static $bar = 1;
    }
  3. পদ্ধতি - এগুলি এমন ফাংশন যা প্রতিটি উদাহরণে অন্তর্ভুক্ত থাকে (এবং উদাহরণগুলিতে পরিচালনা করে)।

    class Foo {
        public function bar() {}
    }
  4. স্ট্যাটিক পদ্ধতি - এগুলি এমন ফাংশন যা পুরো ক্লাসে ভাগ করা হয়। তারা উদাহরণগুলিতে অপারেট করে না , পরিবর্তে কেবল স্থিতিশীল বৈশিষ্ট্যগুলিতে।

    class Foo {
        public static function bar() {}
    }
  5. ধ্রুবক - শ্রেণি নিষ্পত্তি স্থির। এখানে আরও গভীরতর না যাওয়া, তবে সম্পূর্ণতার জন্য যুক্ত করা:

    class Foo {
        const BAR = 1;
    }

সুতরাং মূলত, আমরা ক্লাস এবং অবজেক্টের ধারক স্থিতিশীল সম্পর্কে "ইঙ্গিত" ব্যবহার করে তথ্যগুলি সংরক্ষণ করি যা তথ্য ভাগ করে নেওয়া (এবং তাই স্থিতিশীল) কিনা (এবং তাই গতিশীল) তা চিহ্নিত করে।

রাষ্ট্র এবং পদ্ধতি

কোনও পদ্ধতির অভ্যন্তরে কোনও বস্তুর উদাহরণ $thisভেরিয়েবল দ্বারা প্রতিনিধিত্ব করা হয় । সেই অবজেক্টের বর্তমান অবস্থা রয়েছে এবং কোনও সম্পত্তিকে পরিবর্তন (পরিবর্তন) করার ফলে সেই উদাহরণে পরিবর্তিত হবে (তবে অন্যরা নয়)।

যদি কোনও পদ্ধতিকে স্থিতিকরভাবে বলা হয় তবে $thisভেরিয়েবল সংজ্ঞায়িত হয় না । এটি কারণ এটি স্ট্যাটিক কলের সাথে সম্পর্কিত কোনও উদাহরণ নেই।

আকর্ষণীয় বিষয়টি এখানে স্থির কলগুলি কীভাবে করা হয়। সুতরাং আসুন আমরা কীভাবে রাজ্যে অ্যাক্সেস করব সে সম্পর্কে কথা বলি:

অ্যাক্সেস স্টেট

সুতরাং এখন আমরা যে রাজ্যটি সংরক্ষণ করেছি, আমাদের এটি অ্যাক্সেস করা দরকার। এটি কিছুটা জটিল (বা কিছুটা বেশি পথ ) পেতে পারে, সুতরাং আসুন এটিকে দুটি দৃষ্টিকোণে বিভক্ত করুন: উদাহরণ / শ্রেণীর বাইরে (একটি সাধারণ ফাংশন কল থেকে বা বিশ্বব্যাপী সুযোগ থেকে বলুন), এবং একটি উদাহরণের অভ্যন্তরে / বর্গ (অবজেক্টের কোনও পদ্ধতির মধ্যে থেকে)।

আউটসাইড অফ ইন ইনস্ট্যান্স / ক্লাস থেকে

কোনও উদাহরণ / শ্রেণীর বাইরে থেকে, আমাদের বিধিগুলি বেশ সহজ এবং অনুমানযোগ্য। আমাদের দুটি অপারেটর রয়েছে, এবং প্রত্যেকে আমাদের অবিলম্বে জানায় যে আমরা কোনও উদাহরণ বা শ্রেণি স্থির নিয়ে কাজ করছি:

  • ->- অবজেক্ট-অপারেটর - যখন আমরা কোনও দৃষ্টান্ত অ্যাক্সেস করি তখন এটি সর্বদা ব্যবহৃত হয়।

    $bob = new Person;
    echo $bob->name;

    এটি লক্ষ করা গুরুত্বপূর্ণ যে কলিং Person->fooকোনও অর্থবোধ করে না (যেহেতু Personএকটি শ্রেণি, উদাহরণ নয়)। অতএব, এটি একটি পার্স ত্রুটি।

  • ::- স্কোপ-রেজোলিউশন-অপারেটর - এটি সর্বদা শ্রেণিক স্ট্যাটিক সম্পত্তি বা পদ্ধতি অ্যাক্সেস করতে ব্যবহৃত হয়।

    echo Foo::bar()

    অতিরিক্তভাবে, আমরা একইভাবে কোনও বস্তুর উপর স্থিতিশীল পদ্ধতি কল করতে পারি:

    echo $foo::bar()

    এটি লক্ষ করা অত্যন্ত গুরুত্বপূর্ণ যে আমরা যখন বাইরে থেকে এটি করি তখন অবজেক্টের উদাহরণটি bar()পদ্ধতি থেকে লুকানো থাকে । এর অর্থ এটি দৌড়ানোর মতোই:

    $class = get_class($foo);
    $class::bar();

সুতরাং, $thisস্থির কল সংজ্ঞায়িত করা হয় না।

ইনসাইড অফ এ ইনস্ট্যান্স / ক্লাস থেকে

বিষয়গুলি এখানে কিছুটা পরিবর্তন হয়। একই অপারেটরগুলি ব্যবহৃত হয়, তবে তাদের অর্থ উল্লেখযোগ্যভাবে ঝাপসা হয়ে যায়।

অবজেক্ট অপারেটর -> এখনও বস্তুর দৃষ্টান্ত রাষ্ট্র কল করতে ব্যবহার করা হয়।

class Foo {
    public $a = 1;
    public function bar() {
        return $this->a;
    }
}

অবজেক্ট-অপারেটরটি ব্যবহার করে bar()পদ্ধতিটির $foo(উদাহরণস্বরূপ Foo) কল করা: $foo->bar()এর উদাহরণটির সংস্করণে আসবে $a

সুতরাং আমরা আশা করি যে কিভাবে।

::অপারেটরের অর্থ পরিবর্তিত হলেও। এটি বর্তমান ফাংশনে কল করার প্রসঙ্গে নির্ভর করে:

  • একটি স্থির প্রসঙ্গে

    স্থিতিশীল প্রসঙ্গে, যে কোনও কল ব্যবহার করে ::করা স্থিরও থাকবে। আসুন একটি উদাহরণ তাকান:

    class Foo {
        public function bar() {
            return Foo::baz();
        }
        public function baz() {
            return isset($this);
        }
    }

    কলিং পদ্ধতিটিকে স্থিতিশীলভাবে কল Foo::bar()করবে baz()এবং তাই জনবহুল $thisহবে না । এটি লক্ষণীয় যে পিএইচপি (5.3+) এর সাম্প্রতিক সংস্করণগুলিতে এটি একটি E_STRICTত্রুটি ঘটায় , কারণ আমরা স্থিতিশীলভাবে অ স্থিত পদ্ধতিগুলিকে কল করছি।

  • একটি উদাহরণ প্রসঙ্গে

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

    সুতরাং, উপরের কোডটির দিকে তাকানো, কলিং $foo->bar()ফিরে আসবে true, যেহেতু "স্ট্যাটিক" কলটি একটি উদাহরণ প্রসঙ্গে থাকে।

ধারণা তৈরী কর? ভেবে দেখেনি। এটা বিভ্রান্তিকর.

শর্ট-কাট কীওয়ার্ড

শ্রেণীর নাম ব্যবহার করে সবকিছুকে একত্রে বেঁধে রাখাই বরং নোংরা, পিএইচপি স্কোপ সমাধান সহজতর করতে 3 টি বেসিক "শর্টকাট" কীওয়ার্ড সরবরাহ করে।

  • self- এটি বর্তমান শ্রেণীর নাম বোঝায়। সুতরাং self::baz()হিসাবে একই Foo::baz()মধ্যে Fooবর্গ (এটা কোন পদ্ধতি)।

  • parent - এটি বর্তমান শ্রেণীর পিতামাতাকে বোঝায়।

  • static- এটি বলা ক্লাস বোঝায়। উত্তরাধিকারের জন্য ধন্যবাদ, শিশু শ্রেণিগুলি পদ্ধতি এবং স্থিতিশীল বৈশিষ্ট্যগুলিকে ওভাররাইড করতে পারে। সুতরাং staticশ্রেণীর নামের পরিবর্তে তাদেরকে কল করা আমাদের বর্তমান স্তরের পরিবর্তে কলটি কোথা থেকে এসেছে তা সমাধান করার অনুমতি দেয়।

উদাহরণ

এটি বোঝার সহজতম উপায় হ'ল কয়েকটি উদাহরণ দেখা শুরু করা। আসুন একটি ক্লাস বাছাই:

class Person {
    public static $number = 0;
    public $id = 0;
    public function __construct() {
        self::$number++;
        $this->id = self::$number;
    }
    public $name = "";
    public function getName() {
        return $this->name;
    }
    public function getId() {
        return $this->id;
    }
}

class Child extends Person {
    public $age = 0;
    public function __construct($age) {
        $this->age = $age;
        parent::__construct();
    }
    public function getName() {
        return 'child: ' . parent::getName();
    }
}

এখন, আমরা এখানে উত্তরাধিকারের দিকেও তাকিয়ে আছি। এক মুহুর্তের জন্য উপেক্ষা করুন যে এটি একটি খারাপ অবজেক্টের মডেল, তবে আসুন আমরা এটি খেলে কী হয় তা দেখুন:

$bob = new Person;
$bob->name = "Bob";
$adam = new Person;
$adam->name = "Adam";
$billy = new Child;
$billy->name = "Billy";
var_dump($bob->getId()); // 1
var_dump($adam->getId()); // 2
var_dump($billy->getId()); // 3

সুতরাং আইডি কাউন্টারটি উভয় দৃষ্টান্ত এবং শিশুদের মধ্যে ভাগ করা হয় (কারণ আমরা selfএটি অ্যাক্সেস করতে ব্যবহার করছি If আমরা যদি ব্যবহার করি তবে আমরা staticএটি একটি শিশু শ্রেণিতে ওভাররাইড করতে পারি)।

var_dump($bob->getName()); // Bob
var_dump($adam->getName()); // Adam
var_dump($billy->getName()); // child: Billy

মনে রাখবেন যে আমরা প্রতিবার Person::getName() উদাহরণ পদ্ধতিটি সম্পাদন করছি । তবে আমরা parent::getName()এটির একটি ক্ষেত্রে (শিশু ক্ষেত্রে) এটি করতে ব্যবহার করছি । এটিই এই পদ্ধতিরটিকে শক্তিশালী করে তোলে।

সতর্কতার শব্দ # 1

নোট করুন যে কলিং প্রসঙ্গটি কোনও উদাহরণ ব্যবহার করা হয় কিনা তা নির্ধারণ করে। অতএব:

class Foo {
    public function isFoo() {
        return $this instanceof Foo;
    }
}

সবসময় সত্য হয় না ।

class Bar {
    public function doSomething() {
        return Foo::isFoo();
    }
}
$b = new Bar;
var_dump($b->doSomething()); // bool(false)

এখন এটি সত্যিই অদ্ভুত। আমরা একটি পৃথক শ্রেণি কল করছি, কিন্তু $thisযে Foo::isFoo()পদ্ধতিতে পাস হয় উদাহরণস্বরূপ $bar

এটি সমস্ত ধরণের বাগ এবং ধারণাগত ডাব্লুটিএফ-এরি তৈরি করতে পারে। তাই আমি অত্যন্ত এড়ানো করার সুপারিশ করছি ::যারা তিন ভার্চুয়াল "ছোট করে কাটা" কিওয়ার্ড ছাড়া কিছু উপর উদাহরণস্বরূপ পদ্ধতি মধ্যে থেকে অপারেটর ( static, self, এবং parent)।

সতর্কতার শব্দ # 2

নোট করুন যে স্থির পদ্ধতি এবং বৈশিষ্ট্যগুলি প্রত্যেকে ভাগ করে নিয়েছে। এটি তাদেরকে মূলত বিশ্বব্যাপী পরিবর্তনশীল করে তোলে। সমস্ত একই সমস্যা যা বিশ্বব্যাপী সঙ্গে আসে With সুতরাং আপনি স্থিতিশীল পদ্ধতি / বৈশিষ্ট্যে তথ্য সংরক্ষণ করতে সত্যই দ্বিধা বোধ করবেন যদি না আপনি সত্যই এটি বিশ্বব্যাপী হওয়ার বিষয়ে স্বাচ্ছন্দ্য বোধ করেন।

সতর্কতার শব্দ # 3

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

টি এল / ডিআর

খুব খারাপ, ফিরে যান এবং এটি পড়ুন। এটি খুব দীর্ঘ হতে পারে, তবে এটি এত দীর্ঘ কারণ এটি একটি জটিল বিষয়

টিএল / ডিআর # 2

আচ্ছা ঠিক আছে. সংক্ষেপে, একটি শ্রেণীর মধ্যে বর্তমান শ্রেণীর নামself উল্লেখ করতে ব্যবহৃত হয় , যেখানে $thisবর্তমান অবজেক্টের উদাহরণটি বোঝায় । দ্রষ্টব্য যে selfএকটি অনুলিপি / পেস্ট করুন short আপনি এটি আপনার শ্রেণীর নাম দিয়ে নিরাপদে প্রতিস্থাপন করতে পারেন এবং এটি দুর্দান্ত কাজ করবে। তবে $thisএটি একটি গতিশীল পরিবর্তনশীল যা সময়ের আগে নির্ধারণ করা যায় না (এবং এমনকি আপনার শ্রেণিও নাও হতে পারে)।

টিএল / ডিআর # 3

যদি অবজেক্ট-অপারেটর ব্যবহার করা হয় ( ->), তবে আপনি সর্বদা জানেন যে আপনি কোনও উদাহরণ দিয়ে কাজ করছেন। যদি স্কোপ-রেজুলেশন-অপারেটর ব্যবহার করা হয় ( ::), আপনার প্রসঙ্গটি সম্পর্কে আরও তথ্যের প্রয়োজন (আমরা কী ইতিমধ্যে কোনও বস্তু-প্রসঙ্গে রয়েছি? আমরা কি কোনও বস্তুর বাইরে আছি? ইত্যাদি)।



ঠিক আছে ... $thisআপনি "কঠোর মানদণ্ড" অনুসরণ করেন এবং স্থিতিশীল হিসাবে সংজ্ঞায়িত নয় এমন স্ট্যাটিক পদ্ধতিগুলিকে কল না করলে সংজ্ঞা দেওয়া হবে না। আপনি এখানে ফলাফল ব্যাখ্যা করেছেন: 3v4l.org/WEHVM সম্মত, সত্যিই অদ্ভুত।
মার্ক আচি

2
দীর্ঘ বিবরণটি সম্পূর্ণরূপে পড়ার পরে, এটিকে উপরে তুলতে আমি আবার উপরে স্ক্রোল করতে অলস অনুভব করেছি। খালি ঠাট্টা করলাম, আমি উড়িয়ে দিয়েছি: ডি। ধন্যবাদ এটি খুব দরকারী।
মিঃগ্রিন

3
স্ব :: $ সম্পত্তি এবং স্ব :: সম্পত্তি মধ্যে পার্থক্য সম্পর্কে একটি স্পষ্ট ব্যাখ্যা যোগ করা ভাল হবে; আমার মনে হয় এটি বেশ বিভ্রান্তিকর
টমাসো বারবুগলি

1
ডাব্লুওসি # 1 পিএইচপি 7 সাল থেকে আলাদা আচরণ করে As যেহেতু Foo::isFoo()স্ট্যাটিকালি বলা হয়, $thisসংজ্ঞায়িত হবে না। এটি আমার মতে আরও স্বজ্ঞাত আচরণ। - যদি অন্যটি বাড়ানো হয় তবে অন্য একটি ভিন্ন ফলাফল দেওয়া Barহয় Foo। তারপরে কলটি Foo::isFoo()প্রকৃতপক্ষে উদাহরণ প্রসঙ্গে হবে (পিএইচপি 7-তে নির্দিষ্ট নয়)।
কনট্রোলফ্রেইক

117

self(স্ব-নয়) শ্রেণীর ধরণকে$this বোঝায় , যেখানে শ্রেণীর বর্তমান উদাহরণকে বোঝায় । selfস্থির সদস্যের ভেরিয়েবলগুলি অ্যাক্সেস করার জন্য আপনাকে স্ট্যাটিক সদস্য ফাংশনে ব্যবহার করার জন্য। $thisস্থিতিশীল সদস্য ফাংশনগুলিতে ব্যবহৃত হয়, এবং সদস্য ফাংশনটি যে শ্রেণীর উপর ডাকা হত সেই শ্রেণীর উদাহরণের একটি রেফারেন্স।

কারণ thisএকটি বস্তু, আপনি এটি ব্যবহার করুন:$this->member

কারণ selfকোনও বস্তু নয়, এটি মূলত এমন এক ধরণের যা স্বয়ংক্রিয়ভাবে বর্তমান বর্গকে বোঝায়, আপনি এটি ব্যবহার করুন:self::member


97

$this-> শ্রেণীর ভেরিয়েবল (সদস্য ভেরিয়েবল) বা পদ্ধতিগুলির নির্দিষ্ট উদাহরণ উল্লেখ করতে ব্যবহৃত হয়।

Example: 
$derek = new Person();

re ডেরেক এখন ব্যক্তির একটি নির্দিষ্ট উদাহরণ। প্রত্যেক ব্যক্তির একটি প্রথম নাম এবং একটি সর্বশেষ নাম রয়েছে তবে $ ডেরেকের একটি নির্দিষ্ট প্রথম নাম এবং শেষ নাম (ডেরেক মার্টিন) রয়েছে। $ ডেরিক দৃষ্টান্তের মধ্যে আমরা $ এটি-> প্রথম নাম এবং $ এটি-> সর্বশেষ নাম হিসাবে তাদের উল্লেখ করতে পারি

ClassName :: ক্লাসের এই ধরণের এবং এর স্ট্যাটিক ভেরিয়েবলগুলি, স্ট্যাটিক পদ্ধতিগুলি উল্লেখ করতে ব্যবহৃত হয়। যদি এটি সহায়তা করে, আপনি মানসিকভাবে "স্থিতিশীল" শব্দটি "ভাগ করে নেওয়া" দিয়ে প্রতিস্থাপন করতে পারেন। যেহেতু তারা ভাগ করা আছে, তারা $ এটি উল্লেখ করতে পারে না, যা নির্দিষ্ট উদাহরণকে বোঝায় (ভাগ করে নেই)। স্ট্যাটিক ভেরিয়েবলগুলি (যেমন স্ট্যাটিক b db_connection) এক ধরণের অবজেক্টের সমস্ত উদাহরণের মধ্যে ভাগ করা যায়। উদাহরণস্বরূপ, সমস্ত ডাটাবেস অবজেক্ট একটি একক সংযোগ ভাগ করে (স্ট্যাটিক $ সংযোগ)।

স্ট্যাটিক ভেরিয়েবল উদাহরণ: আমাদের একক সদস্যের ভেরিয়েবল সহ একটি ডেটাবেস ক্লাস রয়েছে তা প্রচার করুন: স্থির $ num_connitions; এখন এটি কনস্ট্রাক্টরে রাখুন:

function __construct()
{
    if(!isset $num_connections || $num_connections==null)
    {
        $num_connections=0;
    }
    else
    {
        $num_connections++;
    }
}

অবজেক্টের যেমন কনস্ট্রাক্টর থাকে, তেমনি তাদের ডেস্ট্রাক্টরও রয়েছে, যা বস্তুটি মারা গেলে বা আনসেট না হয়ে মৃত্যুদন্ড কার্যকর করা হয়:

function __destruct()
{
    $num_connections--;
}

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

echo DB::num_connections;

যেহেতু con num_connitions স্থির (ভাগ করা), এটি সক্রিয় ডাটাবেস অবজেক্টের মোট সংখ্যাকে প্রতিফলিত করবে। আপনি সম্ভবত এই কৌশলটি ডেটাবেস ক্লাসের সমস্ত দৃষ্টান্তের মধ্যে ডাটাবেস সংযোগ ভাগ করতে ব্যবহার করেছেন used এটি করা হয়েছে কারণ ডাটাবেস সংযোগ তৈরি করতে দীর্ঘ সময় লাগে, সুতরাং কেবলমাত্র একটি তৈরি করা এবং ভাগ করে নেওয়া ভাল (এটিকে সিঙ্গলটন প্যাটার্ন বলা হয়)।

স্ট্যাটিক পদ্ধতি (যেমন পাবলিক স্ট্যাটিক ভিউ :: ফরম্যাট_ফোন_নম্বার (s ডিজিট)) ব্যবহার করা যেতে পারে প্রথমে objects অবজেক্টগুলির মধ্যে একটি ইনস্ট্যান্ট করে (যেমন তারা অভ্যন্তরীণভাবে এটি to এটিকে বোঝায় না)।

স্থির পদ্ধতির উদাহরণ:

public static function prettyName($first_name, $last_name)
{
    echo ucfirst($first_name).' '.ucfirst($last_name);
}

echo Person::prettyName($derek->first_name, $derek->last_name);

আপনি দেখতে পাচ্ছেন, পাবলিক স্ট্যাটিক ক্রিয়াকলাপ নামটি অবজেক্ট সম্পর্কে কিছুই জানে না। এটি কেবলমাত্র আপনি যে প্যারামিটারগুলিতে পাস করেছেন সাথে কাজ করছে, কোনও সাধারণ ফাংশনের মতো যা কোনও বস্তুর অংশ নয় part কেন বিরক্ত হ'ল, যদি আমরা কেবল এটি বস্তুর অংশ হিসাবে না পেয়ে পারি?

  1. প্রথমত, অবজেক্টগুলিতে ফাংশন সংযুক্তি আপনাকে জিনিসগুলিকে সংগঠিত রাখতে সহায়তা করে, যাতে সেগুলি কোথায় পাওয়া যায় তা আপনি জানেন।
  2. দ্বিতীয়ত, এটি নামকরণ বিরোধগুলি প্রতিরোধ করে। একটি বড় প্রকল্পে আপনার সম্ভবত দুজন বিকাশকারী getName () ফাংশন তৈরি করবেন। যদি একটি ক্লাসনেম 1 :: getName () তৈরি করে এবং অন্যটি ClassName2 :: getName () তৈরি করে তবে এটি কোনও সমস্যা নয়। কোন বিরোধ নেই। হ্যাঁ স্থির পদ্ধতি!

SELF :: আপনি যদি স্থির পদ্ধতিটি উল্লেখ করতে চান এমন অবজেক্টের বাইরে কোডিং করে থাকেন তবে আপনাকে অবশ্যই অবজেক্টের নাম ভিউ :: ফর্ম্যাট_ফোন_ম্বর ($ ফোন_ নাম্বার) ব্যবহার করে এটি কল করতে হবে; আপনি কোডিং হয় ভিতরে বস্তুর স্ট্যাটিক পদ্ধতি আপনাকে, আপনি পারেন পড়ুন করতে চান যে পারেন বস্তুর নাম দেখুন :: format_phone_number ($ PN) ব্যবহার, অথবা আপনি স্ব :: format_phone_number ($ PN) ব্যবহার করতে পারেন শর্টকাট

স্ট্যাটিক ভেরিয়েবলগুলির ক্ষেত্রে একই: উদাহরণ: দেখুন :: টেমপ্লেট_পথ বনাম স্ব :: টেম্পলেট_পথ

ডিবি শ্রেণীর অভ্যন্তরে, আমরা যদি অন্য কোনও অবজেক্টের স্থিতিশীল পদ্ধতিটি উল্লেখ করতাম তবে আমরা বস্তুর নাম ব্যবহার করতাম: উদাহরণ: সেশন :: getUserOnline ();

তবে ডিবি শ্রেণি যদি নিজস্ব স্ট্যাটিক ভেরিয়েবলটি উল্লেখ করতে চায় তবে এটি কেবল স্ব: উদাহরণ: স্ব :: সংযোগ;

আশা করি বিষয়গুলি পরিষ্কার করতে সহায়তা করবে :)


দুর্দান্ত উত্তর। আমি কেবল উল্লেখ করতে চাই, যখন কোনও স্থির বৈশিষ্ট্য উল্লেখ করা হয়, আপনাকে একটি $চিহ্ন ব্যবহার করতে হবে । উদাহরণস্বরূপself::$templates_path
হেনরিয়াইট

30

থেকে এই ব্লগ পোস্টে :

  • self বর্তমান বর্গ বোঝায়
  • self স্ট্যাটিক ফাংশন এবং রেফারেন্স স্ট্যাটিক সদস্য ভেরিয়েবলগুলি কল করতে ব্যবহৃত হতে পারে
  • self স্থির ফাংশন ভিতরে ব্যবহার করা যেতে পারে
  • self ভিটিবেলকে বাইপাস করে বহুতল আচরণ বন্ধ করতে পারে
  • $this বর্তমান বস্তু বোঝায়
  • $this স্থির ফাংশন কল করতে ব্যবহার করা যেতে পারে
  • $thisস্ট্যাটিক সদস্য ভেরিয়েবলগুলি কল করতে ব্যবহার করা উচিত নয়। selfপরিবর্তে ব্যবহার করুন।
  • $this স্থির ফাংশন ভিতরে ব্যবহার করা যাবে না

26

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

সমস্যা হল আপনি প্রতিস্থাপন করতে পারেন হয় $this->method()সঙ্গে self::method(), যে কোন জায়গায় নির্বিশেষে যদি method()স্ট্যাটিক ঘোষিত বা করা হয় না। সুতরাং কোনটি আপনার ব্যবহার করা উচিত?

এই কোডটি বিবেচনা করুন:

class ParentClass {
    function test() {
        self::who();    // will output 'parent'
        $this->who();   // will output 'child'
    }

    function who() {
        echo 'parent';
    }
}

class ChildClass extends ParentClass {
    function who() {
        echo 'child';
    }
}

$obj = new ChildClass();
$obj->test();

এই উদাহরণস্বরূপ, self::who()সর্বদা 'পিতামাতার' আউটপুট আসবে, যখন $this->who()বস্তুর কী শ্রেণীর উপর নির্ভর করবে।

এখন আমরা দেখতে পাচ্ছি যে স্ব বলতে বোঝায় যে শ্রেণিকে এটি বলা হয়, আবার বর্তমান বস্তুর শ্রেণিকে$this বোঝায় ।

সুতরাং, আপনার কেবল তখনই স্ব ব্যবহার করা উচিত যখন $thisউপলভ্য না হয় বা আপনি যখন বংশধর শ্রেণিগুলিকে বর্তমান পদ্ধতিটি ওভাররাইট করার অনুমতি দিতে চান না।


22

শ্রেণীর সংজ্ঞাটির অভ্যন্তরে, $thisবর্তমান অবজেক্টকে বোঝায়, আবার বর্তমান বর্গকে selfবোঝায়।

এটি ব্যবহার করে কোনও শ্রেণীর উপাদান উল্লেখ করা প্রয়োজন এবং ব্যবহার করে selfকোনও অবজেক্ট উপাদান উল্লেখ করা দরকার $this

self::STAT // refer to a constant value
self::$stat // static variable
$this->stat // refer to an object variable  

21

অ-স্থিতিশীল এবং স্থিতিশীল সদস্য ভেরিয়েবলের জন্য এটি self এটির স্ব ব্যবহারের একটি উদাহরণ এখানে রয়েছে:

<?php
class X {
    private $non_static_member = 1;
    private static $static_member = 2;

    function __construct() {
        echo $this->non_static_member . ' '
           . self::$static_member;
    }
}

new X();
?> 

21

Http://www.php.net/manual/en/language.oop5.static.php এর মতে এখানে নেই $self। এখানে কেবলমাত্র $thisশ্রেণীর বর্তমান অবজেক্ট (অবজেক্ট) এবং স্বের উল্লেখ করার জন্য রয়েছে যা কোনও শ্রেণীর স্থির সদস্যদের উল্লেখ করতে ব্যবহার করা যেতে পারে। একটি বস্তুর উদাহরণ এবং শ্রেণীর মধ্যে পার্থক্য এখানে খেলতে আসে।


9
পরামর্শ: অ্যাসিডে ট্রিপ করার সময় এই উত্তরটি পড়ুন।
20

16

আমি বিশ্বাস করি যে প্রশ্নটি আপনি ক্লাসের স্থির সদস্যকে কল করে কল করতে পারেন কিনা তা নয় ClassName::staticMember। প্রশ্ন ছিল self::classmemberএবং ব্যবহারের মধ্যে পার্থক্য কি$this->classmember

উদাহরণস্বরূপ, নিম্নলিখিত দুটি উদাহরণই কোনও ত্রুটি ছাড়াই কাজ করে, আপনি ব্যবহার করুন self::বা না করুন$this->

class Person{
    private $name;
    private $address;

    public function __construct($new_name,$new_address){
        $this->name = $new_name;
        $this->address = $new_address;
    }
}

class Person{
    private $name;
    private $address;
    public function __construct($new_name,$new_address){
        self::$name = $new_name;
        self::$address = $new_address;
    }
}

এটি বিশেষত মজার যে আপনি "আপনার বিশ্বাস ক্লাসনাম :: স্ট্যাটিক মেম্বারকে কল করে ক্লাসের স্থিতিশীল সদস্যকে কল করতে পারবেন কিনা তা নয় বলে প্রশ্নটি আপনার উত্তরটি শুরু করে। প্রশ্নটি ছিল স্ব :: ক্লাসমেম্বার এবং $ এই-> ক্লাসমেম্বার ব্যবহারের মধ্যে পার্থক্য কী?" এবং তারপরে আপনি কোনও পার্থক্য দেখানোর জন্য এগিয়ে যান। প্রকৃতপক্ষে, আপনি দুটি বিকল্প দুটি যেখানে অভিন্নভাবে কাজ করে তার একটি উদাহরণ দেখান। -1
বাটল বাটকস

তবুও ব্যবহারিক। সুযোগটি রেজোলিউশন সম্পর্কে ছিল এবং এই অংশটি পিএইচপি ম্যানুয়ালটিতে পরিষ্কার নয়। আমি এখনও এটি দরকারী হিসাবে মনে করি
পুনর্নবীকরণ করুন

2
Fatal error: Access to undeclared static property: Person::$name in D:\LAMP\www\test.php on line 16
কে-গুণ

16

self বর্তমান বর্গ বোঝায় (যেখানে এটি বলা হয়),

$thisবর্তমান বস্তু বোঝায়। আপনি স্ব পরিবর্তে স্থির ব্যবহার করতে পারেন। উদাহরণ দেখুন:

    class ParentClass {
            function test() {
                    self::which();  // output 'parent'
                    $this->which(); // output 'child'
            }

            function which() {
                    echo 'parent';
            }
    }

    class ChildClass extends ParentClass {
            function which() {
                    echo 'child';
            }
    }

    $obj = new ChildClass();
    $obj->test();

আউটপুট: পিতামাতার সন্তান


16
  • অবজেক্ট পয়েন্টারটি $thisবর্তমান অবজেক্টকে বোঝায়।
  • শ্রেণীর মান staticবর্তমান অবজেক্টকে বোঝায়।
  • শ্রেণীর মান selfবলতে বোঝায় যে সঠিক শ্রেণিতে এটি সংজ্ঞায়িত হয়েছিল।
  • শ্রেণীর মানটি যে শ্রেণীর parentসংজ্ঞায়িত হয়েছিল তার পিতামাতাকে বোঝায়।

নিম্নোক্ত উদাহরণটি দেখুন যা ওভারলোডিং দেখায়।

<?php

class A {

    public static function newStaticClass()
    {
        return new static;
    }

    public static function newSelfClass()
    {
        return new self;
    }

    public function newThisClass()
    {
        return new $this;
    }
}

class B extends A
{
    public function newParentClass()
    {
        return new parent;
    }
}


$b = new B;

var_dump($b::newStaticClass()); // B
var_dump($b::newSelfClass()); // A because self belongs to "A"
var_dump($b->newThisClass()); // B
var_dump($b->newParentClass()); // A


class C extends B
{
    public static function newSelfClass()
    {
        return new self;
    }
}


$c = new C;

var_dump($c::newStaticClass()); // C
var_dump($c::newSelfClass()); // C because self now points to "C" class
var_dump($c->newThisClass()); // C
var_dump($b->newParentClass()); // A because parent was defined *way back* in class "B"

বেশিরভাগ সময় আপনি বর্তমান শ্রেণীর সাথে উল্লেখ করতে চান যা আপনি কেন ব্যবহার করেন staticবা করেন $this। যাইহোক, এমন সময় আছে যখন আপনার প্রয়োজন হয় self কারণ আপনি যা প্রসারিত তা নির্বিশেষে আপনি মূল বর্গ চান। (খুব, খুব কমই)


14

যেহেতু এখানে কেউ পারফরম্যান্স সম্পর্কে কথা বলেনি, আমি এখানে একটি ছোট বেঞ্চমার্ক (5.6) করেছি:

 Name     | Time    | Percent  
----------|---------|---------  
 $this->  | 0.99163 | 106.23%  
 self::   | 0.96912 | 103.82%  
 static:: | 0.93348 | 100%

এগুলি হ'ল 2 000 000 রানের ফলাফল এবং আমি ব্যবহার কোডটি এখানে:

<?php

require '../vendor/autoload.php';

// My small class to do benchmarks
// All it does is looping over every test x times and record the
//   time it takes using `microtime(true)`
// Then, the percentage is calculated, with 100% being the quickest
// Times are being rouned for outputting only, not to calculate the percentages
$b = new Tleb\Benchmark\Benchmark(2000000);

class Foo
{
    public function calling_this()
    {
        $this->called();
    }

    public function calling_self()
    {
        self::called();
    }

    public function calling_static()
    {
        static::called();
    }

    public static function called()
    {
    }
}

$b->add('$this->',  function () { $foo = new Foo; $foo->calling_this(); });
$b->add('self::',   function () { $foo = new Foo; $foo->calling_self(); });
$b->add('static::', function () { $foo = new Foo; $foo->calling_static(); });

$b->run();

1
নো-অপশন ফাংশন 2 000 000 বার কল করা 1 সেকেন্ড স্থায়ী হয়। পিএইচপি ভালোবাসি।
rr-

ভাল পুরানো পিএইচপি। :) তবে একটি কল = 0.001 মিমি। এটা কি খারাপ?
tleb

আমি বিশ্বাস করি এটি (এবং অনুরূপ জিনিস) এজন্যই ওআরএম এর মতো জিনিসগুলি ধীরে ধীরে অনুভূত হয় যতক্ষণ না আপনি স্টাফকে ক্যাশে করেন এবং স্থিতিশীল সাইট জেনারেটর কোনও জিনিস না।
আরআর-

2
তাত্ত্বিকভাবে এটিতে 1 টি প্রসেসর ক্লক চক্র নেওয়া উচিত, যা 1 / 2e9 s = 0.5 nsএই দিনগুলিতে প্রায় তৈরি করে
বুডি

শুধু আমার উত্তর পুনরায় পড়ুন। সতর্কতা অবলম্বন করুন: এটি ক্লাসটিও তৈরি করে । আমি কী useশব্দটি টিবিএইচ ব্যবহার করিনি কেন জানি না , তবে একটি বেঞ্চমার্কটি আবার করতে আমার পিএইচপি নেই, এবং সত্যিই এটি পুনরায় ইনস্টল করার মতো মনে হয় না।
tleb

13

অপারেটরের selfসাথে কখন ব্যবহৃত ::হয় এটি বর্তমান বর্গকে বোঝায়, যা স্থির এবং অ স্থিতি প্রসঙ্গে উভয় ক্ষেত্রেই করা যায়। $thisবস্তু নিজেই বোঝায়। তদ্ব্যতীত, $thisস্থির পদ্ধতি কল করতে ব্যবহার করা পুরোপুরি আইনী (তবে ক্ষেত্রগুলি উল্লেখ না করে)।


8

আমি একই প্রশ্নে ছুটে এসেছি এবং এর সহজ উত্তরটি হ'ল:

  • $this শ্রেণীর উদাহরণ প্রয়োজন
  • self:: না

আপনি যখনই স্থিতিশীল পদ্ধতি বা স্থিত বৈশিষ্ট্য ব্যবহার করছেন এবং শ্রেণি ইনস্ট্যান্টিয়েটেডের কোনও অবজেক্ট ছাড়াই তাদের কল করতে চান তাদের কল করার জন্য আপনাকে অবশ্যই ব্যবহার self:করতে হবে কারণ $thisসর্বদা অবজেক্টে তৈরি হওয়া প্রয়োজন requires


7

$this বর্তমান শ্রেণীর অবজেক্টকে বোঝায়, self বোঝায় বোঝায় (বস্তু নয়)। বর্গ হ'ল বস্তুর নীলনকশা। সুতরাং আপনি একটি শ্রেণি সংজ্ঞায়িত করেন তবে আপনি বস্তুগুলি তৈরি করেন।

সুতরাং অন্য কথায়, ব্যবহার self for staticএবংthis for none-static members or methods

এছাড়াও শিশু / পিতামাতার দৃশ্যে self / parentবেশিরভাগ ক্ষেত্রে শিশু এবং অভিভাবক শ্রেণীর সদস্য এবং পদ্ধতিগুলি চিহ্নিত করতে ব্যবহৃত হয়।


7

অতিরিক্ত হিসাবে থেকে $this::এখনও আলোচনা করা হয়নি।

কেবলমাত্র তথ্যগত উদ্দেশ্যে, বর্তমান স্কোপ মানটি ব্যবহারের জন্য তাত্ক্ষণিক বস্তুগুলির সাথে কাজ করার সময় পিএইচপি 5.3 হিসাবে static::, ব্যবহারের বিপরীতে , বিকল্প হিসাবে এর $this::মতো ব্যবহার করা যেতে পারে।

http://ideone.com/7etRHy

class Foo
{
    const NAME = 'Foo';

    //Always Foo::NAME (Foo) due to self
    protected static $staticName = self::NAME;

    public function __construct()
    {
        echo $this::NAME;
    }

    public function getStaticName()
    {
       echo $this::$staticName;
    }
}

class Bar extends Foo
{
    const NAME = 'FooBar';

    /**
     * override getStaticName to output Bar::NAME
     */
    public function getStaticName()
    {
        $this::$staticName = $this::NAME;
        parent::getStaticName();
    }
}

$foo = new Foo; //outputs Foo
$bar = new Bar; //outputs FooBar
$foo->getStaticName(); //outputs Foo
$bar->getStaticName(); //outputs FooBar
$foo->getStaticName(); //outputs FooBar

উপরের কোডটি ব্যবহার করা সাধারণ বা প্রস্তাবিত অনুশীলন নয়, তবে কেবল এর ব্যবহারটি চিত্রিত করার জন্য এবং "আপনি কি জানেন?" মূল পোস্টারের প্রশ্নের প্রসঙ্গে।

এটি যেমন এর বিরোধিতা হিসাবে $object::CONSTANTউদাহরণস্বরূপ ব্যবহারের প্রতিনিধিত্ব করেecho $foo::NAME;$this::NAME;


5

selfআপনি যদি সেই শ্রেণীর কোনও অবজেক্ট / উদাহরণ তৈরি না করে কোনও শ্রেণীর কোনও পদ্ধতিতে কল করতে চান তবে ব্যবহার করুন যদি এইভাবে র‌্যাম সংরক্ষণ করা হয় (কখনও কখনও সেই উদ্দেশ্যে স্ব ব্যবহার করুন)। অন্য কথায়, এটি আসলে কোনও পদ্ধতিকে স্ট্যাটিকভাবে কল করে। thisঅবজেক্ট দৃষ্টিকোণ জন্য ব্যবহার করুন ।


2

কেস 1: selfক্লাস ধ্রুবকগুলির জন্য ব্যবহার করা যেতে পারে

 ক্লাস ক্লাসএ { 
     কনস্ট FIXED_NUMBER = 4; 
     স্ব :: POUNDS_TO_KILOGRAMS
}

আপনি যদি এটি ক্লাসের বাইরে কল করতে চান classA::POUNDS_TO_KILOGRAMSতবে ধ্রুবকগুলি অ্যাক্সেস করতে ব্যবহার করুন

কেস 2: অচল সম্পত্তি জন্য

ক্লাস ক্লাসসি {
     পাবলিক ফাংশন __ কনস্ট্রাক্ট () { 
     স্ব :: $: _ কাউন্টার ++,; $ এই-> নাম = স্ব :: $ _ কাউন্টার;
   }
}

1

Php.net মতে এই প্রেক্ষাপটে তিন বিশেষ কীওয়ার্ড আছে: self, parentএবং static। এগুলি শ্রেণীর সংজ্ঞার ভিতরে থেকে বৈশিষ্ট্য বা পদ্ধতিগুলি অ্যাক্সেস করতে ব্যবহৃত হয়।

$thisঅন্যদিকে, যে কোনও শ্রেণীর অ্যাক্সেসযোগ্য ততক্ষণ কোনও ক্লাসের উদাহরণ এবং পদ্ধতিগুলি কল করতে ব্যবহৃত হয়।


-1

স্ব :: ::  বর্তমান শ্রেণীর জন্য ব্যবহৃত মূলশব্দ এবং মূলত এটি স্ট্যাটিক সদস্য, পদ্ধতি এবং ধ্রুবক অ্যাক্সেস করতে ব্যবহৃত হয়। কিন্তু ক্ষেত্রে এই $ আপনি স্ট্যাটিক সদস্য পদ্ধতি এবং ফাংশন কল করতে পারবেন না।

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

নীচে দেওয়া কোডটি স্ব :: এবং $ এই কীওয়ার্ডের একটি উদাহরণ । আপনার কোড ফাইলটিতে কোডটি কেবল অনুলিপি করুন এবং আটকান এবং আউটপুট দেখুন।

class cars{
    var $doors=4;   
    static $car_wheel=4;

  public function car_features(){
    echo $this->doors." Doors <br>";
    echo self::$car_wheel." Wheels <br>"; 
  }
}

class spec extends cars{
    function car_spec(){
        print(self::$car_wheel." Doors <br>");
        print($this->doors." Wheels <br>");
    }
}

/********Parent class output*********/

$car = new cars;
print_r($car->car_features());

echo "------------------------<br>";

/********Extend class from another class output**********/


$car_spec_show=new spec;

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