PHP를위한 통합 함수?


131

많은 프로그래밍 언어에는 병합 기능이 있습니다 ( 예 : 첫 번째 NULL이 아닌 값을 반환 함 ). 슬프게도 2009 년에 PHP는 그렇지 않습니다.

PHP 자체가 통합 기능을 얻을 때까지 PHP에서 구현하는 좋은 방법은 무엇입니까?


11
PHP 7 의 새로운 null 통합 연산자 ??
kojiro

null 병합 연산자에 대한 자세한 내용은 여기를 참조하십시오.- stackoverflow.com
Peter

1
그냥 참고로, PHP7이 fucntion 구현
그르

@Grzegorz : 연산자는 함수가 아니거나 PHP 7에서 그 함수가 어디에서 새로 발견
되었습니까?

기능에 의해 나는 기능을 의미하지 않았다;) 기능. 나는 정확하지 않았다. 감사합니다 :)
Grzegorz

답변:


194

PHP 5.3에는 새로운 연산자가 있습니다. ?:

// A
echo 'A' ?: 'B';

// B
echo '' ?: 'B';

// B
echo false ?: 'B';

// B
echo null ?: 'B';

출처 : http://www.php.net/ChangeLog-5.php#5.3.0


25
"echo $ a? : $ b? : $ c? : $ d;"와 같은 여러 삼항 단축키는 어떻습니까? 작업?
ChrisR

5
배열에 대해 예상대로 작동하지 않습니다. 예를 들어 정의되지 않은 배열 요소가 거짓인지 확인하려고하면 오류가 발생합니다. $input['properties']['range_low'] ?: '?'
Keyo

5
통합 연산자 사용에 상관없이 정의되지 않은 색인 통지를 받아야합니다.
Kevin

2
여러 개의 잘못된 인수는 마지막 인수를 array() ?: null ?: false반환 하고를 반환합니다 false. 운영자는 제정신입니다.
Brad Koch

6
이것은 다른 언어의 병합과 같이 널이 아닌 것을 허용하는 것이 아니라 내재적으로 부울로 변환되는 모든 값을 받아들입니다. 따라서 타입 캐스팅 규칙을 따라야합니다
DanMan

65

PHP 7은 실제 통합 연산자를 도입했습니다 .

echo $_GET['doesNotExist'] ?? 'fallback'; // prints 'fallback'

(가)하기 전에 값 경우 ??하지 않습니다 존재이거나 null이 후 값을 ??가져옵니다.

언급 된 ?:연산자에 비해 개선 된 점은 ??을 던지지 않고 정의되지 않은 변수도 처리한다는 것 E_NOTICE입니다.


마지막으로 더 이상 isset () 및 empty ()가 없습니다!
George Kagan

7
@timeNomad는 여전히 비어있을 것입니다. null 만 검사합니다
Nabeel Khan

안전한 "거짓 병합"을 얻는 유일한 방법은 다음 두 가지를 모두 사용하는 것입니다.($_GET['doesNotExist'] ?? null) ?: 'fallback'
Nathan Baulch

그러나 ?:over 의 장점은 ??빈 값을 통합하고 ??그렇지 않은 빈 값을 통합한다는 것 입니다. 자바 스크립트 (즉의 논리 OR 연산자의 동작과 유사 $val || 'default'), 나는 찾을 것 ?:보다 실제적인 형태로 병합 우리가 궁극적으로 자신을 모두 처리 찾아 우리의 연습하면 널 (null) 같은 방법으로 (즉,에서 $val ?: 'default'). 그리고 당신 E_NOTICE이이 문제를 더 강요하고 삼키고 싶다면 , 당신은 이것을 다음 과 같이 주장 할 수 있습니다 :echo @$val ?: 'default';
Matt Borja

29

Google에서 "php coalesce"를 처음 방문했습니다.

function coalesce() {
  $args = func_get_args();
  foreach ($args as $arg) {
    if (!empty($arg)) {
      return $arg;
    }
  }
  return NULL;
}

http://drupial.com/content/php-coalesce


9
램을 조금만 저장하고 args를 배열로 복제하지 마십시오. foreach (func_get_args ()를 $ arg) {}
TravisO

17
@ [Alfred, Ciaran]-잘못되었습니다. foreach ()는 첫 번째 인수를 한 번만 평가하여 배열을 가져온 다음 반복합니다.
gahooa 2009

6
foreach (여기서는 $ arg) 안에 func_get_args ()를 넣으면 성능 관점에서 아무것도 변경되지 않습니다.
Savageman 2009

7
@Savageman ... 정확히 ... 응용 프로그램에서이 밀리 초의 성능 또는 몇 바이트의 메모리를 압축하려는 경우 잘못된 성능 / 메모리 병목 현상이 발생
했을 수 있습니다.

4
아이러니하게도, 이것은 이제 구글에서 "php coalesce"에 대한 첫 번째 히트입니다.
Will Shaver

18

나는 정말로? : 연산자를 좋아한다. 불행히도 아직 프로덕션 환경에서 구현되지 않았습니다. 그래서 나는 이것과 동등한 것을 사용합니다 :

function coalesce() {
  return array_shift(array_filter(func_get_args()));
}

1
이것은 전달 된 n 인수에서 false (널 포함)로 평가되는 것을 제거하기 위해 array_filter를 사용하는 '무결 한'일체형입니다. 배열의 첫 번째 요소 대신 shift를 사용하는 것이 다소 강력하지만 몰라요 참조 : php.net/manual/en/…
Adam Tolley

3
나는 그것을 좋아하지만 @hakre와 동의 coalesce해야합니다 -포함하는 null이 아닌 첫 번째 인수 를 반환해야합니다 FALSE. 이 함수는 FALSEop가 생각한 것이 아니라 (적어도 내가 coalesce함수에서 원하지 않는 것은 아닙니다) 버릴 것 입니다.
Madbreaks 2013

1
변수 만 참조로 전달해야합니다
Ben Sinclair

9

PHP가 초기화되지 않은 변수와 배열 인덱스를 처리했기 때문에 모든 종류의 병합 함수는 제한적으로 사용됩니다. 나는 이것을 할 수 있기를 바랍니다.

$id = coalesce($_GET['id'], $_SESSION['id'], null);

그러나 이것은 대부분의 경우 PHP가 E_NOTICE와 함께 오류를 발생시킵니다. 변수를 사용하기 전에 변수의 존재를 테스트하는 유일한 안전한 방법은 empty () 또는 isset ()에서 직접 사용하는 것입니다. 통합의 모든 옵션이 초기화 된 것으로 알려진 경우 Kevin이 제안한 3 항 연산자가 가장 좋습니다.


이 경우 배열 공용체는 꽤 잘 작동합니다 ( $getstuff = $_GET+$_SESSION+array('id'=>null);$id=$getstuff['id'];).
Brilliand

@Quill 그게 무슨 뜻입니까? 추천 솔루션을 참조 했습니까?
Ben Sinclair

PHP 7 은이 새로운 공통 삼항 연산자 ??를 도입하여 매우 일반적인 작업을보다 간결하게 만듭니다.
botimer

6

이 기능이 특정 유형에서 작동하는 방식을 정확하게 식별하십시오. PHP에는 다양한 유형 검사 또는 유사한 기능이 있으므로 작동 방식을 알아야합니다. is_null ()과 empty ()을 비교 한 예제입니다.

$testData = array(
  'FALSE'   => FALSE
  ,'0'      => 0
  ,'"0"'    => "0"  
  ,'NULL'   => NULL
  ,'array()'=> array()
  ,'new stdClass()' => new stdClass()
  ,'$undef' => $undef
);

foreach ( $testData as $key => $var )
{
  echo "$key " . (( empty( $var ) ) ? 'is' : 'is not') . " empty<br>";
  echo "$key " . (( is_null( $var ) ) ? 'is' : 'is not')  . " null<br>";
  echo '<hr>';
}

보시다시피 empty ()는이 모든 것에 대해 true를 반환하지만 is_null ()은 그 중 2에 대해서만 true를 반환합니다.


2

Ethan Kent가 게시 한 답변을 확장하고 있습니다. 이 답변은 array_filter 의 내부 작업으로 인해 null로 평가되는 null이 아닌 인수를 삭제 coalesce합니다. 이 함수는 일반적으로 함수가 수행하지 않습니다. 예를 들면 다음과 같습니다.

echo 42 === coalesce(null, 0, 42) ? 'Oops' : 'Hooray';

죄송합니다

이를 극복하기 위해 두 번째 인수와 함수 정의가 필요합니다. 호출 기능은 말에 대한 책임이 array_filter결과 배열에 현재 배열 값을 추가할지 여부를 :

// "callable"
function not_null($i){
    return !is_null($i);  // strictly non-null, 'isset' possibly not as much
}

function coalesce(){
    // pass callable to array_filter
    return array_shift(array_filter(func_get_args(), 'not_null'));
}

단순히 isset또는 'isset'에 두 번째 인수로 전달할 수 있다면 array_filter좋지만 그러한 행운은 없습니다.


0

나는 현재 이것을 사용하고 있지만 PHP 5의 새로운 기능 중 일부로 개선 될 수 없는지 궁금합니다.

function coalesce() {
  $args = func_get_args();
  foreach ($args as $arg) {
    if (!empty($arg)) {
    return $arg;
    }
  }
  return $args[0];
}

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.