? : PHP의 연산자 ( 'Elvis 연산자')


257

오늘 PHP 코드에서 이것을 보았습니다.

$items = $items ?: $this->_handle->result('next', $this->_result, $this);

?:여기에 사용되는 연산자에 익숙하지 않습니다 . 삼항 연산자처럼 보이지만 술어가 참인지 평가하는 표현식은 생략되었습니다. 무슨 뜻인가요?

답변:


528

왼쪽 피연산자가 true 이면 왼쪽 피연산자를 평가하고 그렇지 않으면 오른쪽 피연산자를 평가합니다.

의사 코드에서

foo = bar ?: baz;

대략적으로 해결하다

foo = bar ? bar : baz;

또는

if (bar) {
    foo = bar;
} else {
    foo = baz;
}

bar한 번만 평가 되는 차이점이 있습니다.

foo코드를 사용하여 게시 한 코드 예제에서 설명한 "자체 검사"를 수행 할 수도 있습니다 .

foo = foo ?: bar;

이것은 null 또는 false 인 경우에 할당 bar되며 , 그렇지 않으면 변경되지 않습니다.foofoofoo

몇 가지 예 :

<?php
    var_dump(5 ?: 0); // 5
    var_dump(false ?: 0); // 0
    var_dump(null ?: 'foo'); // 'foo'
    var_dump(true ?: 123); // true
    var_dump('rock' ?: 'roll'); // 'rock'
?>

그건 그렇고, Elvis 연산자 라고합니다 .

엘비스 연산자


11
괄호 안의 변수가 존재하는지 확인하십시오. 그렇지 않으면 오류가 발생합니다. PHP는 단지 그 가치가 있다고 가정하지 않습니다 null. 그냥 '선생님
DanMan

20
재미있는 점은이 답변이 Wiki 기사와 함께 재귀 루프를 형성한다는 것인데, 왜 이것이 "Elvis operator"라고 불리는 지 완전히 설명하지 못했습니다.
seeming.amusing

41
조작이 적고 표현을 조금 더하십시오.
aalaap

2
왜을 사용하지 않습니까 ||? 그래서 blah || 'default'?
Noitidart

10
@Noitidart 가장 왼쪽의 피연산자를 반환하는 JS와 달리 PHP에서는 ||연산자가 항상 부울을 반환합니다.
ksadowski 2016 년

58

문서를 참조하십시오 :

PHP 5.3부터는 삼항 연산자의 중간 부분을 생략 할 수 있습니다. 로 평가 되면 식이 expr1 ?: expr3반환 되고 그렇지 않으면 식이 반환 expr1됩니다 .expr1TRUEexpr3


10
누군가는 필연적으로 expr2에 무슨 일이 있었는지 물어볼 수 있기 때문에 새로운 문서 작성자가 필요합니다. 나는 단지 그것을 썽크했다.
John K

7
이런 젠장? PHP 7로 업그레이드 한 직후 에이 사실을 알 수 있습니까? 나는 이것을 몇 년 동안 사용해 왔을 수 있습니다!
Buttle Butkus

TBH, 문서가 정확합니다. 일어난 일은 expr2방금 사라졌고 평가되지 않았다는 것입니다. $this->expensiveComputation() ?: "nope"동일하지 않은 $this->expensiveComputation() ? $this->expensiveComputation() : "nope"한 번만 평가 expr1을 -.
Piskvor 건물 왼쪽

18

배열에주의하십시오. 다음에 검사 변수를 작성해야합니다 ?.

  $params = ['param1' => 'value1',
             'param2' => 'value2',
             'param3' => 'value3',];

  $param1 = isset($params['param1'])?:null;
  $param2 = !empty($params['param2'])?:null;
  $param3 = $params['param3']?:null; // get E_NOTICE, if $params['param3'] eq false

  var_dump($param1,$param2,$param3);
  true // would like to expect `value1`
  true // would like to expect `value2`
  param3 // properly, but problem above

업데이트

RFC에서. 앞으로 (PHP 7에서) 연산자 Null Coalesce Operator 가 다음과 같이 할 것입니다.

$param1 = $params['param1'] ?? null;
// Equivalent to:  $param1 = isset($params['param1']) ? $params['param1'] : null;

1
이것은 질문에 대한 답이 아니며, Elvis Operator를 언제 사용해야하는지 이해하려는 사람에게는 유용하지 않습니다.
Mark Amery

7
@ 마크 애 머리 흠 .. 정말? 도움이되지 않습니까? 실제로 PHP로 작업하고 삼항으로 배열의 var에 액세스하는 데 수천 가지 사례를 보았습니까? 좋아, 텍스트를 "배열에주의하십시오."로 변경했습니다.
voodoo417

널 합체와 엘비스는 동일합니까?
Nabeel Khan

7
@NabeelKhan 아니요! 그리고 이것은 Elvis 연산자를 PHP imo에서 쓸모 없게 만듭니다. Elvis 연산자는 표현식을 평가하고, 참이면 마지막 부분을 반환합니다. PHP는 형식이 낮기 때문에 많은 것이 사실이거나 거짓이며 대부분의 것이 당신이 원하는 것이 아닐 것입니다. 즉 : Elvis 연산자를 사용하여 변수가 정의되어 있지 않은 경우 기본값을 변수로 설정하려고합니다 .PHP는 0이 정의되어 있지 않다고 말하지만 0을 원할 수 있습니다. , 그것은 null에 대해 변수를 엄격하게 테스트하므로 PHP는 0이 정의되지 않았다고 말합니다.
Gregoire D.

1
@FuscaSoftware : 이와 같은 오류 억제를 사용하는 것은 내 경험에 좋은 생각이 아닙니다.
TeeHays

8

또 다른 중요한 고려 사항 : Elvis Operator는 Zend Opcache 토큰 화 프로세스를 중단합니다. 나는 이것이 어려운 길을 찾았다! 이것은 이후 버전에서 수정되었을 수도 있지만,이 문제가 PHP 5.5.38 (내장 Zend Opcache v7.0.6-dev)에 존재 함을 확인할 수 있습니다.

일부 파일이 Zend Opcache에 캐싱되는 것을 '거부'한다는 것을 알게되면 이것이 이유 중 하나 일 수 있습니다.


4

예, 이것은 PHP 5.3의 새로운 기능입니다. TRUE로 평가되면 테스트 표현식의 값을, FALSE로 평가되면 대체 값을 리턴합니다.


2
미묘하게 잘못된 / 오도하는; 피연산자는 부울이어야합니다. 중요한 것은 첫 번째 가치가 진실 인지 아닌지 여부 TRUE입니다.
Mark Amery

@MarkAmery 명확 해졌습니다. 이런 식으로 잘못 해석하기는 상당히 어렵습니다.
Atli
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.