?: PHP'de operatör ('Elvis operatörü')


258

Bugün bazı PHP kodunda gördüm:

$items = $items ?: $this->_handle->result('next', $this->_result, $this);

?:Burada kullanılan operatöre aşina değilim . Üçlü bir işleç gibi görünür, ancak yüklemin doğru olup olmadığını değerlendirmek için ifade atlanmıştır. Bu ne demek?

Yanıtlar:


529

Sol işlenen ise sol işlenen için değerlendirir truthy , aksi takdirde sağ işlenen.

Sahte kodda,

foo = bar ?: baz;

kabaca

foo = bar ? bar : baz;

veya

if (bar) {
    foo = bar;
} else {
    foo = baz;
}

fark barsadece bir kez değerlendirilecek.

Bunu, fooyayınladığınız kod örneğinde gösterildiği gibi bir "kendi kendine kontrol" yapmak için de kullanabilirsiniz :

foo = foo ?: bar;

Bu atayacaktır bariçin fooeğer fooaksi takdirde terk edecek, null veya Falsey olduğu foodeğişmeden.

Bazı örnekler:

<?php
    var_dump(5 ?: 0); // 5
    var_dump(false ?: 0); // 0
    var_dump(null ?: 'foo'); // 'foo'
    var_dump(true ?: 123); // true
    var_dump('rock' ?: 'roll'); // 'rock'
?>

Bu arada, Elvis operatörü olarak adlandırılıyor .

Elvis operatörü


11
Parantez içindeki değişkenin var olduğundan emin olun, aksi takdirde bir hata oluşturacaksınız. PHP sadece değeri nullya da herhangi bir değeri olduğunu varsaymaz . Just sayin '
DanMan

20
Komik olan, bu cevabın Wiki makalesiyle özyinelemeli bir döngü oluşturması ve bunun neden "Elvis operatörü" olarak adlandırıldığını tam olarak açıklamaması.
16'da eğlenceli.

41
Biraz daha az operasyon, biraz daha ifade lütfen.
aalaap

2
Neden sadece a ||. Yani blah || 'default'?
Noitidart

10
@Noitidart En soldaki doğru işleneni döndürdüğü JS'den farklı olarak, PHP'de ||operatör her zaman bir boole döndürür.
ksadowski

58

Belgelere bakın :

PHP 5.3'ten bu yana, üçlü operatörün orta kısmını dışarıda bırakmak mümkündür. İfade expr1 ?: expr3döner expr1eğer expr1değerlendirir için TRUEve expr3aksi.


11
Yeni bir doktora yazarına ihtiyaç duyuyorlar çünkü kaçınılmaz olarak bir kişi ifade2'ye ne olduğunu soracak. Sadece vurdum.
John K

7
Ne halt? Ben sadece şimdi, PHP 7 yükselttikten sonra bulmak? Bunu yıllardır kullanıyor olabilirdim!
Buttle Butkus

TBH, dokümanlar doğru. Ne oldu, expr2sadece kayboldu ve değerlendirilmedi. $this->expensiveComputation() ?: "nope"ile aynı değildir $this->expensiveComputation() ? $this->expensiveComputation() : "nope"- ifade1 sadece bir kez değerlendirilir.
Piskvor binadan ayrıldı

18

Dizilere dikkat edin. Sonra bir kontrol değişkeni yazmalıyız ?, çünkü:

  $params = ['param1' => 'value1',
             'param2' => 'value2',
             'param3' => 'value3',];

  $param1 = isset($params['param1'])?:null;
  $param2 = !empty($params['param2'])?:null;
  $param3 = $params['param3']?:null; // get E_NOTICE, if $params['param3'] eq false

  var_dump($param1,$param2,$param3);
  true // would like to expect `value1`
  true // would like to expect `value2`
  param3 // properly, but problem above

Güncellenmiş

RFC'den. Gelecekte (PHP 7'de) operatör Null Coalesce Operator bunu yapacaktır, örneğin:

$param1 = $params['param1'] ?? null;
// Equivalent to:  $param1 = isset($params['param1']) ? $params['param1'] : null;

1
Bu soruya cevap vermez ve Elvis Operatörünü ne zaman kullanacağını anlamaya çalışan hiç kimse için yararlı değildir.
Mark Amery

7
@Mark Amery hmm .. Gerçekten mi? Faydalı değil mi? Gerçekten PHP ile çalıştınız ve dizi değişkenlerine erişmek için kullanacağınız binlerce örneğe üçlü baktınız mı? Tamam, metni "
Dizilere

yani boş birleşme ve elvis aynı mı?
Nabeel Khan

7
@NabeelKhan Hayır! Bu da Elvis operatörünü PHP imo'da işe yaramaz hale getiriyor. Elvis operatörü bir ifadeyi değerlendirir ve eğer doğruysa, onu döndürürse son parçayı döndürür. PHP düşük yazıldığından, birçok şey doğru veya yanlış olur ve büyük olasılıkla istediğiniz şey olmaz. Yani: Eğer tanımlanmamışsa bir değişkene varsayılan bir değer ayarlamak istiyorsunuz, Elvis operatörünü kullanmak PHP'nin 0'ın tanımlanmadığını söyleyecektir, ancak 0'ı isteyebilirsiniz ... Bu yüzden PHP 7 Null Coalesce operatörünü alacak , Bu kesinlikle değişken null karşı test edecek, bu yüzden PHP 0 tanımsız olmadığını söyleyecektir.
Gregoire

1
@FuscaSoftware: Hata bastırma yöntemini böyle kullanmak tecrübelerime göre iyi bir fikir değil.
TeeHays

8

Bir başka önemli husus: Elvis Operatörü Zend Opcache tokenizasyon sürecini kırıyor. Bunu zor yoldan buldum! Bu daha sonraki sürümlerde düzeltilmiş olsa da, bu sorunun PHP 5.5.38'de (yerleşik Zend Opcache v7.0.6-dev ile) var olduğunu doğrulayabilirim.

Bazı dosyalarınızın Zend Opcache'de önbelleğe alınmasını 'reddedildiğini' bulursanız, bunun nedenlerinden biri olabilir ... Umarım bu yardımcı olur!


4

Evet, bu PHP 5.3 için yenidir. TRUE olarak değerlendirilirse test ifadesinin değerini veya FALSE olarak değerlendirilirse alternatif değeri döndürür.


2
Hafif yanlış / yanıltıcı; her iki işlenenin de bir boole olması gerekmez. Önemli olan ilk değer olup olmadığıdır truthy öyle olmasın, TRUE.
Mark Amery

@MarkAmery Açıklandı. Bu şekilde yanlış yorumlamak oldukça zor olmalı.
Atli
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.