programing

케이스당 여러 개의 값을 가진 PHP 스위치를 사용하는 가장 좋은 방법은 무엇입니까?

copysource 2022. 12. 10. 14:29
반응형

케이스당 여러 개의 값을 가진 PHP 스위치를 사용하는 가장 좋은 방법은 무엇입니까?

이 PHP 스위치 문은 어떻게 하시겠습니까?

또한 이들은 훨씬 더 작은 버전이기 때문에 작성해야 할 1은 훨씬 더 많은 값이 추가됩니다.

버전 1:

switch ($p) { 
    case 'home': 
    case '': 
        $current_home = 'current';
    break; 

    case 'users.online': 
    case 'users.location': 
    case 'users.featured': 
    case 'users.new': 
    case 'users.browse': 
    case 'users.search': 
    case 'users.staff': 
        $current_users = 'current';
    break;

    case 'forum': 
        $current_forum = 'current';
    break; 
} 

버전 2:

switch ($p) { 
    case 'home': 
        $current_home = 'current';
    break; 

    case 'users.online' || 'users.location' || 'users.featured' || 'users.browse' || 'users.search' || 'users.staff': 
        $current_users = 'current';
    break;

    case 'forum': 
        $current_forum = 'current';
    break; 
} 

업데이트 - 테스트 결과

속도 테스트를 10,000번 반복해서 해봤는데

시간 1: 0.0199389457703 // If 스테이트먼트
시간 2: 0.038904946106 //switch 문
시간 3: 0.106977939606 // 어레이

알 수 없는 문자열이 있어 다른 문자열 중 어떤 문자열과 일치하는지 파악해야 하는 경우 항목을 추가해도 속도가 느려지지 않는 유일한 해결책은 어레이를 사용하는 것이지만 가능한 모든 문자열을 키로 사용하는 것입니다.따라서 스위치는 다음과 같이 교환할 수 있습니다.

// used for $current_home = 'current';
$group1 = array(
        'home'  => True,
        );

// used for $current_users = 'current';
$group2 = array(
        'users.online'      => True,
        'users.location'    => True,
        'users.featured'    => True,
        'users.new'         => True,
        'users.browse'      => True,
        'users.search'      => True,
        'users.staff'       => True,
        );

// used for $current_forum = 'current';
$group3 = array(
        'forum'     => True,
        );

if(isset($group1[$p]))
    $current_home = 'current';
else if(isset($group2[$p]))
    $current_users = 'current';
else if(isset($group3[$p]))
    $current_forum = 'current';
else
    user_error("\$p is invalid", E_USER_ERROR);

이건 그렇게 깨끗해 보이지 않아switch()그러나, 이것은 깔끔하게 유지하기 위해 작은 기능 및 수업 라이브러리를 작성하는 것을 포함하지 않는 유일한 빠른 해결책이다.어레이에 항목을 추가하는 것은 여전히 매우 간단합니다.

버전 2는 동작하지 않습니다!!

case 'users.online' || 'users.location' || ...

는, 다음과 같습니다.

case True:

그리고 그것case어떤 가치에도 선택될 것이다$p,~하지 않는 한$p빈 문자열입니다.

||내부에는 특별한 의미가 없습니다.case스테이트먼트, 비교하고 있지 않습니다.$p각각의 문자열에 대해, 당신은 단지 그것이 아닌지를 확인하는 것 뿐입니다.False.

스위치 케이스는 문자열 변수를 조건으로 사용할 때 달성하려는 기본 의미를 숨기고 읽기 및 이해를 어렵게 하기 때문에 이러한 값을 배열에 넣고 배열에 대해 쿼리합니다.

$current_home = null;
$current_users = null;
$current_forum = null;

$lotsOfStrings = array('users.online', 'users.location', 'users.featured', 'users.new');

if(empty($p)) {
    $current_home = 'current';
}

if(in_array($p,$lotsOfStrings)) {
    $current_users = 'current';
}

if(0 === strcmp('forum',$p)) {
    $current_forum = 'current';
}

완전성을 위해 고장난 '버전2' 로직은 스위치 스테이트먼트로 대체하여 동작할 수 있습니다., 다음과 같이, 속도와 선명함을 위해서 어레이를 사용할 수도 있습니다.

// used for $current_home = 'current';
$home_group = array(
    'home'  => True,
);

// used for $current_users = 'current';
$user_group = array(
    'users.online'      => True,
    'users.location'    => True,
    'users.featured'    => True,
    'users.new'         => True,
    'users.browse'      => True,
    'users.search'      => True,
    'users.staff'       => True,
);

// used for $current_forum = 'current';
$forum_group = array(
    'forum'     => True,
);

switch (true) {
    case isset($home_group[$p]):
        $current_home = 'current';
        break;
    case isset($user_group[$p]):
        $current_users = 'current';
        break;
    case isset($forum_group[$p]):
        $current_forum = 'current';
        break;
    default:
        user_error("\$p is invalid", E_USER_ERROR);
}    

요즘에는 할 수 있어요.

switch ([$group1, $group2]){
    case ["users", "location"]:
    case ["users", "online"]:
        Ju_le_do_the_thing();
        break;
    case ["forum", $group2]:
        Foo_the_bar();
        break;
}

다음은 이 개념을 설명하는 즉시 실행 가능한 코드 세트입니다.

<?php

function show_off_array_switch(){
  $first_array = ["users", "forum", "StubbornSoda"];
  $second_array = ["location", "online", "DownWithPepsiAndCoke"];

  $rand1 = array_rand($first_array);
  $rand2 = array_rand($second_array);

  $group1 = $first_array[$rand1];
  $group2 = $second_array[$rand2];

  switch ([$group1, $group2]){
      case ["users", "location"]:
      case ["users", "online"]:
          echo "Users and Online";
          break;
      case ["forum", $group2]:
          echo "Forum and variable";
          break;
      default:
          echo "default";
  }
  echo "\nThe above result was generated using the array: \n" . print_r([$group1, $group2], true);
}

for ($i = 0; $i < 10; $i++){
  show_off_array_switch();
}

다음 출력은 (1회 랜덤 실행의 경우) 다음과 같습니다.

 Users and Online
The above result was generated using the array: 
Array
(
    [0] => users
    [1] => online
)
Users and Online
The above result was generated using the array: 
Array
(
    [0] => users
    [1] => online
)
default
The above result was generated using the array: 
Array
(
    [0] => users
    [1] => DownWithPepsiAndCoke
)
Users and Online
The above result was generated using the array: 
Array
(
    [0] => users
    [1] => location
)
Forum and variable
The above result was generated using the array: 
Array
(
    [0] => forum
    [1] => DownWithPepsiAndCoke
)
Forum and variable
The above result was generated using the array: 
Array
(
    [0] => forum
    [1] => DownWithPepsiAndCoke
)
Forum and variable
The above result was generated using the array: 
Array
(
    [0] => forum
    [1] => online
)
default
The above result was generated using the array: 
Array
(
    [0] => StubbornSoda
    [1] => location
)
Users and Online
The above result was generated using the array: 
Array
(
    [0] => users
    [1] => location
)
Users and Online
The above result was generated using the array: 
Array
(
    [0] => users
    [1] => location
)

만약 다른 사람이 당신의 코드를 유지한다면, 그들은 버전 2를 더블테이크 할 것입니다.이것은 매우 비표준적인 것입니다.

난 버전 1을 고수할 거야.저는 진술 블록이 없는 사건 진술은 명시적이어야 한다고 생각합니다.// fall through그 옆에 있는 코멘트를 통해 실제로 실패하려는 의도가 있음을 알 수 있습니다.이를 통해 사건을 다르게 처리할 것인지 잊어버릴 것인지의 애매함을 해소할 수 있습니다.

아직 언급되지 않은 다른 아이디어:

switch(true){ 
  case in_array($p, array('home', '')): 
    $current_home = 'current'; break;

  case preg_match('/^users\.(online|location|featured|new|browse|search|staff)$/', $p):
    $current_users = 'current'; break;

  case 'forum' == $p:
    $current_forum = 'current'; break; 
}

#2의 가독성 문제로 인해 누군가가 불만을 제기할 수 있지만, 저는 그러한 코드를 상속하는 데 문제가 없습니다.

버전 1이 보기 쉽고, 의도도 명확하며, 케이스 조건도 쉽게 추가할 수 있습니다.

두 번째 버전은 한 번도 안 먹어봤어요.많은 언어에서는 각 케이스 라벨이 일정한 식에 대해 평가해야 하기 때문에 컴파일조차 할 수 없습니다.

저는 버전 1을 확실히 선호합니다.버전 2에서는 필요한 코드 행이 적을 수 있지만 예측대로 값이 많이 포함되어 있으면 읽기가 매우 어렵습니다.

(솔직히 지금까지 버전2가 합법적인지도 몰랐어요.그런 식으로 하는 건 처음 봐요.)

어떤 버전 2도 실제로 작동하지 않지만, 이러한 접근 방식을 원한다면 다음을 수행할 수 있습니다(가장 빠르지는 않지만 직관적일 수 있음).

switch (true) {
case ($var === 'something' || $var === 'something else'):
// do some stuff
break;
}

아마도요.

        switch ($variable) {
        case 0:
            exit;
            break;
        case (1 || 3 || 4 || 5 || 6):
            die(var_dump('expression'));
        default:
            die(var_dump('default'));
            # code...
            break;
    }

버전 1이 최선인 것 같아요.그것은 읽고 이해하는 것이 훨씬 더 쉽다.

if( in_array( $test, $array1 ) )
{
    // do this
}
else if( stristr( $test, 'commonpart' ) )
{
    // do this
}
else
{
    switch( $test )
    {
        case 1:
            // do this
            break;
        case 2:
            // do this
            break;
        default:
            // do this
            break;
    }
}

스위치를 변수와 조합하면 유연성이 향상됩니다.

<?php
$p = 'home'; //For testing

$p = ( strpos($p, 'users') !== false? 'users': $p);
switch ($p) { 
    default:
        $varContainer = 'current_' . $p; //Stores the variable [$current_"xyORz"] into $varContainer
        ${$varContainer} = 'current'; //Sets the VALUE of [$current_"xyORz"] to 'current'
    break;

}
//For testing
echo $current_home;
?>

자세한 내용은 변수 체크 아웃 및 php 매뉴얼에 제출한 예를 참조하십시오.
1: http://www.php.net/manual/en/language.variables.variable.php#105293
2: http://www.php.net/manual/en/language.variables.variable.php#105282

PS: 이 코드는 작고 심플합니다.마음에 드는 대로입니다.테스트 완료, 동작도 가능

단순히 문자열에서 일반적인 패턴을 찾고 있습니다.PHP가 preg_match를 사용하여 구현하기 때문에 쓰기 위한 코드가 거의 없고 아마도 훨씬 더 빠르기 때문에 정규 표현이 더 효율적인 방법이라고 생각했습니다.예를 들어 다음과 같습니다.

case preg_match('/^users./'):
// do something here
break;

PHP 매뉴얼에서 이 작업을 수행할 수 있습니다.https://www.php.net/manual/en/control-structures.switch.php#41767

$input = 'users.online';
$checked = null;
        
switch (true):
    case ($input === 'home'):
        $checked = 'ok 1';
        break;

    case (in_array($input , ['users.online', 'users.location', 'users.featured', 'users.browse', 'users.search', 'users.staff'])):
        $checked = 'ok 2';
        break;

    case ($input === 'forum'):
        $checked = 'ok 3';
        break;
endswitch;

echo $checked;

언급URL : https://stackoverflow.com/questions/1309728/best-way-to-do-a-php-switch-with-multiple-values-per-case

반응형