Массив из формы ввода - Выберите оператор MySQLi Параметризация - PullRequest
1 голос
/ 10 ноября 2019

Превращение фраз, введенных в форму ввода, в массив для передачи в оператор выбора MySQL where, используя MySQLi. У меня есть этот php-код, но я не могу понять, как параметризовать запрос, чтобы предотвратить атаки с использованием SQL-инъекций. Я просмотрел несколько вопросов на этом сайте, но я изо всех сил стараюсь связать его с моим кодом.

if(!empty($_POST['Message']))
{
      $searchStr = get_post($con,'Message');
      $aKeyword = explode(" ", $searchStr);

      $query ="SELECT m.ID, m.MessageText FROM MessageMain m LEFT OUTER JOIN Likes l on m.ID = l.PostID WHERE MessageText LIKE '%" . $aKeyword[0] . "%'";

     for($i = 1; $i < count($aKeyword); $i++) {
        if(!empty($aKeyword[$i])) {
            $query .= " OR MessageText like '%" . $aKeyword[$i] . "%'";
        }
      }

      $query .= " GROUP BY m.ID, m.MessageText ORDER BY count(m.id) desc";

       $result = $con->query($query);
       $rowcount=mysqli_num_rows($result);

1 Ответ

2 голосов
/ 10 ноября 2019

Если вы хотите построить предложение WHERE динамически на основе количества подходящих ключевых слов, вы можете сделать это следующим образом:

if (!empty($_POST['Message'])) {
    $searchStr = get_post($con, 'Message');
    $aKeyword = explode(" ", $searchStr);

    $whereClauseArr = [];
    foreach ($aKeyword as $keyword) {
        if ($keyword) {
            $whereClauseArr[] = "MessageText LIKE ?";
            $whereValues[] = '%'.$keyword.'%';
        }
    }

    $stmt = $con->prepare(
        'SELECT m.ID, m.MessageText 
        FROM MessageMain m 
        LEFT OUTER JOIN Likes l on m.ID = l.PostID 
        WHERE '.implode(' OR ', $whereClauseArr).'
        GROUP BY m.ID, m.MessageText ORDER BY count(m.id) desc'
    );

    $stmt->bind_param(str_repeat('s', count($whereValues)), ...$whereValues);
    $stmt->execute();
    $result = $stmt->get_result();
}

Хотя в вашем случае проверка одного и того же столбца для несколькихзначения, вероятно, лучше сделать с помощью регулярного выражения. Это сделает ваш запрос более простым и, возможно, также более быстрым в зависимости от количества ключевых слов, которые у вас есть.

if (!empty($_POST['Message'])) {
    $searchStr = get_post($con, 'Message');
    $aKeyword = explode(" ", $searchStr);

    $aKeyword = array_filter($aKeyword); // Remove empty values

    $stmt = $con->prepare(
        'SELECT m.ID, m.MessageText 
        FROM MessageMain m 
        LEFT OUTER JOIN Likes l on m.ID = l.PostID 
        WHERE MessageText REGEXP ?
        GROUP BY m.ID, m.MessageText ORDER BY count(m.id) desc'
    );

    $regexString = implode('|', $aKeyword);
    $stmt->bind_param('s', $regexString);
    $stmt->execute();
    $result = $stmt->get_result();
}
...