Is_a और Instof के बीच क्या अंतर है?


205

मैं इसके बारे में जागरूक हूं instanceof एक ऑपरेटर है और is_aयह एक तरीका है।

क्या प्रदर्शन में विधि धीमी है? आप क्या उपयोग करना पसंद करेंगे?


15
is_a () धीमा हो सकता है - लेकिन आप इसे call_user_func () का उपयोग करके कॉल कर सकते हैं जबकि
Instof

जवाबों:


211

अपडेट करें

PHP 5.3.9 के रूप में , कार्यक्षमता is_a()बदल गई है। नीचे दिए गए मूल उत्तर में कहा गया है कि पहले तर्क के रूप में स्वीकार is_a() करना चाहिएObject , लेकिन PHP संस्करण> = 5.3.9 अब स्ट्रिंग वर्ग के नामों की तुलना करने के $allow_stringलिए वैकल्पिक तीसरा बूलियन तर्क (चूक false) स्वीकार करते हैं :

class MyBaseClass {}
class MyExtendingClass extends MyBaseClass {}

// Original behavior, evaluates to false.
is_a(MyExtendingClass::class, MyBaseClass::class);

// New behavior, evaluates to true.
is_a(MyExtendingClass::class, MyBaseClass::class, true);

के बीच नए व्यवहार में महत्वपूर्ण अंतर है instanceofऔर is_a()वह instanceofहमेशा यह जांच करेगा कि लक्ष्य निर्दिष्ट वर्ग (त्वरित कक्षाओं सहित) की एक तात्कालिक वस्तु है, जबकि is_a()केवल यह आवश्यक है कि $allow_stringतर्क के डिफ़ॉल्ट मान पर सेट होने पर वस्तु को तत्काल किया जाए false


मूल

दरअसल, is_aएक फ़ंक्शन है, जबकि instanceofएक भाषा निर्माण है। is_aकाफी धीमी हो जाएगी (क्योंकि इसमें फंक्शन कॉल निष्पादित करने के सभी ओवरहेड हैं), लेकिन समग्र निष्पादन समय या तो विधि में न्यूनतम है।

यह अब 5.3 के रूप में नहीं निकाला गया है, इसलिए वहां कोई चिंता नहीं है।

हालांकि एक अंतर है। is_aएक फंक्शन होने के लिए पैरामीटर 1 के रूप में एक ऑब्जेक्ट लेता है, और एक स्ट्रिंग (चर, स्थिर, या शाब्दिक) पैरामीटर 2 के रूप में। So:

is_a($object, $string); // <- Only way to call it

instanceof पैरामीटर 1 के रूप में एक वस्तु लेता है, और पैरामीटर 2 के रूप में एक वर्ग नाम (चर), वस्तु उदाहरण (चर), या वर्ग पहचानकर्ता (उद्धरण के बिना वर्ग नाम) ले सकता है।

$object instanceof $string;      // <- string class name
$object instanceof $otherObject; // <- object instance
$object instanceof ClassName;    // <- identifier for the class

36
is_aअनिर्दिष्ट क्यों था ?
थियोडोर आर। स्मिथ

21
@ theodore-r-smith प्रलेखन के अनुसार "यह" लोकप्रिय अनुरोध "" php.net/manual/en/migration53.undeprecated.php
Janci

3
@ दनिप$class = 'Foo'; var_dump($obj instanceof $class);
ircmaxell

39
is_aबनाम instanceofऑपरेटर के बारे में ध्यान देने वाली एक और बात यह है कि is_aदूसरे पैरामीटर के लिए अभिव्यक्ति को स्वीकार करेंगे, जबकि उदाहरण के लिए अभ्यस्त। उदाहरण के लिए is_a($object, 'Prefix_'.$name)काम करता है, जबकि $object instanceof 'Prefix_'.$nameनहीं
इवान पुरखिसर

6
is_aकभी भी पहले स्थान पर पदावनत नहीं होना चाहिए था। हालांकि इसे ठीक करने में अभी थोड़ी देर है। समस्या यह है कि instanceofऑपरेटर PHP 4 में वाक्यविन्यास त्रुटियों को फेंकता है, और जब से is_aऑपरेटर को पेश किया गया था ठीक उसी समय हटा दिया गया था जब PHP 4 और 5 दोनों के लिए एक E_STRICT फेंकने के बिना कोड लिखना असंभव हो गया था। तुम भी नहीं कर सकते if (version_compare(PHP_VERSION, 5) >= 0) { /* use instanceof */ } else { /* use is_a */ }क्योंकि यह अभी भी PHP 4 में एक वाक्यविन्यास त्रुटि का कारण होगा
meustrus

47

यहाँ is_a () और उदाहरण के प्रदर्शन परिणाम हैं :

Test name       Repeats         Result          Performance     
instanceof      10000           0.028343 sec    +0.00%
is_a()          10000           0.043927 sec    -54.98%

परीक्षण स्रोत यहाँ है


6
दूसरे शब्दों में, अंतर केवल महत्वपूर्ण है अगर आपको प्रति 10000 उपयोगों पर ~ 0.015 सेकंड बचाने की आवश्यकता है।
सीजे डेनिस

1
जैसा कि php 7कोई अंतर नहीं है।
अधिकतम

@CJDennis अनुभव से, जब हर कोई इस तरह से सोचता है, तो अंतिम उत्पाद उम्मीद से धीमा होगा। (सॉफ्ट + OS + सर्वरों को अडॉप्ट किया हुआ)। याद रखें कि जोड़ा गया समय हमेशा रैखिक नहीं होता है, लेकिन घातीय हो सकता है। हमेशा मन में परिपूर्णता रखें।
टोटो

@Toto एक उत्कृष्ट ब्लॉग पोस्ट है जो अनुभवी डेवलपर्स शुरुआती से सीख सकते हैं। उम्मीद है कि आप इसे शीर्ष दाईं ओर देख सकते हैं। समय से पहले अनुकूलन से सावधान रहें! वे समस्याएँ बनने के बाद ही समय की समस्याओं को हल करें ! यदि प्रदर्शन स्वीकार्य है, तो इसे बदलने में समय व्यतीत न करें!
सीजे डेनिस

10

instanceofअन्य वस्तु उदाहरणों के साथ प्रयोग किया जा सकता है, वर्ग का नाम, या इंटरफ़ेस। मुझे नहीं लगता कि is_a()इंटरफेस के साथ काम करता है (केवल एक स्ट्रिंग एक वर्ग नाम का प्रतिनिधित्व करता है), लेकिन मुझे सही करता है अगर यह करता है। (अपडेट: देखें https://gist.github.com/1455148 )

Php.net से उदाहरण :

interface MyInterface
{
}

class MyClass implements MyInterface
{
}

$a = new MyClass;
$b = new MyClass;
$c = 'MyClass';
$d = 'NotMyClass';

var_dump($a instanceof $b); // $b is an object of class MyClass
var_dump($a instanceof $c); // $c is a string 'MyClass'
var_dump($a instanceof $d); // $d is a string 'NotMyClass'

आउटपुट:

bool(true)
bool(true)
bool(false)

3
is_aउसी तरह से इंटरफेस के साथ काम करता है instanceof( जैसा कि मैं एक ही बात कहने जा रहा था, लेकिन मैंने सबमिट करने से पहले इसकी जांच की, और यह वास्तव में काम करता है) ...
ircmaxell

2
-1 कृपया केवल एक जिस्ट से लिंक करने के बजाय अपडेट को सारांशित करें। जो सीखने की कोशिश कर रहे लोगों के लिए अनहोनी है।
एरिक रॉबर्टसन

5

क्रिसफ के जवाब के संबंध में, is_a() अब PHP 5.3.0 के रूप में पदावनत नहीं किया गया है । मुझे लगता है कि इस तरह की चीजों के लिए आधिकारिक स्रोत द्वारा जाना हमेशा सुरक्षित होता है।

आपके प्रश्न के संबंध में, डैनियल, मैं प्रदर्शन मतभेदों के बारे में नहीं कह सकता, लेकिन इसका कुछ हिस्सा पठनीयता तक कम हो जाएगा और जिसे आप के साथ काम करना आसान लगता है।

इसके अलावा, चेक बनाम को नकारने के बारे में भ्रम के बारे में कुछ चर्चा है । उदाहरण के लिए, आप करेंगे:instanceofis_a()instanceof

<?php
if( !($a instanceof A) ) { //... }
?>

निम्नलिखित के लिए बनाम is_a():

<?php
if( !is_a($a, 'A' ) { //... }
?>

या

<?php
if( is_a($a, 'A') === FALSE) { //... }
?>

एडिट लुक्स ऐसा लगता है जैसे क्रिसएफ ने अपना उत्तर हटा दिया, लेकिन मेरे जवाब का पहला हिस्सा अभी भी खड़ा है।


5

गति के अलावा, एक और महत्वपूर्ण अंतर यह है कि वे किनारे के मामलों को कैसे संभालते हैं।

is_a($x1, $x2) // fatal error if x2 is not a string nor an object
$x1 instanceof $x2  // returns false even if $x2 is int, undefined, etc.

तो, is_a () संभव बग को हाइलाइट करता है जबकि Instof उन्हें दबा देता है।


2

अनुकूलन न्यूनतम है। और कोड की पठनीयता, समझ और स्थिरता के सामने सूक्ष्म-अनुकूलन कभी भी वास्तविक अच्छा उत्तर नहीं होता है।

(Personaly मैं prefere instanceof , लेकिन पसंद आपकी है;))

मुख्य अंतर संभावना के साथ सीधे वर्ग के नाम का उपयोग है instanceof

$ एक उदाहरण MyClass

से छोटा है

is_a ($ a, MyClass :: वर्ग)

(ठीक है ... यह तुच्छ नहीं है।)

Instof (भाषा संरचना) और is_a के बीच वाक्यविन्यास रंग उपयोगी है (मेरे लिए) भी। बड़े कार्यों के लिए फ़ंक्शन रंग दे रहा है। और अगर में एकल उपयोग के लिए, Instof अधिक कोष्ठक की जरूरत नहीं है।

नोट: निश्चित रूप से MyClass :: वर्ग के बजाय आप एक छोटी सी सीधी स्ट्रिंग का उपयोग कर सकते हैं:

is_a ($ एक, 'MyClass')

लेकिन एक कोड में सीधे स्ट्रिंग का उपयोग करना एक अच्छा अभ्यास नहीं है

यदि आप सरल स्ट्रिंग और वर्गों के नामों के बीच अंतर कर सकते हैं, तो वाक्यविन्यास टकराव बेहतर और अधिक उपयोगी है। और निरंतर क्लासनाम के साथ नाम बदलना आसान है। विशेष यदि आप उपनाम के साथ नाम स्थान का उपयोग करते हैं।

तो, wy उपयोग is_a () है ?

एक ही सामंजस्य के लिए: पठनीयता और निस्संदेहता। (चुनाव तुम्हारा है) जब इस्तेमाल के साथ स्पेशल ! या अन्य बूलियन ऑपरेटर: is_a कोष्ठक के साथ अधिक लगता है।

अगर ($ a और (is_a ($ a, MyClass :: class) या is_a ($ a, MyOtherClass :: class))

से अधिक पठनीय है:

अगर ($ a और (! ($ एक उदाहरण MyClass) या ($ एक intanceof MyOtherClass))

एक अन्य अच्छा कारण है जब आपको फ़ंक्शन में कॉलबैक का उपयोग करने की आवश्यकता होती है। ( array_map की तरह …) instanceof नहीं एक समारोह है, यह एक भाषा निर्माण, ताकि आप कॉलबैक के रूप में उपयोग नहीं कर सकते।

थोस मामलों में, is_a उपयोगी हो सकता है


1

मैं प्रदर्शन के लिए नहीं बोल सकता - मैंने अभी तक कुछ भी नहीं मापा है - लेकिन आप जो प्रयास कर रहे हैं उसके आधार पर, इसके साथ सीमाएं हैं instanceof। मेरे प्रश्न की जाँच करें, अभी हाल ही में, इसके बारे में:

वर्ग स्थिर के साथ PHP 'Instof' विफल

मैंने is_aइसके बजाय उपयोग करना समाप्त कर दिया है। मुझे instanceofबेहतर संरचना पसंद है (मुझे लगता है कि यह अच्छे से पढ़ता है) और जहां मैं कर सकता हूं उसका उपयोग करना जारी रखूंगा।


1

प्रदर्शन परिणाम यहां से प्राप्त होते हैं :

instanceof ज्यादा तेज़ है।

कार्य

function method_1($a = null) { 
    return is_object($a) && is_a($a, 'Example');
}

function method_2($a = null) {
    return is_a((object) $a, 'Example');
}

function method_3($a = null) {
    return $a instanceof 'Example';
}

टाइम्स (प्रत्येक बार 5000 बार चलाएं)

0.00573397 // method_1(5) 
0.01437402 // method_2(5) 
0.00376201 // method_3(5)

1

एक परिदृश्य है जहां केवल is_a()काम करता है और instanceofविफल हो जाएगा।

instanceof एक शाब्दिक वर्ग के नाम या एक चर की अपेक्षा करता है जो या तो एक वस्तु या एक स्ट्रिंग है (एक वर्ग के नाम के साथ) इसके सही तर्क के रूप में।

लेकिन अगर आप किसी फ़ंक्शन से क्लास नाम की स्ट्रिंग प्रदान करना चाहते हैं तो यह काम नहीं करेगा और सिंटैक्स त्रुटि हो जाएगी।

हालांकि, एक ही परिदृश्य के साथ ठीक काम करता है is_a()

उदाहरण:

<?php

function getClassName() : string
{
    return "Foobar";
}

class Foobar
{
    private $xyz;

}

$x = new Foobar();

// this works of course
var_dump($x instanceof Foobar);

// this creates a syntax error
var_dump($x instanceof getClassName());

// this works
var_dump(is_a($x, getClassName()));

यह PHP 7.2.14 पर आधारित है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.