এটি একটি দীর্ঘ, দুঃখের গল্প।
যখন পিএইচপি 5.2 প্রথম এই সতর্কবার্তাটি প্রবর্তন করেছিল, দেরীতে স্থির বাইন্ডিংগুলি এখনও ভাষায় ছিল না। আপনি যদি দেরিতে স্থির বাইন্ডিংগুলির সাথে পরিচিত না হন তবে নোট করুন যে এর মতো কোডটি আপনার প্রত্যাশার মতো কাজ করে না:
<?php
abstract class ParentClass {
static function foo() {
echo "I'm gonna do bar()";
self::bar();
}
abstract static function bar();
}
class ChildClass extends ParentClass {
static function bar() {
echo "Hello, World!";
}
}
ChildClass::foo();
কঠোর মোডের সতর্কতাটি বাদ দিয়ে উপরের কোডটি কার্যকর করে না। self::bar()
কল foo()
স্পষ্টভাবে উল্লেখ bar()
পদ্ধতি ParentClass
, এমনকি যখন foo()
একটি পদ্ধতি হিসাবে বলা হয় ChildClass
। আপনি যদি এই কোডটি কঠোর মোড বন্ধ করে চালানোর চেষ্টা করেন, আপনি দেখতে পাবেন " পিএইচপি মারাত্মক ত্রুটি: বিমূর্ত পদ্ধতিটি প্যারেন্টক্লাস :: বার () " কল করতে পারবেন না ।
এটি দেওয়া হয়েছে, পিএইচপি 5.2 এ বিমূর্ত স্থির পদ্ধতিগুলি অকেজো ছিল। সমগ্র বিন্দু এবং তারপর বিভিন্ন শিশু শ্রেণীর বিভিন্ন বাস্তবায়নের প্রদান - একটি বিমূর্ত পদ্ধতি ব্যবহার করে যে আপনি কোড যে বুদ্ধিমান কি বাস্তবায়ন এটি আহ্বান হতে যাচ্ছে ছাড়া মেথড কল করে লিখতে পারেন। তবে যেহেতু পিএইচপি 5.2 কোনও অভিভাবক শ্রেণীর এমন কোনও পদ্ধতি লেখার পক্ষে কোনও পরিষ্কার উপায় অফার করে না যা শিশু শ্রেণীর একটি স্ট্যাটিক পদ্ধতি বলে যার উপর এটি ডাকা হয়, তাই বিমূর্ত স্থির পদ্ধতির এই ব্যবহার সম্ভব নয়। সুতরাং abstract static
পিএইচপি 5.2 এর যে কোনও ব্যবহারই খারাপ কোড, সম্ভবত self
কীওয়ার্ডটি কীভাবে কাজ করে তার একটি ভুল বোঝাবুঝি দ্বারা অনুপ্রাণিত হয় । এটি সম্পর্কে একটি সতর্কতা নিক্ষেপ করা সম্পূর্ণ যুক্তিসঙ্গত ছিল।
কিন্তু তারপরে পিএইচপি 5.3 ক্লাসটির সাথে উল্লেখ করার সক্ষমতা যুক্ত করেছিল যার উপর static
কীওয়ার্ডের মাধ্যমে একটি পদ্ধতি আহ্বান করা হয়েছিল (কীওয়ার্ডের বিপরীতে self
, যা সর্বদা ক্লাসকে বোঝায় যেখানে পদ্ধতিটি সংজ্ঞায়িত করা হয়েছিল )। আপনি যদি আমার উপরের উদাহরণে পরিবর্তন self::bar()
করেন তবে static::bar()
এটি পিএইচপি 5.3 এবং তার উপরের ক্ষেত্রে দুর্দান্ত কাজ করে। আপনি সম্বন্ধে আরও পড়তে পারেন self
বনাম static
এ নিউ স্ব বনাম নতুন স্ট্যাটিক ।
স্থির কীওয়ার্ড যুক্ত হওয়ার সাথে abstract static
একটি সতর্কতা নিক্ষেপ করার স্পষ্ট যুক্তি চলে গেল। দেরীতে স্ট্যাটিক বাইন্ডিংয়ের মূল উদ্দেশ্যটি পিতামাতার শ্রেণিতে সংজ্ঞায়িত পদ্ধতিগুলিকে স্থির পদ্ধতিগুলি কল করতে অনুমতি দেওয়া ছিল যা শিশু শ্রেণিতে সংজ্ঞায়িত করা হত; বিমূর্ত স্ট্যাটিক পদ্ধতিগুলিকে মঞ্জুরি দেওয়া অস্তিত্বের দেরিতে স্থির বাইন্ডিংগুলি যুক্তিসঙ্গত এবং সামঞ্জস্যপূর্ণ বলে মনে হয়।
আমার ধারণা, আপনি এখনও সতর্কতা রাখার জন্য একটি মামলা করতে পারেন। উদাহরণস্বরূপ, আপনি তর্ক করতে পারেন যেহেতু পিএইচপি আপনাকে বিমূর্ত ক্লাসগুলির স্থির পদ্ধতিগুলি কল করতে দেয়, উপরের আমার উদাহরণে (এমনকি এটি প্রতিস্থাপনের self
মাধ্যমে এটি ঠিক করার পরেও static
) আপনি একটি পাবলিক পদ্ধতি প্রকাশ করছেন ParentClass::foo()
যা ভাঙা হয়েছে এবং আপনি সত্যই চান না প্রকাশ করা. একটি স্থিতিশীল শ্রেণি ব্যবহার না করে - যা সমস্ত পদ্ধতির উদাহরণ পদ্ধতি তৈরি করে এবং সকলের বাচ্চাকে ParentClass
একক বা কিছু হতে পারে - এই সমস্যাটি সমাধান করবে, যেহেতু ParentClass
, বিমূর্ত হয়ে, তাত্ক্ষণিকভাবে কার্যকর করা যায় না এবং তাই এর উদাহরণ পদ্ধতিগুলি পারে না ডাকা হবে. আমি মনে করি এই যুক্তিটি দুর্বল (কারণ আমি প্রকাশ করি বলে মনে করিParentClass::foo()
কোনও বড় বিষয় নয় এবং স্ট্যাটিক ক্লাসের পরিবর্তে সিঙ্গেলন ব্যবহার করা প্রায়শই অকারণে ভার্বোস এবং কুরুচিপূর্ণ) তবে আপনি যুক্তিযুক্তরূপে একমত হতে পারেন - এটি কিছুটা বিষয়বস্তু কল।
সুতরাং এই যুক্তির উপর ভিত্তি করে, পিএইচপি ডেভেলস ভাষাতে সতর্কতা রেখেছিল, তাই না?
ওহো, ঠিক ।
পিএইচপি বাগ রিপোর্ট 53081, উপরে লিঙ্কযুক্ত, সতর্কতাটি বাদ দেওয়ার জন্য বলা হয়েছে কারণ নির্মাণটি সংযোজন static::foo()
বিমূর্ত স্ট্যাটিক পদ্ধতিগুলি যুক্তিসঙ্গত এবং দরকারী করেছে। রাসমাস লেয়ারডর্ফ (পিএইচপি-র স্রষ্টা) অনুরোধটিকে বোগাস হিসাবে লেবেল করে শুরু করে এবং সতর্কতাটিকে ন্যায়সঙ্গত করার চেষ্টা করার জন্য দীর্ঘ যুক্তিযুক্ত যুক্তির মধ্য দিয়ে যায়। তারপরে, অবশেষে, এই বিনিময়টি ঘটে:
জর্জিও
আমি জানি কিন্তু:
abstract class cA
{
//static function A(){self::B();} error, undefined method
static function A(){static::B();} // good
abstract static function B();
}
class cB extends cA
{
static function B(){echo "ok";}
}
cB::A();
Rasmus
ঠিক আছে, এটি ঠিক কাজ করা উচিত।
জর্জিও
তবে এটি অনুমোদিত নয় :(
Rasmus
কি অনুমতি নেই?
abstract class cA {
static function A(){static::B();}
abstract static function B();
}
class cB extends cA {
static function B(){echo "ok";}
}
cB::A();
এটি কাজ করে। আপনি অবশ্যই স্ব :: বি () কল করতে পারবেন না, তবে স্থির :: বি () ভাল fine
রাসমাসের দাবি যে তার উদাহরণে কোড "ভাল কাজ করে" মিথ্যা; যেমনটি আপনি জানেন, এটি একটি কঠোর মোড সতর্কতা নিক্ষেপ করে। আমার ধারণা তিনি কঠোর মোড চালু না করেই পরীক্ষা করছিলেন। নির্বিশেষে, একটি বিভ্রান্তিত রাসমাস অনুরোধটি ভুলভাবে "বোগাস" হিসাবে বন্ধ করে দিয়েছে।
এবং সেই কারণেই সতর্কতা এখনও ভাষাতেই রয়েছে in এটি পুরোপুরি সন্তোষজনক ব্যাখ্যা নাও হতে পারে - আপনি সম্ভবত এখানে এসে আশা করেছিলেন যে সতর্কতার যৌক্তিক ন্যায়সঙ্গততা রয়েছে। দুর্ভাগ্যক্রমে, আসল বিশ্বে, কখনও কখনও পছন্দগুলি যৌক্তিক সিদ্ধান্ত গ্রহণের পরিবর্তে জাগতিক ভুল এবং খারাপ যুক্তি থেকে জন্ম নেয়। এটি কেবল সেই সময়ের মধ্যে একটি।
ভাগ্যক্রমে, অনুমানযোগ্য নিকিতা পপভ পিএইচপি আরএফসির অংশ হিসাবে পিএইচপি 7 তে ভাষা থেকে এই সতর্কতাটি সরিয়ে দিয়েছেন : E_STRICT নোটিশগুলির পুনরায় শ্রেণিবদ্ধ করুন । শেষ পর্যন্ত, বিচক্ষণতা বিরাজ করছে এবং একবার পিএইচপি 7 প্রকাশিত হলে আমরা সকলেই abstract static
এই নির্বোধ সতর্কতা না পেয়ে আনন্দের সাথে ব্যবহার করতে পারি ।