변수에 기본값을 지정하는 가장 좋은 방법 (Perl ||, || = 시뮬레이션)


134

펄에서 이런 종류의 일을 사랑 : $foo = $bar || $baz할당 $baz$foo경우 $bar비어 있거나 정의되지 않습니다. 또한이 $foo ||= $bletch단지 지정되는 $bletch$foo있는 경우$foo 정의되지 않았거나 비어 있지 않은 .

이 상황에서 삼항 연산자는 지루하고 지루합니다. PHP에서 간단하고 우아한 방법을 사용할 수 있습니까?

아니면 유일한 대답은 isset ()을 사용하는 사용자 정의 함수입니까?



1
BTW 원하는 기능을 가진 펄 사업자는 //그리고 //=그들은 펄 v5.10.0의로 존재한다. 정의가 아닌 논리적 가치에 대한 원본 ||||=테스트.
Palec

@Palec, 왜 29 upvotes를 가진 4 살짜리 질문이 6 upvotes를 가진 1 살짜리 질문의 복제물로 식별됩니까 (그 자체가 다른 질문의 복제물로 표시 되었습니까?) 제목이 더 일반적이기 때문에 질문에 답하십시오 (예 : isset ()).
Tom Auger

명확하고 정확한 복제본입니다. 그것은 어느 것이 원본이어야하는지에 대해 많이 생각하지 않았 음을 인정합니다. 나는 다른 것의 중간에 있었고, 둘 사이의 연결을 만드는 것이 목표였습니다. 내 VTC를 취소합니다.
Palec

다른 질문의 복제본으로 잘못 표시된 (IMO 오류) 정확한 복제본 : isset ()의 PHP 속기?
Palec

답변:


130

PHP 7에서는 마침내이를 우아하게 처리 할 수있는 방법이 있습니다. 이를 Null 통합 연산자 라고합니다 . 다음과 같이 사용할 수 있습니다.

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

이것은

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

14
우주선 운영자 도 장점이 있다고 주장합니다 .
Mariano

3
마리아노가 다리를 잡아 당기는 줄 알았는데, 그렇습니다. <=>부팅 하는 것은 꽤 정확합니다!
HPWD

1
널 병합 연산자는 값에 따라 다르므로 조건부 연산자와 다르게 작동 null합니다. 예를 들어 $_GET['name']빈 문자열로 설정된 경우 첫 번째 줄은 빈 문자열을 반환하지만을 사용하여 "john doe"를 반환 할 수 $_GET['name'] ? $_GET['name'] : 'john doe'있습니다.
VPhantom

211

PHP 5.3에는 속기 ?:연산자가 있습니다.

$foo = $bar ?: $baz;

$bar빈 값이 아닌 경우 할당 합니다 (PHP에서 Perl과 어떻게 다른지 모르겠습니다). 그렇지 않으면 $bazPerl 및 이전 버전의 PHP에서와 동일합니다.

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

그러나 PHP에는 이에 대한 복합 할당 연산자가 없습니다 (즉, Perl과 동일하지 않음 ||=).

또한, $bar알림을 끄지 않으면 PHP가 설정되어 있지 않으면 소리 가납니다. 사이의 의미 적 차이도있다 isset()하고 empty(). 변수가 존재하지 않거나로 설정된 경우 전자는 false를 반환합니다 NULL. 사실 후자의 반환은 존재하지 않는, 또는로 설정되어있는 경우 0, '', false또는 NULL.


2
+1 5.3의 또 다른 훌륭한 기능을 소개하기 위해 RHEL5 / PHP5.1.2 서버에서 빠졌습니다.
Michael Berkowski

나는 당신이 두 번째 문장 The first returns대신에 의미 하는 것 같아요 The second.
토토

21
변수가 정의되어 있지 않으면 PHP는 그에 대한 통지를 던집니다. 불행히도 이것은 대치하지 않습니다. $var = isset($var) ? $var : 'default value'; 그것은 대답에서 ... 그것을 스키를 타는 사람을 위해 다시 지적한다고 말합니다. :-D
Brad

6
$ var = @ $ var하는 것이 좋지 않습니까? : 'default value'; 그렇다면 왜 그렇습니까? 유일하게 "오류"는 $ 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. 그러나 그는 어쨌든 그들을 피하고 싶어하는 것 같습니다.
mario

6

7. * 이전의 PHP에서는 다음과 같이 로컬에 오류가 표시되지 않은 정의되지 않은 변수에? :를 사용할 수 있습니다 @.

$foo = @$bar ?: $baz;

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 또는 다른 것과 같은 두 번째 매개 변수로 무거운 것을 사용하지 마십시오. 그러한 경우, 당신은 isseting을 사용하는 것이 좋습니다.

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