스위치 사용 === 비교 == 비교 PHP에서


78

어쨌든 다음 코드가 여전히 스위치를 사용하고 반환 b하지 않도록 만들 수 a있습니까? 감사!

$var = 0;
switch($var) {
    case NULL : return 'a'; break;
    default : return 'b'; break;
}

물론 if 문을 사용하면 다음과 같이 할 수 있습니다.

$var = 0;
if($var === NULL) return 'a';
else return 'b';

그러나 더 복잡한 예의 경우 이것은 장황 해집니다.

답변:


55

죄송합니다 ===. switch () 문서 에 따르면 switch 문에서 비교를 사용할 수 없습니다 .

스위치 / 케이스는 느슨한 비교를 수행합니다.

즉, 해결 방법을 찾아야합니다. 에서 느슨한 비교 테이블 , 당신은 사실의 사용을 만들 수있는 NULL == "0"타입 캐스팅은 false입니다 :

<?php
$var = 0;
switch((string)$var) 
{
    case "" : echo 'a'; break; // This tests for NULL or empty string   
    default : echo 'b'; break; // Everything else, including zero
}
// Output: 'b'
?>

라이브 데모


1
음,이 작업을 수행하고 싶은 다른 상황 (NULL뿐 아니라)이 있습니다.
Aaron Yodaiken 2010-08-19

18

다음은 "엄격한"switch 문에있는 원본 코드입니다.

switch(true) {
    case $var === null:
        return 'a';
    default:
        return 'b';
}

다음과 같이 더 복잡한 switch 문을 처리 할 수도 있습니다.

switch(true) {
    case $var === null:
        return 'a';
    case $var === 4:
    case $var === 'foobar':
        return 'b';
    default:
        return 'c';
}

8

아니 switch-소위 "느슨한"비교 만 수행합니다. 을 if/else if사용하여 언제든지 블록으로 바꿀 수 있습니다 ===.


경험이나 문서를 언급하고 있습니까? 나중에 링크를 게시하십시오
TMS

1
당신은 실제로 와 이렇게 switch나는 그 생각하지만, (내 대답을 참조) if-else나은이 특정 작업입니다.
DaveRandom

좋은 답변이 많아서 미안합니다. 1 개만 고를 수 있습니다. if / elseif와 함께갔습니다. 감사합니다.
yar matie

사실 없다 "항상": 모든 경우 블록은 무엇이없는 경우 break또는 return?
Storm

3

아마도 당신은 변수를 켜고 정수를 기대하고 있습니다. 을 사용하여 변수의 정수 상태를 미리 확인하는 것은 is_int($val) 어떻습니까?


3

숫자가 포함 된 문자열이있는 스위치에서 동일한 문제가 발생했습니다 ( "15.2"는 PHP 용 스위치에서 "15.20"과 같습니다).

비교할 텍스트 앞에 문자를 추가하는 문제를 해결했습니다.

$var = '15.20';
switch ('#'.$var) {
    case '#15.2' :
      echo 'wrong';
    break;
    case '#15.20' :
      echo 'right';
    break;
}

1

스위치 사용 === 비교 == 비교 PHP에서

불행히도 switch느슨한 비교를 사용하며 내가 아는 한 그것을 변경할 방법이 없습니다.



1

난 그냥 사용

$var === null and $var = -1; // since switch is not type-safe
switch ( $var ) {
    case 0:
        # this tests for zero/empty string/false
        break;
    case -1:
        # this tests for null
        break;
}

로 시작하는 주석 //이 남겨진 경우 (그리고로 시작하는 주석은 #아마도 가장 잘 삭제 될 것입니다) 이것은 여전히 ​​매우 읽기 쉬워 보인다고 생각합니다 .


1

아니. 로부터 매뉴얼 페이지 :

스위치 / 케이스는 느슨한 비교를 수행 합니다.

두 가지 조건 만있는 경우 두 if번째 예제와 같은 것을 사용 하십시오. 그렇지 않으면 NULL먼저 확인 하고 다른 가능성을 켜십시오.

if (is_null($var))
{
  return 'a';
}

switch ($var)
{
    // ...
}

1

예제 코드에서 외삽하면 여러 일반 사례와 하나의 특수 사례가 있다고 생각합니다 (여기, null ).

내가 알아낼 수있는 가장 간단한 방법은 전환 전에이 케이스를 처리하는 것입니다.

if ($value === null) {
    return 'null';
}

switch ($value) {
    case 0:
        return 'zero';
    case 1:
        return 'one';
    case 2:
        return 'two';
}

기억할 주석을 추가하면 null예상치 않게 0케이스 와 일치 할 수 있습니다 (반대로 케이스 0와 일치 함 null).


1

예. PHP 8에서는 match문으로 할 수 있습니다 .

스위치와 달리 비교는 약한 동등성 검사 (==)가 아니라 신원 검사 (===)입니다. 일치 표현식은 PHP 8.0.0부터 사용할 수 있습니다.

여기를 참조하십시오 : https://www.php.net/manual/en/control-structures.match.php

$var=0;
echo match ($var) {
    NULL=> 'a',
    default => 'b'
};

0

이건 불가능 해.

그러나 다음과 같은 내부if명령문을 넣을 수 있습니다 .switch

switch($var) {
    // Loose cases here

    case 0:
        if($var === NULL) {
            return 'a';
        }

        // Fall through

    default:
        return 'b';
}

또는 간단히 :

switch($var) {
    // Loose cases here

    default:
        if($var === NULL) {
            return 'a';
        }

        return 'b';
}

7
그 시점에서 왜 스위치를 귀찮게합니까? `switch (true) {case $ var === null : ...}
ircmaxell

1
@ircmaxell, 나는 OP가 폴 스루 논리를 원하거나 switch때로는 엄격한 검사를 넘어서 사용할 이유를 원한다고 가정했습니다 .
strager

0

변수 유형을 켤 수도 있습니다.

switch (gettype($var)) {
...
}

나쁜 생각-문서에서 :Never use gettype() to test for a certain type, since the returned string may be subject to change in a future version. In addition, it is slow too, as it involves string comparison. Instead, use the is_* functions.
Peter Ajtai

gettype ()이 변경되면 함수가 쓸모없고 언어의 안정성이 떨어집니다. is_ *를 사용해도 스위치에 대한 질문에 답할 수 없습니다. 내가 :) 동의 나머지 부분
그렉

0

가장 좋은 방법 중 하나는 다음을 사용하여 NULL 값을 확인하는 것입니다. is_null

<?php
echo getValue();
function getValue()
{
    $var = 0;   
    switch(true) {
        case is_null($var) : return 'a'; break;
        default : return 'b'; break;
    }
}
?>

1
그러나 가장 좋은 === null점은 불필요한 함수 호출 오버 헤드를 방지하기 때문입니다.
Antti29

0

어설 션과 같은 클래스를 만들고 원하는 로직을 넣으십시오. "true"메서드가 반환되는 한 $this(그리고 거짓 긍정을 피하기위한 다른 것은 없습니다.)

class Haystack
{
    public $value;

    public function __construct($value)
    {
        $this->value = $value;
    }

    public function isExactly($n)
    {
        if ($n === $this->value)
            return $this;
    }
}

$var = new Haystack(null);

switch ($var) {
    case $var->isExactly(''):
        echo "the value is an empty string";
        break;

    case $var->isExactly(null):
        echo "the value is null";
        break;
}

또는 스위치를 실제 클래스에 넣을 수 있습니다.

class Checker
{
    public $value;

    public function __construct($value)
    {
        $this->value = $value;
    }

    public function isExactly($n)
    {
        if ($n === $this->value)
            return $this;
    }

    public function contains($n)
    {
        if (strpos($this->value, $n) !== false)
            return $this;
    }

    public static function check($str)
    {
        $var = new self($str);

        switch ($var) {
            case $var->isExactly(''):
                return "'$str' is an empty string";
            case $var->isExactly(null):
                return "the value is null";
            case $var->contains('hello'):
                return "'$str' contains hello";
            default:
                return "'$str' did not meet any of your requirements.";
        }
    }
}

var_dump(Checker::check('hello world'));   # string(28) "'hello world' contains hello"

물론 그 지점에서 확인중인 작업으로 수행하려는 작업을 재평가하고 대신 실제 유효성 검사 라이브러리를 사용하는 것이 좋습니다.


0

변수의 유형 을 모두 테스트하려면 두 정보를 모두 포함 하는 새 문자열 변수 를 빌드하고 연결을 통해 다른 시나리오와 비교합니다 ( gettype ( 에 따라) 가능한 모든 유형을 구현하면 해당 사례에서 작동합니다. ) 문서 ), 예 :

<?php
    $var= 9999;
    $valueAndTypeOfVar = (string)$var.' '.gettype($var);
    switch($valueAndTypeOfVar) {
        case "$var boolean" : echo 'a'; break;
        case "$var integer" : echo 'b'; break; 
        case "$var double" : echo 'c'; break;
        case "$var string" : echo 'd'; break; 
        case "$var array" : echo 'e'; break;
        case "$var object" : echo 'f'; break; 
        case "$var resource" : echo 'g'; break;
        case "$var NULL" : echo 'h'; break; 
        case "$var unknown type" : echo 'i'; break; 
        default: echo 'j'; break;
    }

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