【问题标题】:How do I choose the desired icon when fetching results?获取结果时如何选择所需的图标?
【发布时间】:2016-01-12 13:14:19
【问题描述】:

我正在创建一个问答网站,类似于 SO。现在我需要在每个答案旁边打印一个“检查”icon (指定接受的答案)。现在有一些条件:

  • 当前用户已登录?
  • 当前用户是问题的作者?
  • 是否有任何可接受的答案?

还有一些其他情况..!


实际上我实现了这一点。但是我使用了很多嵌套的if-statement 来做到这一点,在我看来真的没有优化。现在我想知道有没有更好的算法来写这段代码?

$results = $stm->fetchAll(PDO::FETCH_ASSOC);       // Fetching all answers

foreach ($results as $result){

    if ($_SESSION['id'] == $author_id){            // User is logged
        if($result['id'] == $AcceptedAnswerId){    // There is accepted answer
            $AcceptAnswerIcon = "<a href='#'>
                                    <i style='color: green;' class='fa fa-check'></i>
                                 </a>";
        } else {                                   // There isn't accepted answer
            $AcceptAnswerIcon = "<a href='#'>
                                    <i style='color: gray' class='fa fa-check'></i>
                                 </a>";
        }
    } 

    elseif ($_SESSION['id'] !== $author_id) {      // User isn't logged
        if($result['id'] == $AcceptedAnswerId){    // There isn accepted answer
            $AcceptAnswerIcon = "<i style='color: green;' class='fa fa-check'></i>";
        } else {                                   // There isn't accepted answer
            $AcceptAnswerIcon = null;
        }
    }

    else {
        $AcceptAnswerIcon = null;
    }


// ... I will use $AcceptAnswerIcon in here and mix it with answer structure


} // End of "foreach" block             

【问题讨论】:

  • 尝试编写不言自明的业务逻辑方法:function userCanAcceptAnswer($user, $answer) { return $user['id'] == $answer['author_id'] &amp;&amp; ...; }if (userCanAcceptAnswer(..)) echo '&lt;i ..';。这应该会大大简化这样的模板代码。
  • @deceze 这不是一个有效的关闭原因。这一点之前已经被经常指出。它在这里太宽泛了,可能是代码审查的一个很好的候选者。

标签: php performance if-statement


【解决方案1】:

更好地使用面向对象的 PHP 以获得更好的处理......

class Author{

    //funtion will return true if author
    function is_author(){

    }



    //function will return true if it is accepted.
    function is_accepted(){

    }


}


$author = new Author();

现在使用这个条件来减少更多的 if 和 else...

if ( $author->is_author() ) {
    //do something

    $AcceptAnswerIcon = "<a href='#'>
                                <i style='". if($author->is_accepted()) { ."color: green;".} else { ."color:gray;' class='fa fa-check'></i>
                             </a>";


} else {


    if($result['id'] == $AcceptedAnswerId){    // There isn accepted answer
        $AcceptAnswerIcon = "<i style='color: green;' class='fa fa-check'></i>";
    } else {                                   // There isn't accepted answer
        $AcceptAnswerIcon = null;
    }


}

【讨论】:

  • Emm .. 我不知道,只为一个图标定义一个类和一些方法? :-),好像有点贵。但是感谢您的方法... +1
  • 好吧..手动减少/简化您的 if else 非常困难,虽然它有很多条件...或者您可以通过为每个人设置符号来使用 Switch...
【解决方案2】:

更新:

首先,由于您只是在寻找 1 个正确答案,因此在找到(或未找到)之后,它将跳出循环,保持简单:

foreach($results as $result)
{
  $foundCorrectAnswer = ($result['id'] == $AcceptedAnswerId);
  if($foundCorrectAnswer)
  {
    break;
  }
}

毕竟,有 3 个可能的输出(我的第一个错误是我只看到了 2 个),所以这里是:

if($isLogged)
{
  $color = $foundCorrectAnswer ? 'green' : 'gray';
  $AcceptAnswerIcon = "<a href='#'><i style='color: {$color};' class='fa fa-check'></i></a>";
}
else if($foundCorrectAnswer)
{
  $AcceptAnswerIcon = "<i style='color: green;' class='fa fa-check'></i>";
}

那么完整的代码:

$isLogged = $_SESSION['id'] == $author_id;
$results = $stm->fetchAll(PDO::FETCH_ASSOC);
foreach($results as $result)
{
  $foundCorrectAnswer = ($result['id'] == $AcceptedAnswerId);
  if($foundCorrectAnswer)
  {
    break;
  }
}

if($isLogged)
{
  $color = $foundCorrectAnswer ? 'green' : 'gray';
  $AcceptAnswerIcon = "<a href='#'><i style='color: {$color};' class='fa fa-check'></i></a>";
}
else if($foundCorrectAnswer)
{
  $AcceptAnswerIcon = "<i style='color: green;' class='fa fa-check'></i>";
}

【讨论】:

  • 该字符串中$acceptAnswerIcon 周围的{} 是什么?
  • 你的代码也不完整......!如果“有一个可接受的答案”和“当前用户不是问题的作者”会发生什么?在这种情况下,我需要从&lt;a&gt; 中创建一个图标&lt;i&gt;
  • 该字符串中 $acceptAnswerIcon 周围的 { 和 } 是什么?这只是转义了变量。没什么特别的
  • 在这种情况下,我需要从&lt;a&gt; 中创建一个图标&lt;i&gt;。关于这个是我的错,我没有注意到这个微小的差异,我会更新答案
【解决方案3】:

备注

  • 在您的逻辑中 if ... elseif ... else 最后一个 else 没有意义,因为用户只能登录或不登录。
  • 为了使您的代码更紧凑,您可以将在不同场合使用的字符串(和其他)元素放入变量或常量(定义)中。
    这样的效果是您的代码更小,也可能是(?) 更快。
    在这里,我从 字符串创建了一个模板,其中带有 {var} 标记,这些标记在运行时被变量替换。
  • 另一方面,我不建议将您的代码强制紧凑,因为这样做可能会使代码难以理解。
  • 您可以在下面找到更紧凑的代码变体。
    我使用了三元条件 $result = (condition) ? truevalue : falsevalue,这通常会使代码更紧凑(但见上文)。

代码片段

$results = $stm->fetchAll(PDO::FETCH_ASSOC);       // Fetching all answers
define ('template','<a href="#">'.PHP_EOL.'   <i style="color: {color};" class="fa fa-check"></i>'.PHP_EOL.'</a>');

foreach ($results as $result){
    $has_acceptedanswers = ($result['id'] == $AcceptedAnswerId);
    if ($_SESSION['id'] == $author_id){           // User is logged
        $template = template;
        $color = ($has_acceptedanswers) ? 'green' : 'gray';
    } else {                                      // User is not logged
        $template = ($has_acceptedanswers) ? template : false;
        $color = 'green';
    }
    $AcceptAnswerIcon = ($template === false) ? null : str_replace('{color}',$color,$template);

    //...
}

【讨论】:

  • @Alex(并不是说这是一个不好的答案@hherger),但同样的html问题也发生在这里。
  • 请告诉我你为什么使用PHP_EOL
  • 因为 EOL(行尾)因您使用的系统(linux、window、osx)而异
猜你喜欢
  • 1970-01-01
  • 2021-07-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-06-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多