変数にデフォルト値を与える最良の方法(Perlをシミュレートする||、|| =)


134

私はPerlでこの種のものをやって大好きです:$foo = $bar || $baz割り当てるため$baz$fooあれば$bar、空または未定義です。が定義されていないか空の場合に$foo ||= $bletchのみ割り当て$bletchられるもの$foo$fooあります。

この状況での3項演算子は退屈で面倒です。PHPで利用できるシンプルでエレガントな方法は確かにありますか?

または、唯一の答えはisset()を使用するカスタム関数ですか?



1
ところで、所望の機能を持つPerlの演算子である////=、それらは、Perl v5.10.0のように存在します。オリジナルで||あり||=、定義性ではなく論理値をテストします。
Palec

@Palec、なぜ29票の4歳の質問が6票の1歳の質問の複製として識別されるのですか(それ自体が別の質問の複製としてマークされましたか?)これを維持することには大きな価値があると思いますタイトルがより一般的であるため、質問(答えを参照しない、つまりisset())。
トム・オージェ

それらは明確で正確な複製です。どちらを元にすべきかについてあまり考えていなかったことを認めます。何かの真ん中にいて、2つの間にリンクを張ることが目標でした。VTCを撤回します。
Palec

別の質問の複製として(誤って)IMOとマークされた完全な複製:isset()のPHP省略形?
Palec

回答:


130

PHP 7では、これを上品に行う方法がついに完成しました。これは、ヌル合体演算子と呼ばれます。次のように使用できます。

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

これは

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

14
宇宙船のオペレーターにもメリットがあると思います。
マリアーノ

3
マリアーノは私たちの足を引っ張っていると思いましたが、いや、それ<=>はブートすることであり、かなり正確です!
HPWD 2018年

1
null合体演算子はnull値に固有であるため、条件演算子とは動作が異なることに注意してください。たとえば$_GET['name']、が空の文字列に設定されている場合、最初の行は空の文字列を返しますが、を使用して「john doe」を返すことができ$_GET['name'] ? $_GET['name'] : 'john doe'ます。
VPhantom

211

PHP 5.3には省略?:演算子があります。

$foo = $bar ?: $baz;

$bar空の値でない場合に割り当てます(これがPHPとPerlでどのように異なるかはわかりません)。それ以外の場合$bazは、Perlと以前のバージョンのPHPで同じです。

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

しかし、PHPにはこのための複合代入演算子はありません(つまり、Perlに相当するものはありません||=)。

また、$bar通知をオフにしない限り、が設定されていないとPHPは音を立てます。との間にも意味上の違いがisset()ありempty()ます。前者は、変数が存在しない場合、またはに設定されてNULLいる場合にfalseを返します。後者の戻り真それが存在しないか、に設定されている場合0''falseまたはNULL


2
+1 RHEL5 / PHP5.1.2サーバーで見逃している5.3のもう1つの優れた機能を紹介してくれました。
Michael Berkowski、

私はあなたが最後から二番目の文章のThe first returns代わりにという意味だと思いますThe second
トト

21
変数が未定義の場合、PHPはそれについて通知をスローすることに注意してください。これは、残念ながら、$var = isset($var) ? $var : 'default value'; それに代わるものではありません。それは答えでそれを言います...それをすくい取る人のためにもう一度指摘するだけです。:-D
Brad

6
$ var = @ $ varを実行するのは悪いことですか?: 'デフォルト値'; もしそうなら、なぜですか?$ varが設定されていないこと、および$ varが設定されていなくてもかまわないことが唯一の「エラー」である可能性があるため
Codemonkey

8

すばらしい回答をありがとう!

可能な代替策のためにここに来る他の人のために、ここでは、この種のものから退屈を取り除くのに役立ついくつかの関数があります。

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];
    }
}

例:

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

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

これらは改善できると確信しています。


7

古いバージョンのPHPとの互換性を保つための一般的なイディオムは次のとおりです。

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

これは、ブール値のコンテキストで評価できる値に対して機能します。ここでの利点は、変数が未定義の場合にデバッグe_noticeを提供することにもなります。


定義されていない$bool ? $bool : "default"場合、通知は発行され$boolませんか?
BoltClock

確かに、それは同じです。OPはを参照してisset($var) ? $var : DEFAULTいると思います。しかし、彼はとにかくそれらを避けたいように聞こえます。
マリオ


0

これはissetケースに適した別の形式です

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

別の簡単な方法で、条件を追加し、同時に別の変数に割り当てることができるため、より多くの制御が可能になります

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


0

可能な解決策:defaultFor()

ファクトリソリューションがない場合(実際に非常に迷惑です)は、次の小さなヘルパーをお勧めします。ほとんどの場合それは仕事をします:


    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

これがあなたが達成したかったものに近いことを願っています。存在しない変数と一緒に使用しても何も通知されず、非常に便利です。確かに欠点があります。デフォルト値は常に事前に計算されるため、file_get_contentsなどの2番目のパラメーターとして重いものを使用しないでください。そのような場合は、issetingを使用するほうがよいでしょう。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.