【问题标题】:Conditional prepared statements PHP mysqli, reduce条件准备语句 PHP mysqli, reduce
【发布时间】:2017-05-31 12:18:44
【问题描述】:

它有效,但我觉得它不是解决我的问题的最佳方法。 我想要我的代码做的是检查 location = 1 并发送所有位置的消息。

function getCurrentMessage($location){
    $conn = Connection::getConnection();

    if($location == 1) {
        $query = "SELECT first_name, last_name, description, title, message ,font_size , effective_date 
                FROM tbl_messages
                JOIN tbl_authors ON tbl_authors.id_author = tbl_messages.id_author 
                JOIN tbl_locations ON tbl_messages.id_location = tbl_locations.id_location
                AND effective_date <= CURDATE()
                ORDER BY effective_date desc
                LIMIT 2;";

        $result = array();

        if ($stmt = $conn->prepare($query)) {
            $stmt->bind_result($first_name, $last_name, $location, $title, $message, $size, $date);
            $stmt->execute();

            while ($stmt->fetch()) {
                $message = new Message($first_name, $last_name, $location, $title, $message, $size, $date);
                array_push($result, $message);
            }
        }
    }
    else{
        $query = "SELECT first_name, last_name, description, title, message ,font_size , effective_date 
                FROM tbl_messages
                JOIN tbl_authors ON tbl_authors.id_author = tbl_messages.id_author 
                JOIN tbl_locations ON tbl_messages.id_location = tbl_locations.id_location
                WHERE tbl_messages.id_location = ?
                AND effective_date <= CURDATE()
                ORDER BY effective_date desc
                LIMIT 2;";

        $result = array();

        if ($stmt = $conn->prepare($query)) {
            $stmt->bind_result($first_name, $last_name, $location, $title, $message, $size, $date);
            $stmt->bind_param('i', $location);
            $stmt->execute();

            while ($stmt->fetch()) {
                $m = new Message($first_name, $last_name, $location, $title, $message, $size, $date);
                array_push($result, $m);
            }
        }
    }

    return $result;
}

也许我可以在 SQL 语句中加入一些逻辑。 如果您有任何见解,请提供帮助。

【问题讨论】:

  • 你可以去掉函数开头的位置检查。这将有助于只允许使用一个查询。然后有一个 where 子句,它将从函数中的参数中获取位置,例如 WHERE location=?
  • code review 是最好的提问地点

标签: php sql database mysqli prepared-statement


【解决方案1】:

只需重构所有不依赖条件的重复部分。

function getCurrentMessage($location){
    $conn = Connection::getConnection();

    if($location == 1) {
        $query = "SELECT first_name, last_name, description, title, message ,font_size , effective_date 
                FROM tbl_messages
                JOIN tbl_authors ON tbl_authors.id_author = tbl_messages.id_author 
                JOIN tbl_locations ON tbl_messages.id_location = tbl_locations.id_location
                AND effective_date <= CURDATE()
                ORDER BY effective_date desc
                LIMIT 2;";

        if (!$stmt = $conn->prepare($query)) {
            return false;
        }

    }
    else{
        $query = "SELECT first_name, last_name, description, title, message ,font_size , effective_date 
                FROM tbl_messages
                JOIN tbl_authors ON tbl_authors.id_author = tbl_messages.id_author 
                JOIN tbl_locations ON tbl_messages.id_location = tbl_locations.id_location
                WHERE tbl_messages.id_location = ?
                AND effective_date <= CURDATE()
                ORDER BY effective_date desc
                LIMIT 2;";

        if (!$stmt = $conn->prepare($query)) {
            return false;
        }
        $stmt->bind_param('i', $location);
    }

    $result = array();

    $stmt->bind_result($first_name, $last_name, $location, $title, $message, $size, $date);
    $stmt->execute();

    while ($stmt->fetch()) {
         $m = new Message($first_name, $last_name, $location, $title, $message, $size, $date);
         array_push($result, $m);
    }

    return $result;
}

您可以走得更远,但这只是一个示例。请注意,如果语句准备失败,该函数如何返回 false。由于您在一个函数内部,这将停止执行该函数并返回 false,因为如果准备失败,则没有进一步的意义。如果你想要一些可以被捕获的东西,你也可以使用异常。

【讨论】:

    【解决方案2】:

    我现在意识到这个问题应该在代码审查Code review 中发布 , 但是在了解了有关 MYSQL 的更多信息后,我想出了一种清理代码的方法,所以这是我使用控制流函数的答案。
    如果您有任何其他想法来进一步清理代码,请告诉我。

    $conn = getConnection();
    $query = "SELECT first_name, last_name, description, title, message ,font_size , DATE_FORMAT(effective_date,'%h:%i %p %m-%d-%Y')
              FROM tbl_messages
              JOIN tbl_authors ON tbl_authors.id_author = tbl_messages.id_author
              JOIN tbl_locations ON tbl_messages.id_location = tbl_locations.id_location
              WHERE tbl_messages.id_location = IF(? = 1,tbl_messages.id_location,?)
              AND effective_date <= NOW()
              ORDER BY effective_date DESC
              LIMIT 1
              ";
    
    if (!$stmt = $conn->prepare($query)) {
        return false;
    }
    
    $stmt->bind_param('ii', $location,$location);
    
    $result = array();
    
    $stmt->bind_result($first_name, $last_name, $location, $title, $message, $size, $date);
    $stmt->execute();
    
    while ($stmt->fetch()) {
        $m = new Message($first_name, $last_name, $location, $title, $message, $size, $date);
        array_push($result, $m);
    }
    
    return $result;
    

    【讨论】:

      猜你喜欢
      • 2015-03-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-20
      • 1970-01-01
      • 1970-01-01
      • 2014-03-13
      • 2018-06-06
      • 2013-03-24
      相关资源
      最近更新 更多