[php] PHP 삼항 연산자 대 null 병합 연산자

PHP에서 삼항 연산자 속기 ( ?:)와 null 병합 연산자 ( ??) 의 차이점을 설명 할 수 있습니까 ?

그것들은 언제 다르게 행동하고 언제 똑같은 방식으로 (그런 경우에도)?

$a ?: $b

VS.

$a ?? $b



답변

첫 번째 인수가 null 인 E_NOTICE경우, 정의되지 않은 변수가있을 때 null 병합이 a를 출력하지 않는다는 점을 제외하고는 기본적으로 동일 합니다. PHP 7.0 마이그레이션 문서는 이 말을했다 :

null 통합 연산자 (??)는 isset ()과 함께 삼항을 사용해야하는 일반적인 경우에 구문 설탕으로 추가되었습니다. 존재하고 NULL이 아닌 경우 첫 번째 피연산자를 리턴합니다. 그렇지 않으면 두 번째 피연산자를 반환합니다.

이것을 보여주는 예제 코드는 다음과 같습니다.

<?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'.


답변

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"

그래서 이것은 나의 해석입니다.

1. 널 병합 연산자- ??:

  • ??NULL 만 허용하는 “게이트”와 같습니다 .
  • 따라서 첫 번째 매개 변수 가 아닌 한 항상 첫 번째 매개 변수를 반환 합니다NULL .
  • 이 수단은 ??동일하다( !isset() || is_null() )

2. 삼항 연산자- ?:

  • ?:anything falsy통과 하는 문과 같습니다.NULL
  • 0, empty string, NULL, false, !isset(), empty()… falsy 냄새 아무것도
  • 전형적인 삼항 연산자처럼 : echo ($x ? $x : false)
  • 참고 : ?:던질 것이다 PHP NOTICE정의되지 않은 (에 unset또는 !isset()) 변수

3. 그래서 의사, 언제 ??그리고 ?:..

  • 나는 농담이야-나는 의사가 아니며 이것은 단지 해석 일 뿐이다
  • 나는 ?:언제

    사용할 것이다

    • 하고 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();

4. 스태킹 연산자 …

  1. 삼항 연산자를 쌓을 수 있습니다

    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 {}
  2. 널 Coalese 연산자는 쌓을 수 있습니다

    $v = $x ?? $y ?? $z; 

    이 순서는 다음과 같습니다.

    if(!isset($x) || is_null($x) ) {}
    else if(!isset($y) || is_null($y) ) {}
    else {}
  3. 스태킹을 사용하여 이것을 줄일 수 있습니다.

    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';

참고 가 truthiness를 확인하지 않습니다 . 설정되어 있고 null이 아닌 경우에만 확인합니다.

이 작업을 수행 할 수도 있으며 첫 번째로 정의 된 (set 및 not null) 값이 반환됩니다.

$val = $input1 ?? $input2 ?? $input3 ?? 'default';

이제는 적절한 통합 연산자입니다.


답변

가장 큰 차이점은

  1. 삼항 연산자 표현식 expr1 ?: expr3은 평가
    되지만 리턴되는 expr1경우 Null Coalescing Operator 표현식 은 그렇지 않은 경우
    평가expr1TRUE(expr1) ?? (expr2)expr1expr1 NULL

  2. 삼항 연산자는 expr1 ?: expr3 왼쪽 값이 경우 통지를 방출 (expr1) 은 존재하지 않고 반면에 널 합체 운영자 (expr1) ?? (expr2) 왼쪽 값이 경우 특히, 통지를 방출하지 않는 (expr1) 것처럼 존재하지 않습니다 isset().

  3. TernaryOperator 가 연관되어 있습니다.

    ((true ? 'true' : false) ? 't' : 'f');

    Null Coalescing Operator 는 올바른 연관성입니다.

    ($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로 취급하지만 단축 삼항 연산자는 그렇지 않습니다. 그리고 그것은 염두에 두어야 할 것입니다.

$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


답변

둘 다 더 긴 표현을위한 속기입니다.

?:의 약자입니다 $a ? $a : $b. $ a가 TRUE 로 평가되면이 표현식은 $ a로 평가됩니다 .

??의 약자입니다 isset($a) ? $a : $b. $ a가 설정되고 널이 아닌 경우이 표현식은 $ a로 평가됩니다.

$ a가 정의되지 않았거나 null 인 경우 사용 사례가 겹칩니다. $ a가 정의되지 ??않으면 E_NOTICE가 생성 되지 않지만 결과는 같습니다. $ a가 null이면 결과는 같습니다.


답변

초보자를위한 :

Null 통합 연산자 (??)

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: ..

도움이 되었기를 바랍니다