Как написать безопасный запрос SELECT, который имеет переменное количество пользовательских значений с mysqli? - PullRequest
0 голосов
/ 22 июня 2019

Мне нужна помощь для выполнения foreach в моем коде.

Я публикую несколько значений в имени пользователя: as username[0] = user1 , user2

, но мой foreach дает мне результат, как только последняя записьили ничего.

$companyname = $_POST['companyname'];
$username_grab = $_POST['username'];
$username = implode(",", $username_grab);

foreach ($username_grab as $value){
    $value = $username_grab;

    $sql = "select * from linked_user where username = '$value' and company_name = '$companyname'";
    $res = mysqli_query($conn,$value);
    while($row = mysqli_fetch_array($res)){
        $returnValue['username'] = $row['username'];
        $returnValue['user_scid'] = $row['user_scid'];
    }
}
echo json_encode($returnValue);
?>

Ответы [ 2 ]

3 голосов
/ 22 июня 2019

Задача, которую вы должны выполнить, - это подготовленный оператор с переменным числом заполнителей. В PDO это проще, но я покажу вам подход на основе объектно-ориентированного стиля mysqli. Неважно, что, всегда печатайте массив в кодировке json, чтобы ваш принимающий скрипт знал, какой тип данных ожидать.

У меня был фрагмент, включающий полный набор диагностики и проверку ошибок. Я не тестировал этот скрипт, но он очень похож на мой пост .

if (empty($_POST['companyname']) || empty($_POST['username'])) {  // perform any validations here before doing any other processing
    exit(json_encode([]));
}

$config = ['localhost', 'root', '', 'dbname'];  // your connection credentials or use an include file
$values = array_merge([$_POST['companyname']], explode(',', $_POST['username']));  // create 1-dim array of dynamic length
$count = sizeof($values);
$placeholders = implode(',', array_fill(0, $count - 1, '?'));  // -1 because companyname placeholder is manually written into query
$param_types = str_repeat('s', $count);
if (!$conn = new mysqli(...$config)) {
    exit(json_encode("MySQL Connection Error: <b>Check config values</b>"));  // $conn->connect_error
}
if (!$stmt = $conn->prepare("SELECT user_scid, user_scid FROM linked_user WHERE company_name = ? AND username IN ({$placeholders})")) {
    exit(json_encode("MySQL Query Syntax Error: <b>Failed to prepare query</b>"));  // $conn->error
}
if (!$stmt->bind_param($param_types, ...$values)) {
    exit(json_encode("MySQL Query Syntax Error: <b>Failed to bind placeholders and data</b>"));  // $stmt->error;
}
if (!$stmt->execute()) {
    exit(json_encode("MySQL Query Syntax Error: <b>Execution of prepared statement failed.</b>"));  // $stmt->error;
}
if (!$result = $stmt->get_result()) {
    exit(json_encode("MySQL Query Syntax Error: <b>Get Result failed.</b>")); // $stmt->error;
}
exit(json_encode($result->fetch_all(MYSQLI_ASSOC)));

Если вы не хотите использовать все эти диагностические условия и комментарии, вот эквивалент «голых костей», который должен работать одинаково:

if (empty($_POST['companyname']) || empty($_POST['username'])) {
    exit(json_encode([]));
}

$values = explode(',', $_POST['username']);
$values[] = $_POST['companyname'];
$count = count($values);
$placeholders = implode(',', array_fill(0, $count - 1, '?'));
$param_types = str_repeat('s', $count);

$conn = new mysqli('localhost', 'root', '', 'dbname');
$stmt = $conn->prepare("SELECT user_scid, user_scid FROM linked_user WHERE username IN ({$placeholders}) AND company_name = ?");
$stmt->bind_param($param_types, ...$values);
$stmt->execute();
$result = $stmt->get_result();
exit(json_encode($result->fetch_all(MYSQLI_ASSOC)));
0 голосов
/ 22 июня 2019

Удалите '$ value = $ username_grab;' внутри foreach

т.е.

foreach ($username_grab as $value){
    // $value = $username_grab;   This does not belong

Если это не поможет, можете ли вы показать код, с которого он отправляет сообщения, и сделать

print_r($username_grab)

сразу после установки

Редактировать

<?php
$companyname = $_POST['companyname'];
$username_grab = $_POST['username'];                            // This (based on your example) is a weird single index array - Array ( [0] => user1,user2 )
// $username = implode(",", $username_grab);                    // implode turns an array into a string using a delimiter
$usernames = explode(",", $username_grab[0]);                   // explode turns a string into an array by delimiter. The [0] index is for the post coming through as such
// $usernames should now look something like this. This is the array you will be working with
// Array ( [0] => user1, [1] => user2 )

foreach($usernames AS $value)
{
    $sql = "select * from linked_user where username = '" . mysqli_escape_string($value) . "' and company_name = '" . mysqli_escape_string($companyname) . "'"; // SQL injection is a threat. Seperate issue to look into   
    $res = mysqli_query($conn,$value);
    $cnt = 0;                                                   // Looking for multiple results. Counter for array
    while($row = mysqli_fetch_array($res))
    {
        $returnValue[$cnt]['username'] = $row['username'];      // Create a two dimensional array (multiple users. Each has their own index then
        $returnValue[$cnt]['user_scid'] = $row['user_scid'];    // Can replace the $cnt field with $row['userid'] (or whatever) if you have a primary key on the table i.e. $returnValue[$row['userid']]['username'] = $row['username'];
    }
    $cnt++;                                                     // Increase the counter for the next user
}

// $returnValue should now look something like this
// Array ( 
// [0] => Array (
//          ['username'] => 'user1', 
//          ['user_scid'] => 'whateverthedbsaysforuser1'),
// [1] => Array (
//          ['username'] => 'user2', 
//          ['user_scid'] => 'whateverthedbsaysforuser2'),
// )
echo json_encode($returnValue);
?>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...