কোনও উদাহরণের শ্রেণি একটি ইন্টারফেস প্রয়োগ করে কিনা তা পরীক্ষা করা হচ্ছে?


148

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

উত্তর:


258
interface IInterface
{
}

class TheClass implements IInterface
{
}

$cls = new TheClass();
if ($cls instanceof IInterface) {
    echo "yes";
}

আপনি "উদাহরণস্বরূপ" অপারেটরটি ব্যবহার করতে পারেন। এটি ব্যবহার করতে, বাম অপারেন্ডটি একটি শ্রেণীর উদাহরণ এবং ডান অপারেন্ড একটি ইন্টারফেস। যদি বস্তুটি একটি নির্দিষ্ট ইন্টারফেস প্রয়োগ করে তবে এটি সত্য হয়।


102

হিসাবে therefromhere পয়েন্ট আউট, আপনি ব্যবহার করতে পারেন class_implements()। প্রতিবিম্বের মতো, এটি আপনাকে শ্রেণীর নামটিকে স্ট্রিং হিসাবে নির্দিষ্ট করতে দেয় এবং শ্রেণীর কোনও উদাহরণের প্রয়োজন হয় না:

interface IInterface
{
}

class TheClass implements IInterface
{
}

$interfaces = class_implements('TheClass');

if (isset($interfaces['IInterface'])) {
    echo "Yes!";
}

class_implements() এসপিএল এক্সটেনশনের অংশ।

দেখুন: http://php.net/manual/en/function.class-implements.php

পারফরম্যান্স টেস্ট

কিছু সাধারণ পারফরম্যান্স পরীক্ষা প্রতিটি পদ্ধতির ব্যয় দেখায়:

কোনও বস্তুর উদাহরণ দেওয়া হয়েছে

লুপের বাইরে অবজেক্ট নির্মাণ (100,000 পুনরাবৃত্তি)
 ____________________________________________
| ক্লাস_প্রাপ্তি | প্রতিচ্ছবি | উদাহরণস্বরূপ |
| ------------------ | ------------ | ------------ |
| 140 এমএস | 290 এমএস | 35 এমএস |
'--------------------------------------------'

লুপের ভিতরে অবজেক্ট নির্মাণ (100,000 পুনরাবৃত্তি)
 ____________________________________________
| ক্লাস_প্রাপ্তি | প্রতিচ্ছবি | উদাহরণস্বরূপ |
| ------------------ | ------------ | ------------ |
| 182 এমএস | 340 এমএস | 83 এমএস | সস্তা কন্সট্রাক্টর
| 431 এমএস | 607 এমএস | 338 এমএস | ব্যয়বহুল নির্মাণকারী
'--------------------------------------------'

শুধুমাত্র একটি শ্রেণীর নাম দেওয়া হয়েছে

100,000 পুনরাবৃত্তি
 ____________________________________________
| ক্লাস_প্রাপ্তি | প্রতিচ্ছবি | উদাহরণস্বরূপ |
| ------------------ | ------------ | ------------ |
| 149 এমএস | 295 এমএস | এন / এ |
'--------------------------------------------'

ব্যয়বহুল __ কনস্ট্রাক্ট () কোথায়:

public function __construct() {
    $tmp = array(
        'foo' => 'bar',
        'this' => 'that'
    );  

    $in = in_array('those', $tmp);
}

এই পরীক্ষাগুলি এই সাধারণ কোডের উপর ভিত্তি করে ।


56

nlaq নির্দেশ করে যে instanceofপরীক্ষা করতে ব্যবহার করা যেতে পারে যদি বস্তুটি কোনও শ্রেণীর উদাহরণ যা ইন্টারফেস প্রয়োগ করে।

কিন্তু instanceofশ্রেণীর ধরণ এবং একটি ইন্টারফেসের মধ্যে পার্থক্য করে না। আপনি জানেন না যে বস্তুটি এমন একটি শ্রেণি যা কল করার জন্য ঘটে IInterface

এটি আরও সুনির্দিষ্টভাবে পরীক্ষা করতে আপনি পিএইচপি-তে প্রতিবিম্ব এপিআই ব্যবহার করতে পারেন:

$class = new ReflectionClass('TheClass');
if ($class->implementsInterface('IInterface'))
{
  print "Yep!\n";
}

Http://php.net/manual/en/book.reflection.php দেখুন


2
এটি "স্ট্যাটিক" ক্লাসে ব্যবহার করা যেতে পারে
জ্নারকাস

6

@ এখানে থেকে: ধন্যবাদ, ভাল টিপস। এটি এসপিএল এক্সটেনশনের অংশ। আমার উত্তরটি প্রতিবিম্ব এক্সটেনশন ব্যবহার করেছে।
বিল কারভিন

3
আপনি যদি একই জায়গার সাথে ইন্টারফেস এবং ক্লাসগুলির মধ্যে অস্পষ্টতা না থাকায় নেমস্পেস ব্যবহার করেন এবং আপনি নিরাপদে instanceofআবার ব্যবহার করতে পারেন ।
ফ্লু

class_implements()ক্লাস_আইপ্লিমেন্টগুলি কল করা এবং তারপরে ইন_আরে, সম্পূর্ণ প্রতিবিম্বের পরিবর্তে স্পষ্টতই দ্রুত কল্পনা করার জন্য +1
নিকোলাস

19

কেবলমাত্র ভবিষ্যতের অনুসন্ধানগুলিতে সহায়তা করার জন্য is_susclass_of একটি ভাল বৈকল্পিক (পিএইচপি 5.3.7+ এর জন্য):

if (is_subclass_of($my_class_instance, 'ISomeInterfaceName')){
    echo 'I can do it!';
}

5

আপনি নিম্নলিখিতগুলিও করতে পারেন

public function yourMethod(YourInterface $objectSupposedToBeImplementing) {
   //.....
}

ইন্টারফেস $objectSupposedToBeImplementingবাস্তবায়ন না করলে এটি পুনরুদ্ধারযোগ্য ত্রুটি ছুঁড়ে দেবে YourInterface


3

হালনাগাদ

is_a ফাংশন বিকল্প হিসেবে এখানে অনুপস্থিত।

আমি বর্ণিত উপায়গুলির মধ্যে কোনটি সবচেয়ে পারফরম্যান্ট তা পরীক্ষা করে দেখার জন্য আমি কিছু পারফরম্যান্স টেস্ট করেছি।

100k পুনরাবৃত্তির উপরে ফলাফল

      instanceof [object] took   7.67 ms | +  0% | ..........
            is_a [object] took  12.30 ms | + 60% | ................
             is_a [class] took  17.43 ms | +127% | ......................
class_implements [object] took  28.37 ms | +270% | ....................................
       reflection [class] took  34.17 ms | +346% | ............................................

পার্থক্যটি দেখতে আসলে কিছু "বিন্দু" যুক্ত করা হয়েছে ots

এর দ্বারা উত্পন্ন: https://3v4l.org/8Cog7

উপসংহার

আপনার যদি চেক করার কোনও বিষয়instance of থাকে তবে গ্রহণযোগ্য উত্তরে উল্লিখিত মতো ব্যবহার করুন ।

আপনার যদি চেক করার জন্য ক্লাস থাকে তবে ব্যবহার করুন is_a

বোনাস

আপনি যে ইন্টারফেসটি থাকা দরকার তার উপর ভিত্তি করে কোনও শ্রেণি ইনস্ট্যান্ট করতে চান সেই ক্ষেত্রে এটি ব্যবহার করা আরও পূর্বের is_a। কেবল একটি ব্যতিক্রম আছে - যখন কনস্ট্রাক্টর খালি থাকে।

উদাহরণ: is_a(<className>, <interfaceName>, true);

এটি ফিরে আসবে bool। তৃতীয় প্যারামিটারটি " allow_string " এটা বর্গ নাম পরীক্ষা করতে পারবেন ছাড়া বর্গ শুরু করতে গিয়ে।

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