Bunun instanceofbir operatör ve bunun is_abir yöntem olduğunun farkındayım .
Yöntem performansta daha yavaş mı? Ne kullanmayı tercih edersin?
Bunun instanceofbir operatör ve bunun is_abir yöntem olduğunun farkındayım .
Yöntem performansta daha yavaş mı? Ne kullanmayı tercih edersin?
Yanıtlar:
Güncelleme
İtibariyle PHP 5.3.9 , işlevselliği is_a()değişti. Aşağıdaki orijinal yanıt , ilk bağımsız değişken olarak bir kabul etmesi is_a() gerektiğini belirtir Object, ancak PHP sürümleri> = 5.3.9 , bunun yerine dize sınıfı adlarının karşılaştırılmasına izin vermek için isteğe bağlı bir üçüncü boole bağımsız değişkenini $allow_string(varsayılan olarak false) kabul eder :
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);
Arasında yeni davranış temel fark, instanceofve is_a()ki instanceof, oysa her zaman hedefi (uzanan sınıflar da dahil olmak üzere) belirtilen sınıfın bir örneği olup olmadığını kontrol edecek is_a(), yalnızca nesne örneği gerektirir $allow_stringbağımsız değişken varsayılan değerine ayarlanır false.
orijinal
Aslında is_abir işlev, instanceofbir dil yapısıdır. is_aönemli ölçüde daha yavaş olacaktır (bir işlev çağrısını yürütmenin tüm ek yüküne sahip olduğundan), ancak her iki yöntemde de genel yürütme süresi minimumdur.
Artık 5.3'ten beri kullanımdan kaldırılmıyor, bu yüzden endişelenmenize gerek yok.
Ancak bir fark var. is_abir işlev olması, bir nesneyi parametre 1 olarak ve bir dize (değişken, sabit veya değişmez) parametre 2 olarak alır.
is_a($object, $string); // <- Only way to call it
instanceof bir nesneyi parametre 1 olarak alır ve parametre adı olarak bir sınıf adı (değişken), nesne örneği (değişken) veya sınıf tanımlayıcısı (tırnak işaretleri olmadan yazılan sınıf adı) alabilir.
$object instanceof $string; // <- string class name
$object instanceof $otherObject; // <- object instance
$object instanceof ClassName; // <- identifier for the class
is_atarif edilmedi?
$class = 'Foo'; var_dump($obj instanceof $class);
is_akarşı dikkat edilmesi gereken bir diğer şey , ikinci parametre için ifadeleri kabul ederken, instanceof alışkanlıktır. Örnek için işler yaparken değilinstanceofis_ais_a($object, 'Prefix_'.$name)$object instanceof 'Prefix_'.$name
is_aasla ilk etapta reddedilmemeliydi. Gerçi şimdi düzeltmek için biraz geç. Sorun, instanceofoperatörün PHP 4'te sözdizimi hataları is_aatması ve operatörün tanıtılmasıyla aynı anda kullanımdan kaldırılmasından bu yana , etrafa bir E_STRICT atmadan hem PHP 4 hem de 5 için kod yazmak imkansız hale geldi. if (version_compare(PHP_VERSION, 5) >= 0) { /* use instanceof */ } else { /* use is_a */ }PHP 4'te hala bir sözdizimi hatasına neden olacağından bile yapamazsınız
İşte is_a () ve instanceof performans sonuçları :
Test name Repeats Result Performance
instanceof 10000 0.028343 sec +0.00%
is_a() 10000 0.043927 sec -54.98%
Test kaynağı burada .
php 7hiçbir fark yoktur.
instanceofdiğer nesne örnekleri, sınıfın adı veya bir arabirim ile kullanılabilir. Ben sanmıyorum (Güncelleme: Bkz. Https://gist.github.com/1455148 )is_a()bu olursa beni arayüzlerle eserler (bir sınıf adı temsil eden tek bir dize), ancak düzeltin.
Php.net'ten bir örnek :
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'
çıktılar:
bool(true)
bool(true)
bool(false)
is_aarayüzlerle aynı şekilde çalışır instanceof(aynı şeyi söyleyecektim, ama göndermeden önce kontrol ettim ve gerçekten işe yarıyor) ...
ChrisF'in cevabı ile ilgili olarak, is_a() olarak, PHP 5.3.0'dan itibaren artık kullanımdan kaldırılmamıştır . Bunun gibi şeyler için resmi kaynağa gitmenin her zaman daha güvenli olduğunu düşünüyorum.
Sorunuzla ilgili olarak, Daniel, performans farklılıkları hakkında söyleyemem, ancak bir kısmı okunabilirliğe inecek ve daha kolay çalışabileceğinizi göreceksiniz.
Ayrıca, vs vs bir çek ihmal etrafında karışıklık hakkında bazı tartışmalar var . Örneğin, şunları yapabilirsiniz:instanceofis_a()instanceof
<?php
if( !($a instanceof A) ) { //... }
?>
vs aşağıdakiler için is_a():
<?php
if( !is_a($a, 'A' ) { //... }
?>
veya
<?php
if( is_a($a, 'A') === FALSE) { //... }
?>
Edit ChrisF cevabını silmiş gibi görünüyor, ancak cevabımın ilk kısmı hala duruyor.
Hızın yanı sıra, bir diğer önemli fark da kenar kasaları nasıl ele aldıklarıdır.
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.
Yani, is_a () olası hataları vurgularken instanceof bunları bastırır.
Optimizasyon minimaldir. Ve mikro-optimizasyonlar, kodun okunabilirliği, anlaşılabilirliği ve kararlılığı önünde asla gerçek bir cevap değildir.
(şahsen instanceof'i tercih ederim tercih , ama seçim senin;))
Temel fark, instanceof ile doğrudan sınıf adını kullanma olasılığıdır
$ bir sınıfım örneği
daha kısa
is_a ($ a, Sınıfım :: sınıf)
(tamam… önemsiz değil.)
İnstanceof (dil yapısı) ve is_a arasındaki sözdizimi rengi de benim için yararlıdır. daha büyük işlemlere renk fonksiyonu sağlar. Ve eğer tek kullanımlık olursa, daha fazla parantez gerektirmez.
Not: Elbette MyClass :: sınıfı yerine daha kısa bir doğrudan dize kullanabilirsiniz:
is_a ($ a, 'Sınıfım')
Ancak bir kodda doğrudan dize kullanmak iyi bir uygulama değildir .
Basit dize ve sınıf adları arasında bir fark yaratabiliyorsanız, sözdizimsel renklendirme daha iyi ve daha yararlıdır. Ayrıca, sabit sınıf adıyla adları değiştirmek daha kolaydır. Özellikle takma adla ad alanı kullanıyorsanız.
Peki, neden is_a () kullanıyorsunuz ?
Aynı neden için: okunabilirlik ve istenemezlik. (seçim sizin) Özel olarak kullanıldığında ! veya diğer boole operatörleri: is_a parantez ile daha pratik görünmektedir.
eğer ($ a AND (! is_a ($ a, Sınıfım :: sınıf) VEYA is_a ($ a, SınıfımClass :: sınıf)))
daha okunabilir:
if ($ a AND (! ($ $ bir Sınıfım örneği) VEYA ($ a intanceof MyOtherClass)))
Diğer bir iyi neden, işlevlerde geri aramayı kullanmanız gerektiğidir. ( dizi_map … gibi ) instanceof bir işlev değildir, bir dil yapısıdır, bu nedenle geri arama olarak kullanamazsınız.
Bu durumlarda, is_a yararlı olabilir
Performans için konuşamam - henüz hiçbir şey ölçmedim - ama ne yapmaya çalıştığınıza bağlı olarak, sınırlamalar var instanceof. Kısa bir süre önce bu konudaki soruma göz atın:
PHP 'instanceof' sınıf sabiti ile başarısız oluyor
Bunun is_ayerine kullandım. Ben instanceofdaha iyi yapısını seviyorum (Bence güzel okur) ve mümkün olduğunca kullanmaya devam edecektir.
İşte elde edilen performans sonuçları burada :
instanceof daha hızlı.
Fonksiyonlar
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';
}
Times (her biri 5000 kez çalıştırın)
0.00573397 // method_1(5)
0.01437402 // method_2(5)
0.00376201 // method_3(5)
Sadece is_a()çalışan ve instanceofbaşarısız olacak bir senaryo var .
instanceof değişmez bir sınıf adı veya bir nesne veya dize (bir sınıfın adı ile) olan bir değişkeni doğru argümanı olarak bekler.
Ancak bir işlev çağrısından bir sınıf adının dizesini sağlamak istiyorsanız, çalışmaz ve sözdizimi hatasına neden olur.
Ancak, aynı senaryo aşağıdakilerle uyumludur: is_a() .
Misal:
<?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()));
Bu PHP 7.2.14 tabanlıdır.