回答:
最初の引数がnullの場合、それらは基本的に同じE_NOTICE
ですが、未定義の変数がある場合、nullの合体はを出力しません。PHP 7.0の移行ドキュメントは、これは言っています:
null結合演算子(??)は、isset()と組み合わせて三項を使用する必要がある一般的なケースの構文糖として追加されました。存在し、NULLでない場合は、最初のオペランドを返します。それ以外の場合は、2番目のオペランドを返します。
これを示すためのコード例を以下に示します。
<?php
$a = null;
print $a ?? 'b'; // b
print "\n";
print $a ?: 'b'; // b
print "\n";
print $c ?? 'a'; // a
print "\n";
print $c ?: 'a'; // Notice: Undefined variable: c in /in/apAIb on line 14
print "\n";
$b = array('a' => null);
print $b['a'] ?? 'd'; // d
print "\n";
print $b['a'] ?: 'd'; // d
print "\n";
print $b['c'] ?? 'e'; // e
print "\n";
print $b['c'] ?: 'e'; // Notice: Undefined index: c in /in/apAIb on line 33
print "\n";
通知がある行は、nullの合体演算子ではなく、省略形の三項演算子を使用している行です。ただし、通知があっても、PHPは同じ応答を返します。
コードを実行:https : //3v4l.org/McavC
もちろん、これは常に最初の引数がであることを前提としていますnull
。それがnullでなくなると、??
演算子は常に最初の引数を返しますが、?:
省略形は最初の引数が真実である場合にのみ返され、PHPがブール値に型キャストする方法に依存するという違いに終わります。
そう:
$a = false ?? 'f'; // false
$b = false ?: 'g'; // 'g'
次に、$a
と等しく、false
と$b
等しくなければなりません'g'
。
$b = []; var_dump($b['a']['b']['c'] ?? 'default');
またはオブジェクト付き$b = new Foo; var_dump($b->a()->b()->c() ?? 'default');
$a = [];
。参照:3v4l.org/iCCa0
phpインタラクティブモード(php -a
ターミナル上)で以下を実行しました。各行のコメントは結果を示しています。
var_dump (false ?? 'value2'); # bool(false)
var_dump (true ?? 'value2'); # bool(true)
var_dump (null ?? 'value2'); # string(6) "value2"
var_dump ('' ?? 'value2'); # string(0) ""
var_dump (0 ?? 'value2'); # int(0)
var_dump (false ?: 'value2'); # string(6) "value2"
var_dump (true ?: 'value2'); # bool(true)
var_dump (null ?: 'value2'); # string(6) "value2"
var_dump ('' ?: 'value2'); # string(6) "value2"
var_dump (0 ?: 'value2'); # string(6) "value2"
??
:??
NULLからのみを許可する「ゲート」のようなものです。NULL
??
は同じです( !isset() || is_null() )
?:
?:
anything falsy
通過する門のようなものです。NULL
0
、empty string
、NULL
、false
、!isset()
、empty()
... falsyにおいが何かをecho ($x ? $x : false)
?:
をスローPHP NOTICE
しますunset
!isset()
??
し?:
ますか??:
か
empty($x)
チェックを!empty($x) ? $x : $y
、$x ?: $y
if(!$x) { fn($x); } else { fn($y); }
短縮することができます fn(($x ?: $y))
??
か
!isset() || is_null()
確認したい$object = $object ?? new objClassName();
三元演算子は積み重ねることができます ...
echo 0 ?: 1 ?: 2 ?: 3; //1
echo 1 ?: 0 ?: 3 ?: 2; //1
echo 2 ?: 1 ?: 0 ?: 3; //2
echo 3 ?: 2 ?: 1 ?: 0; //3
echo 0 ?: 1 ?: 2 ?: 3; //1
echo 0 ?: 0 ?: 2 ?: 3; //2
echo 0 ?: 0 ?: 0 ?: 3; //3
これは基本的に次のシーケンスです。
if( truthy ) {}
else if(truthy ) {}
else if(truthy ) {}
..
else {}
Null Coaleseオペレーターは積み重ねることができます ...
$v = $x ?? $y ?? $z;
これは次のシーケンスです。
if(!isset($x) || is_null($x) ) {}
else if(!isset($y) || is_null($y) ) {}
else {}
スタッキングを使用して、これを短くすることができます:
if(!isset($_GET['name'])){
if($user_name){
$name = $user_name;
}else {
$name = 'anonymous';
}
} else {
$name = $_GET['name'];
}
これに:
$name = $_GET['name'] ?? $user_name ?: 'anonymous';
かっこいいですよね?:-)
このようにショートカット三項演算子を使用する場合、$_GET['username']
が設定されていない場合は通知が表示されます。
$val = $_GET['username'] ?: 'default';
だから代わりにあなたはこのようなことをしなければなりません:
$val = isset($_GET['username']) ? $_GET['username'] : 'default';
演算子を合体ヌルは、上記のステートメントに相当し、あれば「デフォルト」を返します。$_GET['username']
設定されていないかでありますnull
:
$val = $_GET['username'] ?? 'default';
真実性はチェックしないことに注意してください。設定されていてnullでない場合にのみチェックします。
これを行うこともでき、最初に定義された(設定されているnull
)値が返されます。
$val = $input1 ?? $input2 ?? $input3 ?? 'default';
これが適切な合体演算子です。
主な違いは
三項演算子の表現 expr1 ?: expr3
を返すexpr1
場合expr1
に評価
TRUE
反面ヌル合体オペレータ表現 (expr1) ?? (expr2)
評価さがにexpr1
ている場合がexpr1
ありません NULL
3項演算子 expr1 ?: expr3
は、左側の値(expr1)
が存在しない場合に通知を発行し ますが、一方で、Null結合演算子(expr1) ?? (expr2)
特に、左側の値(expr1)
が存在しない場合、通知を発行しませんisset()
。
TernaryOperatorは関連付けられたままです
((true ? 'true' : false) ? 't' : 'f');
ヌルコアレッシング演算子は右連想です
($a ?? ($b ?? $c));
次に、例による違いを説明しましょう:
三項演算子 (?:)
$x='';
$value=($x)?:'default';
var_dump($value);
// The above is identical to this if/else statement
if($x){
$value=$x;
}
else{
$value='default';
}
var_dump($value);
ヌル合体演算子 (??)
$value=($x)??'default';
var_dump($value);
// The above is identical to this if/else statement
if(isset($x)){
$value=$x;
}
else{
$value='default';
}
var_dump($value);
ここでの違いと類似性を説明した表である'??'
とは、?:
特記事項:nullの合体演算子と三項演算子は式であり、変数ではなく式の結果として評価されます。参照によって変数を返すかどうかを知ることは重要です。ステートメントは$ fooを返しますか?$ bar; $ var == 42を返しますか?$ a:$ b; したがって、参照による戻り関数では機能せず、警告が発行されます。
動的データ処理に関しては、どちらも動作が異なります。
変数が空( '')の場合、nullの合体は変数をtrueとして扱いますが、省略3項演算子は扱いません。そして、それは心に留めておくべきことです。
$a = NULL;
$c = '';
print $a ?? '1b';
print "\n";
print $a ?: '2b';
print "\n";
print $c ?? '1d';
print "\n";
print $c ?: '2d';
print "\n";
print $e ?? '1f';
print "\n";
print $e ?: '2f';
そして出力:
1b
2b
2d
1f
Notice: Undefined variable: e in /in/ZBAa1 on line 21
2f
リンク:https : //3v4l.org/ZBAa1
It returns its first operand if it exists and is not NULL; otherwise it returns its second operand
。
初心者向け:
ヌル合体演算子(??)
null
値と未定義(変数/配列インデックス/オブジェクト属性)を除いてすべてが真です
例:
$array = [];
$object = new stdClass();
var_export (false ?? 'second'); # false
var_export (true ?? 'second'); # true
var_export (null ?? 'second'); # 'second'
var_export ('' ?? 'second'); # ""
var_export ('some text' ?? 'second'); # "some text"
var_export (0 ?? 'second'); # 0
var_export ($undefinedVarible ?? 'second'); # "second"
var_export ($array['undefined_index'] ?? 'second'); # "second"
var_export ($object->undefinedAttribute ?? 'second'); # "second"
これは基本的に、変数(配列インデックス、オブジェクト属性など)が存在するかどうかを確認し、存在しないことを確認しnull
ます。isset
機能に似ています
三項演算子の省略形(?:)
すべての偽のものは(false
、null
、0
、空の文字列)が偽として来ているが、それが未定義なら、それはまた、偽として来るが、Notice
スローされます。
元
$array = [];
$object = new stdClass();
var_export (false ?: 'second'); # "second"
var_export (true ?: 'second'); # true
var_export (null ?: 'second'); # "second"
var_export ('' ?: 'second'); # "second"
var_export ('some text' ?? 'second'); # "some text"
var_export (0 ?: 'second'); # "second"
var_export ($undefinedVarible ?: 'second'); # "second" Notice: Undefined variable: ..
var_export ($array['undefined_index'] ?: 'second'); # "second" Notice: Undefined index: ..
var_export ($object->undefinedAttribute ?: 'second'); # "Notice: Undefined index: ..
お役に立てれば
このリンクを下にスクロールしてセクションを表示すると、以下のような比較例が表示されます。
<?php
/** Fetches the value of $_GET['user'] and returns 'nobody' if it does not exist. **/
$username = $_GET['user'] ?? 'nobody';
/** This is equivalent to: **/
$username = isset($_GET['user']) ? $_GET['user'] : 'nobody';
/** Coalescing can be chained: this will return the first defined value out of $_GET['user'], $_POST['user'], and 'nobody'. **/
$username = $_GET['user'] ?? $_POST['user'] ?? 'nobody';
?>
ただし、後でコードを読むときにコードを理解するのが難しくなるため、演算子をチェーン化することはお勧めしません。
null結合演算子(??)は、isset()と組み合わせて三項を使用する必要がある一般的なケースの構文糖として追加されました。存在し、NULLでない場合は、最初のオペランドを返します。それ以外の場合は、2番目のオペランドを返します。
基本的に、合体演算子を使用すると、3項演算子とは異なり、nullの自動チェックが行われます。
a || b || c
JS の一般的なパターンに非常によく似ていますが、PHPをブール値に使用できる点が異なります(false || 2
JSでは2 false ?? 2
、PHPではfalse)
??
またはを使用することには長所と短所があるよう?:
です。使用する利点?:
は、falseとnullを評価し、 ""を同じに評価することです。欠点は、先行する引数がnullの場合、E_NOTICEを報告することです。??
プロ何E_NOTICEがないことですが、conが、それは同じ偽とヌル評価しないということです。私の経験では、人々がnullとfalseを交互に使用し始めるのを見てきましたが、最終的にはnullとfalseのどちらかではなく両方を使用するようにコードを変更することに頼っています。もう1つの方法は、より複雑な3項条件を作成することです(isset($something) or !$something) ? $something : $something_else
。
以下は、??
nullとfalseの両方を使用した演算子の使用の違いの例です。
$false = null;
$var = $false ?? "true";
echo $var . "---<br>";//returns: true---
$false = false;
$var = $false ?? "true";
echo $var . "---<br>"; //returns: ---
ただし、3項演算子について詳しく説明することで、e_noticeをスローせずに、falseまたは空の文字列 ""をnullのように動作させることができます。
$false = null;
$var = (isset($false) or !$false) ? $false : "true";
echo $var . "---<br>";//returns: ---
$false = false;
$var = (isset($false) or !$false) ? $false : "true";
echo $var . "---<br>";//returns: ---
$false = "";
$var = (isset($false) or !$false) ? $false : "true";
echo $var . "---<br>";//returns: ---
$false = true;
$var = (isset($false) or !$false) ? $false : "true";
echo $var . "---<br>";//returns: 1---
個人的には、PHPの将来のリビジョンに:?
、上記の構文を置き換える別の新しい演算子が含まれると本当にいいと思います。つまり、
// $var = $false :? "true";
その構文はnull、false、および ""を同等に評価し、E_NOTICEをスローしません...
?? null ?:
はかなり素晴らしいです、ありがとうミスター。賢い男。
class a
{
public $a = 'aaa';
}
$a = new a();
echo $a->a; // Writes 'aaa'
echo $a->b; // Notice: Undefined property: a::$b
echo $a->a ?? '$a->a does not exists'; // Writes 'aaa'
// Does not throw an error although $a->b does not exist.
echo $a->b ?? '$a->b does not exist.'; // Writes $a->b does not exist.
// Does not throw an error although $a->b and also $a->b->c does not exist.
echo $a->b->c ?? '$a->b->c does not exist.'; // Writes $a->b->c does not exist.
Null Coalescing operator
は、チェックwhether the variable is set
との2つのタスクのみを実行しますwhether it is null
。次の例を見てください。
<?php
# case 1:
$greeting = 'Hola';
echo $greeting ?? 'Hi There'; # outputs: 'Hola'
# case 2:
$greeting = null;
echo $greeting ?? 'Hi There'; # outputs: 'Hi There'
# case 3:
unset($greeting);
echo $greeting ?? 'Hi There'; # outputs: 'Hi There'
上記のコード例は、Null Coalescing operator
存在しない変数とNULL
同じ方法で設定された変数を処理することを示しています。
Null Coalescing operator
の改善ternary operator
です。2つを比較する次のコードスニペットをご覧ください。
<?php /* example: checking for the $_POST field that goes by the name of 'fullname'*/
# in ternary operator
echo "Welcome ", (isset($_POST['fullname']) && !is_null($_POST['fullname']) ? $_POST['fullname'] : 'Mr. Whosoever.'); # outputs: Welcome Mr. Whosoever.
# in null coalecing operator
echo "Welcome ", ($_POST['fullname'] ?? 'Mr. Whosoever.'); # outputs: Welcome Mr. Whosoever.
したがって、2つの違いは、Null Coalescing operator
演算子は未定義の変数をternary operator
。よりも処理するように設計されていることです。一方、ternary operator
はの省略形ですif-else
。
Null Coalescing operator
はternary operator
、を置き換えるものではありませんが、上記の例のような一部のユースケースでは、手間をかけずにクリーンなコードを記述できます。
クレジット:http : //dwellupper.io/post/6/php7-null-coalescing-operator-usage-and-examples
isset($_POST['fullname'])
すでにNULL
値をチェックしているため&& !is_null($_POST['fullname'])
、最初の例ではとにかく冗長です
$ _GETや$ _REQUESTなどのスーパーグローバルを使用する場合、空の文字列になる可能性があることに注意してください。この特別なケースでは、この例
$username = $_GET['user'] ?? 'nobody';
$ usernameの値が空の文字列になるため、失敗します。
したがって、$ _ GETまたは$ _REQUESTを使用する場合は、次のように代わりに三項演算子を使用する必要があります。
$username = (!empty($_GET['user'])?$_GET['user']:'nobody';
現在、$ usernameの値は期待どおり「nobody」です。