Bir değişkene varsayılan bir değer vermenin en iyi yolu (Perl benzetimi ||, || =)


134

Perl'de bu tür bir şey yapmayı seviyorum: $foo = $bar || $bazatamak $baziçin $fooise $barboş veya tanımlanmamıştır. Ayrıca sahip $foo ||= $bletchtek atar hangi $bletchiçin $fooeğer $footanımlanmış veya boş değildir.

Bu durumda üçlü operatör sıkıcı ve yorucudur. Elbette PHP'de basit ve zarif bir yöntem var mı?

Yoksa tek yanıt isset () kullanan özel bir işlev mi?



1
Btw istenen işlevselliği Perl operatörleri //ve //=ve Perl v5.10.0 itibariyle mevcuttur. Orijinal ||ve ||=mantıksal değer için test, tanım için değil.
Palec

@Palec, neden 29 olumlu oy içeren 4 yıllık bir soru, 6 olumlu oy içeren 1 yıllık bir sorunun kopyası olarak tanımlansın (ki bu soru başka bir sorunun kopyası olarak işaretlendi?) Bunu tutmanın büyük bir değeri olduğunu düşünüyorum. soru, başlık daha genel olduğundan (yanıta referans vermez, yani: isset ()).
Tom Burgu

Açık ve kesin kopyalar. Hangisinin orijinal olması gerektiği konusunda fazla düşünmediğimi itiraf ediyor, başka bir şeyin ortasındaydım, ikisi arasında bir bağlantı kurmak amaçtı. VTC'mi geri çekiyorum.
Palec

Başka bir sorunun kopyası olarak işaretlenmiş (hatalı olarak IMO) tam bir kopyası: isset () için PHP kısaltması?
Palec

Yanıtlar:


131

PHP 7'de nihayet bunu zarif bir şekilde yapmanın bir yolunu bulduk. Null birleştirme operatörü olarak adlandırılır . Bunu şu şekilde kullanabilirsiniz:

$name = $_GET['name'] ?? 'john doe';

Bu eşdeğerdir

$name = isset($_GET['name']) ? $_GET['name']:'john doe';

14
Uzay gemisi operatörünün de hak sahibi olduğunu iddia ediyorum .
Mariano

3
Mariano'nun bacaklarımızı çekeceğini sanıyordum ama hayır, bu bir şey <=>ve çizmesi oldukça doğru!
HPWD

1
Boş birleştirme operatörünün, bir nulldeğere özgü olduğu için koşullu operatörden farklı davrandığını unutmayın . Örneğin, $_GET['name']boş bir dizgeye ayarlanmışsa, ilk satır boş bir dizge döndürür, ancak kullanarak "john doe" döndürebiliriz $_GET['name'] ? $_GET['name'] : 'john doe'.
VPhantom

211

PHP 5.3'ün bir kısaltma ?:operatörü vardır:

$foo = $bar ?: $baz;

Hangi atar $baraksi, (ben bu Perl PHP farklı olacağını bilmiyorum) boş bir değer değilse $bazve Perl ve PHP eski sürümlerinde bu aynıdır:

$foo = $bar ? $bar : $baz;

Ancak PHP'nin bunun için bir bileşik atama operatörü yoktur (yani Perl'in eşdeğeri yoktur ||=).

Ayrıca, $barbildirimleri kapatmadığınız sürece PHP ayarlanmazsa gürültü çıkarır . Ayrıca isset()ve arasında anlamsal bir fark vardır empty(). Birincisi, değişken yoksa veya olarak ayarlanmışsa yanlış döndürür NULL. Gerçek ikincisi döner o yok ya ayarlıysa 0, '', falseveya NULL.


2
+1 5.3'ün bir başka harika özelliğini bana tanıttığı için, RHEL5 / PHP5.1.2 sunucularımda eksiklik yaşıyorum.
Michael Berkowski

Sanırım sondan bir önceki cümlenin The first returnsyerine demek istiyorsun The second.
Toto

21
Değişkeniniz tanımsız ise, PHP bununla ilgili uyarılar atacaktır. Bu, maalesef, bunun yerini $var = isset($var) ? $var : 'default value'; tutmuyor. Cevapta diyor ki ... sadece gözden geçiren herkes için tekrar işaret ediyor. :-D
Brad

6
$ Var = @ $ var yapmak kötü mü?: 'Varsayılan değer'; Öyleyse neden? Tek "hata" $
var'ın

8

Tüm harika cevaplar için teşekkürler!

Buraya olası bir alternatif için gelen herhangi biri için, işte bu tür şeylerin sıkıntısını gidermeye yardımcı olan bazı işlevler.

function set_if_defined(&$var, $test){
    if (isset($test)){
        $var = $test;
        return true;
    } else {
        return false;
    }
}

function set_unless_defined(&$var, $default_var){
    if (! isset($var)){
        $var = $default_var;
        return true;
    } else {
        return false;
    }
}

function select_defined(){
    $l = func_num_args();
    $a = func_get_args();
    for ($i=0; $i<$l; $i++){
        if ($a[$i]) return $a[$i];
    }
}

Örnekler:

// $foo ||= $bar;
set_unless_defined($foo, $bar);

//$foo = $baz || $bletch
$foo = select_defined($baz, $bletch);

Eminim bunlar geliştirilebilir.


7

Eski PHP sürümleriyle uyumlu kalmak için yaygın bir deyim şudur:

 $var = $bool   or   $var = "default";
 // If I use it, then only with excessive spaces for clarity.

Bu, boole bağlamında değerlendirilebilecek değerler için çalışır. Buradaki avantaj, değişkenin tanımsız olması durumunda size hata ayıklama e_notice vermesidir.


Bir bildirim yayılan değil mi $bool ? $bool : "default"eğer $booltanımlı değil?
BoltClock

Tabii, aynısı. OP'nin bahsettiğini varsaydım isset($var) ? $var : DEFAULT. Ama yine de onlardan uzak durmak istiyor gibi görünüyor.
mario

6

7. * öncesi PHP'de, yerel olarak bir @: ile bastırılmış hataları olan tanımsız bir değişken için?: Kullanılabilir.

$foo = @$bar ?: $baz;

0

bu issetdava için başka bir iyi formattır

isset($foo) || $foo= $bar;

başka bir basit yol ve daha fazla koşul ekleyebildiğiniz ve aynı anda başka bir değişkene atayabildiğiniz için size daha fazla kontrol sağlayacaktır.

$foo = (isset($oData['foo']))?$bar['foo']:'default value';


0

Olası bir çözüm: defaultFor ()

Bir fabrika çözümümüz olmadıkça (ki bu gerçekten çok can sıkıcıdır), aşağıdaki küçük yardımcıyı tavsiye ederim. Çoğu durumda işi yapar:


    function defaultFor(&$x,$default=null) {
        if(!isset($x)) $x = $default;
    }

    //--------------------  Now you can do this: --------------

    defaultFor($a,"Jack");  // if $a is not set, it will be "Jack"
    defaultFor($x);         // no more notices for $x but keep it !isset

Umarım bu, ulaşmak istediğiniz şeye yakındır. Var olmayan bir değişkenle kullanırsanız size herhangi bir uyarı vermez ve oldukça kullanışlıdır. Elbette bir dezavantajı vardır: varsayılan değer her zaman önceden hesaplanır, bu nedenle onu bir file_get_contents veya başka bir şey gibi ikinci bir parametre olarak ağır bir şeyle kullanmayın. Bu gibi durumlarda, satış yapmak daha iyidir.


0

Genel olarak şöyle bir şey yaptığımı düşünüyorum:

$foo = $bar || $baz;

olmadıkça, kötü bir fikir olduğunu $barve $bazher iki mantıksal ifadenin bulunmaktadır. Değilse:

$bar = 10;
$baz = 11;

o zaman soru şu olur: Bir şeyin doğru mu yanlış mı olduğunu belirleyen nedir? Çoğu insan muhtemelen sıfırın yanlış olmasını ve diğer her şeyin doğru olmasını bekler. Ama (örnek Ruby) bazı dillerle, sadece falseve nilher ikisi anlamına gelir yanlış 0ve 1doğru olurdu. Bu çapraz dil belirsizliği nedeniyle, bu durumlarda açıkça belirtmenin en iyisi olduğunu düşünüyorum:

if ($bar !== 0) {
   $foo = $bar;
} else {
   $foo = $baz;
}

veya:

$foo = $bar !== 0 ? $bar : $baz;
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.