【问题标题】:Improve switch statement in PHP or suggest an alternative workaround改进 PHP 中的 switch 语句或建议替代解决方法
【发布时间】:2017-06-03 16:58:45
【问题描述】:

我正在尝试改进下面的 switch 语句。这里发生的情况是,根据找到的 x 个令牌多次调用代码,因此下面的代码每个令牌运行一次。

如果未找到$post->ID,则会向该令牌发送通知,并将 ID 添加到数据库中。

这可行,但是在某些时候它会在大约 40% 的令牌检查后停止,大概是因为找到了 ID?由于我在 wordpress 上,我使用update_option 将 id 存储在表中,但也许可以使用另一种方法?

$os = $this->os;
switch ($os) {

    case "iOS":
        $iOS_pastPushSavedID = get_option( 'iOS_pastPushSavedID',  $default = false);
        if($post->ID != $iOS_pastPushSavedID) {
            update_option( 'iOS_pastPushSavedID', $post->ID, no);
            $sendPush = true;
            //$title = ($os . '_New Push = ' . ' storedID: ' . $iOS_pastPushSavedID . ' / postID: ' . $post->ID);   
        } else {
            //$title = ($os . '_Duplicate Push = ' . ' storedID: ' . $iOS_pastPushSavedID . ' / postID: ' . $post->ID); 
            $sendPush = false;
        }
    break;

    case "Android":
        $android_pastPushSavedID = get_option( 'android_pastPushSavedID',  $default = false);
        if($post->ID != $android_pastPushSavedID) {
            //$title = ($os . '_New Push = ' . ' storedID: ' . $android_pastPushSavedID . ' / postID: ' . $post->ID);
            update_option( 'android_pastPushSavedID', $post->ID, no);
            $sendPush = true;           
        } else {
            //$title = ($os . '_Duplicate Push = ' . ' storedID: ' . $android_pastPushSavedID . ' / postID: ' . $post->ID);
            $sendPush = false;
        }
    break;

    case "Fire OS":
        $fireos_pastPushSavedID = get_option( 'fireos_pastPushSavedID',  $default = false);
        if($post->ID != $fireos_pastPushSavedID) {
            //$title = ($os . '_New Push = ' . ' storedID: ' . $fireos_pastPushSavedID . ' / postID: ' . $post->ID);
            update_option( 'fireos_pastPushSavedID', $post->ID, no);
            $sendPush = true;           
        } else {
            //$title = ($os . '_Duplicate Push = ' . ' storedID: ' . $fireos_pastPushSavedID . ' / postID: ' . $post->ID);
            $sendPush = false;
        }
    break;

    case "Safari":
        $safari_pastPushSavedID = get_option( 'safari_pastPushSavedID',  $default = false);
        if($post->ID != $safari_pastPushSavedID) {
            //$title = ($os . '_New Push = ' . ' storedID: ' . $safari_pastPushSavedID . ' / postID: ' . $post->ID);
            update_option( 'safari_pastPushSavedID', $post->ID, no);
            $sendPush = true;

        } else {
            //$title = ($os . '_Duplicate Push = ' . ' storedID: ' . $safari_pastPushSavedID . ' / postID: ' . $post->ID);
            $sendPush = false;
        }
    break;

    case "Chrome":
        $chrome_pastPushSavedID = get_option( 'chrome_pastPushSavedID',  $default = false);
        if($post->ID != $chrome_pastPushSavedID) {
            //$title = ($os . '_New Push = ' . ' storedID: ' . $chrome_pastPushSavedID . ' / postID: ' . $post->ID);
            update_option( 'chrome_pastPushSavedID', $post->ID, no);
            $sendPush = true;           
        } else {
            //$title = ($os . '_Duplicate Push = ' . ' storedID: ' . $chrome_pastPushSavedID . ' / postID: ' . $post->ID);
            $sendPush = false;
        }
    break;

    case "Firefox":
        $firefox_pastPushSavedID = get_option( 'firefox_pastPushSavedID',  $default = false);
        if($post->ID != $firefox_pastPushSavedID) {
            //$title = ($os . '_New Push = ' . ' storedID: ' . $firefox_pastPushSavedID . ' / postID: ' . $post->ID);
            update_option( 'firefox_pastPushSavedID', $post->ID, no);
            $sendPush = true;

        } else {
        //$title = ($os . '_Duplicate Push = ' . ' storedID: ' . $firefox_pastPushSavedID . ' / postID: ' . $post->ID);
            $sendPush = false;
        }
    break;

    default:
        $sendPush = false;
}

【问题讨论】:

    标签: php wordpress switch-statement


    【解决方案1】:

    除非我误解了您的流程,否则这是一种非常干/简洁的方式,无需冗长的switch/case 块:

    $os_opts=[
        'iOS'=>'iOS',
        'Android'=>'android',
        'Fire OS'=>'fireos',
        'Safari'=>'safari',
        'Chrome'=>'chrome',
        'Firefox'=>'firefox'
    ];
    
    $os=$this->os;
    $sendPush=false;
    if(isset($os_opts[$os])){                           // deny empty and invalid options
        $os_opt="{$os_opts[$os]}_pastPushSavedID";     // build string for next two functions
        if($post->ID!=get_option($os_opt,$default=false)){
            update_option($os_opt,$post->ID,no);
            $sendPush = true;
        }
    }
    

    $os_opts 数组的键与 $os 匹配,值与 get_option()update_option() 匹配。这将大大减少代码长度,并使未来的修改变得非常容易。

    由于get_option()结果只使用了一次,所以将其声明为变量是没有意义的;只需在 if 条件中使用它即可。

    get_option()update_option() 的第一个参数总是以相同的子字符串结尾。我在前面加上 $os_opts[$os] 值并将其声明为变量是有意义的。变量声明不是必要的,但我个人的规则是;如果您要多次使用数据,请使用一个变量,如果只有一次,请不要声明它。

    【讨论】:

      【解决方案2】:

      你可以这样做。你可以像这样缩短你的代码。

      $optionName='';//added some default values
      $sendPush = false;;//added some default values
      switch ($os) {
      
          case "iOS":
              $optionName='iOS_pastPushSavedID';
          break;
      
          case "Android":
              $optionName='android_pastPushSavedID';
          break;
      
          case "Fire OS":
              $optionName='fireos_pastPushSavedID';
          break;
      
          case "Safari":
              $optionName='safari_pastPushSavedID';
          break;
      
          case "Chrome":
              $optionName='chrome_pastPushSavedID';
          break;
      
          case "Firefox":
              $optionName='firefox_pastPushSavedID';
          break;
      
          default:
              $sendPush = false;
      }
      //this is operation which is common when $optionName is not empty.
      if(!empty($optionName))
      {
          $optionData = get_option($optionName,  $default = false);
          if($post->ID != $optionData) {
              update_option( $optionData, $post->ID, no);
              $sendPush = true;
          } else {
              $sendPush = false;
          }
      }
      

      【讨论】:

      • 谢谢!将检查并恢复。感谢您的快速回复。您会建议将 var 存储在 MySQL Wordpress 中的更快的替代方案吗?或者我的解决方案你认为好吗?发送
      • @Jason 欢迎...我认为没关系,这是您在这里尝试做的事情的最短代码。我的代码我给了你一种方法,你可以防止自己一次又一次地重写相同的代码.. :)
      • 谢谢!明天试试这个,然后告诉你!
      【解决方案3】:

      我还是这样写的

      function getOptionSpecifier() {
      
          switch ($this->os) {
              case "iOS":
                  return 'iOS_pastPushSavedID';
              case "Android":
                  return 'android_pastPushSavedID';
              case "Android":
                  return 'android_pastPushSavedID';
              case "Fire OS":
                  return 'fireos_pastPushSavedID';
              case "Safari":
                  return 'safari_pastPushSavedID';
              case "Chrome":
                  return 'chrome_pastPushSavedID';
              case "Firefox":
                  return 'firefox_pastPushSavedID';
              default:
                  return '';
      
          }
      }
      
      function send_notification($id) {
          $optionSpecifier = getOptionSpecifier();
      
          if ($optionSpecifier === NULL) {
              return false;
          }
      
          $pastPushSavedID = get_option( $optionSpecifier,  $default = false);
      
          if($id != $pastPushSavedID) {
              update_option( $optionSpecifier, $id, no);
              return true;
              //$title = ($os . '_New Push = ' . ' storedID: ' . $iOS_pastPushSavedID . ' / postID: ' . $post->ID);
          } else {
              //$title = ($os . '_Duplicate Push = ' . ' storedID: ' . $iOS_pastPushSavedID . ' / postID: ' . $post->ID);
              return false;
          }
      }
      
      $sendPush  = send_notification($post->ID);
      

      多个功能ala“关注点分离”等等......

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-03-03
        • 2011-01-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多