PHP için birleştirme işlevi?


131

Çoğu programlama dilinin birleştirme işlevi vardır ( örneğin , ilk NULL olmayan değeri döndürür ). Ne yazık ki 2009'da PHP bunu yapmıyor.

PHP'nin kendisi bir birleştirme işlevi alana kadar PHP'de bir tane uygulamanın iyi bir yolu ne olabilir?


11
İlgili: PHP 7 için yeni boş birleştirme operatörü ??
kojiro

Boş birleştirme operatörü hakkında daha fazla bilgi burada bulunabilir - stackoverflow.com/questions/33666256/…
Peter

1
Dikkat etmek gerekirse, PHP7 bu işlevi uyguladı
Grzegorz

@Grzegorz: Bir operatör bir işlev değildir veya bu işlevi PHP 7'de nerede yeni
buldunuz

İşlev olarak i işlevi kastetmedim;) Özellik. Ben kesin değildim. Teşekkür ederim :)
Grzegorz

Yanıtlar:


194

Php 5.3'te bunu yapan yeni bir operatör var: ?:

// A
echo 'A' ?: 'B';

// B
echo '' ?: 'B';

// B
echo false ?: 'B';

// B
echo null ?: 'B';

Kaynak: http://www.php.net/ChangeLog-5.php#5.3.0


25
Ya birden çok üçlü kısayol, "echo $ a?: $ B?: $ C?: $ D;" gibi bir şey olur. iş?
ChrisR

5
Diziler için beklendiği gibi çalışmıyor. Örneğin, tanımlanmamış bir dizi elemanının yanlış olup olmadığını kontrol etmeye çalışırken bir hataya neden olur. $input['properties']['range_low'] ?: '?'
Keyo

5
Birleştirme operatörünü kullanmanıza bakılmaksızın Tanımsız Dizin bildirimi almalısınız.
Kevin

2
Çoklu falsey argümanları son argümanı array() ?: null ?: falsedöndürür , döndürür false. Operatör gerçekten aklı başında.
Brad Koch

6
Unutmayın ki bu sadece diğer dillerde boş olmayan birleşme gibi birleşme değil, aynı zamanda dolaylı olarak bir boolean'a dönüştürülecek olan herhangi bir değeri de kabul eder. Bu nedenle, tür döküm kurallarınızı
tazelediğinizden

65

PHP 7 gerçek bir birleştirme işleci tanıttı :

echo $_GET['doesNotExist'] ?? 'fallback'; // prints 'fallback'

Önündeki değer ??yoksa veya nullalındıktan sonraki değer ??ise.

Bahsedilen ?:operatöre göre iyileştirme , ??tanımsız değişkenleri de E_NOTICE.


Sonunda artık her yerde isset () ve empty () yok!
George Kagan

7
@timeNomad hala ihtiyacınız olacak boş, yalnızca null olup olmadığını kontrol ediyor
Nabeel Khan

Güvenli "sahte-birleştirme" yapmanın tek yolu ikisinden de biraz kullanmaktır:($_GET['doesNotExist'] ?? null) ?: 'fallback'
Nathan Baulch

Avantajı ?:üzerinde ??, ancak kuyunun olarak boş değerler coalesces olmasıdır ??yapmaz. JavaScript (yani mantıksal VEYA operatörün davranışına benzer $val || 'default'), ben bulacağını ?:daha pratik şekli olarak kaynaştırma sonuçta kendimizi hem taşıma bulmak bizim pratikte ise boş ve boş aynı şekilde (yani içinde $val ?: 'default'). Ve konuyu daha da zorlamak ve yutmak E_NOTICEistiyorsanız, bunu bile tartışabilirsiniz:echo @$val ?: 'default';
Matt Borja

29

Google'da "php coalesce" için ilk hit.

function coalesce() {
  $args = func_get_args();
  foreach ($args as $arg) {
    if (!empty($arg)) {
      return $arg;
    }
  }
  return NULL;
}

http://drupial.com/content/php-coalesce


9
Küçük bir ram kaydedin ve
bağımsız

17
@ [Alfred, Ciaran] - yanılıyorsunuz. foreach (), bir dizi elde etmek için ilk argümanı yalnızca bir kez değerlendirir ve ardından üzerinde yineler.
gahooa

6
Func_get_args () işlevini foreach içine koymak (burada $ arg olarak) performans açısından hiçbir şeyi değiştirmez.
Savageman

7
@Savageman ... tam olarak ... bu milisaniyelik performansı veya birkaç bayt belleği uygulamanızdan sıkıştırmayı düşünüyorsanız, muhtemelen yanlış performans / bellek darboğazına bakıyorsunuzdur
ChrisR

4
İronik olarak, bu artık Google'da "php coalesce" için ilk hit oldu.
Will Tıraş

18

Gerçekten beğendim mi?: Operatörü. Ne yazık ki, henüz üretim ortamımda uygulanmadı. Bu yüzden bunun eşdeğerini kullanıyorum:

function coalesce() {
  return array_shift(array_filter(func_get_args()));
}

1
bu, iletilen n bağımsız değişkenlerde yanlış (null dahil) olarak değerlendirilen herhangi bir şeyden kurtulmak için array_filter kullanan 'doğru' bir birleşmedir. Benim tahminim dizideki ilk öğe yerine shift kullanmak bir şekilde daha sağlam, ancak bilmediğim kısım. bkz: php.net/manual/en/…
Adam Tolley

3
Hoşuma gitti ama @hakre ile aynı fikirde olmak zorundayım - karşılaştığı coalesceilk boş olmayan argümanı döndürmesi gerekiyor FALSE. FALSEYine de bu fonksiyon , muhtemelen operasyonun aklında olanı (en azından bir coalescefonksiyondan istediğim şeyi değil) atacaktır .
Madbreaks

1
Yalnızca değişkenler referans olarak aktarılmalıdır
Ben Sinclair

9

Unutulmamalıdır ki, PHP'nin büyük olmayan değişkenleri ve dizi indekslerini ele alması nedeniyle, her türlü birleştirme işlevinin sınırlı kullanımı vardır. Bunu yapabilmeyi çok isterim:

$id = coalesce($_GET['id'], $_SESSION['id'], null);

Ancak bu çoğu durumda PHP'nin E_NOTICE ile hata yapmasına neden olur. Kullanmadan önce bir değişkenin varlığını test etmenin tek güvenli yolu, onu doğrudan boş () veya isset () içinde kullanmaktır. Birleştirmenizdeki tüm seçeneklerin başlatıldığını biliyorsanız, Kevin tarafından önerilen üçlü operatör en iyi seçenektir.


Bu durumda, dizi birlikleri oldukça iyi çalışır ( $getstuff = $_GET+$_SESSION+array('id'=>null);$id=$getstuff['id'];).
Brilliand

@Quill bu ne anlama geliyor? Referans ile önerilen çözümü yaptınız mı?
Ben Sinclair

PHP 7, bu çok yaygın işlemi daha kısa ve öz hale getirmek için sevimli yeni isset üçlü operatörünü ??sunar.
botimer

6

Bu işlevin belirli türlerle tam olarak nasıl çalışmasını istediğinizi belirlediğinizden emin olun. PHP'nin çok çeşitli tür denetimi veya benzer işlevleri vardır, bu nedenle bunların nasıl çalıştığını bildiğinizden emin olun. Bu, is_null () ve empty () arasındaki örnek bir karşılaştırmadır.

$testData = array(
  'FALSE'   => FALSE
  ,'0'      => 0
  ,'"0"'    => "0"  
  ,'NULL'   => NULL
  ,'array()'=> array()
  ,'new stdClass()' => new stdClass()
  ,'$undef' => $undef
);

foreach ( $testData as $key => $var )
{
  echo "$key " . (( empty( $var ) ) ? 'is' : 'is not') . " empty<br>";
  echo "$key " . (( is_null( $var ) ) ? 'is' : 'is not')  . " null<br>";
  echo '<hr>';
}

Gördüğünüz gibi empty () bunların tümü için true döndürür, ancak is_null () bunu yalnızca 2 tanesi için yapar.


2

Ethan Kent tarafından gönderilen cevabı genişletiyorum . Bu yanıt, bir işlevin tipik olarak yaptığı şey olmayan dizi_filtresinin iç işleyişi nedeniyle yanlış olarak değerlendirilen boş olmayan argümanları atacaktır coalesce. Örneğin:

echo 42 === coalesce(null, 0, 42) ? 'Oops' : 'Hooray';

Hata

Bunun üstesinden gelmek için ikinci bir argüman ve fonksiyon tanımı gereklidir. Çağrılabilir işlevi anlatarak sorumludur array_filtersonuç dizisine güncel dizi değer katmak için olsun veya olmasın:

// "callable"
function not_null($i){
    return !is_null($i);  // strictly non-null, 'isset' possibly not as much
}

function coalesce(){
    // pass callable to array_filter
    return array_shift(array_filter(func_get_args(), 'not_null'));
}

Basitçe geçebilirseniz issetveya 'isset'2. argüman olarak geçerseniz iyi olurdu array_filter, ama böyle bir şans yok.


0

Şu anda bunu kullanıyorum, ancak PHP 5'teki bazı yeni özelliklerle geliştirilip geliştirilemeyeceğini merak ediyorum.

function coalesce() {
  $args = func_get_args();
  foreach ($args as $arg) {
    if (!empty($arg)) {
    return $arg;
    }
  }
  return $args[0];
}

0

PHP 5.3+, kapanışlarla:

function coalesce()
{
    return array_shift(array_filter(func_get_args(), function ($value) {
        return !is_null($value);
    }));
}

Demo: https://eval.in/187365


Yalnızca değişkenler referans olarak aktarılmalıdır
Ben Sinclair

Evet, basitleştirmek için demo için katı kuralları çiğnedim. :)
Paulo Freitas
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.