Потому что:
- Вы используете предоставленные пользователем данные, и вы должны исходить из того, что ваш запрос уязвим для атаки злонамеренного внедрения
- Количество данных, которые должны быть встроены в запрос, является переменным / неопределенным
- Вы пишете условные проверки только для одного столбца таблицы
Вы должны использовать подготовленный оператор и объединить всю логику предложения WHERE
в один оператор IN
.
Построение этого динамического подготовленного оператора является более запутанным (с точки зрения синтаксиса), чем использование pdo, но это не означает, что вам нужно отказаться от mysqli просто из-за этой задачи.
Я запекал каждую возможную контрольную точку ошибки, чтобы вы могли легко отлаживать ее в случае возникновения непредвиденных ситуаций. Я должен подчеркнуть, что вы никогда не должны показывать подробности об ошибках широкой публике в качестве наилучшей практики безопасности.
Я протестировал это решение с моими собственными данными в базе данных на моем локальном хосте, чтобы оно работало.
<code>$_POST['userMedia'] ='Facebook,Twitter,Twitch,';
$media = explode(',', rtrim($_POST['userMedia'], ',')); // build array from csv string
$presetMedia = 'House';
$media[] = $presetMedia; // push known media string into array
$media = array_unique($media); // make sure there are no duplicates
var_export($media); // see what this generates
if (!$count = count($media)) {
echo "There are no values in media, so a prepared statement is overkill and IN won't work when empty";
// handle this case however you wish (if it is even possible within your project)
} elseif (!$conn = new mysqli("localhost", "root", "", "myDB")) { // use your own credentials
echo "Database Connection Error: " , $conn->connect_error;
} else {
$csph = implode(',', array_fill(0, $count, '?')); // comma-separated placeholders e.g: ?,?,?,?
echo "<div>Placeholders: $csph</div>";
$query = "SELECT * FROM `mediaservices` WHERE `socialmedianame` IN ($csph)";
echo "<div>Query: $query</div>";
if (!$stmt = $conn->prepare($query)) {
echo "<div>Syntax Error @ prepare: {$conn->error}</div>"; // NEVER show error details to the public
}else{
array_unshift($media, str_repeat('s', $count)); // prepend the type values string e.g: ssss
var_export($media); // see what this generates
foreach ($media as &$v) {
$ref[] = &$v; // call_user_func_array requires array that is passed-by-reference
}
call_user_func_array([$stmt, 'bind_param'], $ref); // call bind_param() upon stmt object, using each media value
if (!$stmt->execute() || !$result = $stmt->get_result()) { // execute statement and get the resultset while checking for falsey returned feedback
echo "<div>Error @ execute/get_result: {$stmt->error}</div>"; // NEVER show error details to the public
} elseif (!$result->num_rows) { // check for empty rows, if you wish
echo "<div>No Rows Found</div>";
} else {
echo "<pre>";
while ($row = $result->fetch_assoc()) {
var_export($row); // do what you like with the associative-keyed elements
echo "<br>";
}
echo "
";
}
$ Stmt-> близко ();
}
}
Вывод должен быть таким:
array ( 0 => 'Facebook', 1 => 'Twitter', 2 => 'Twitch', 3 => 'House' )
Placeholders: ?,?,?,?
Query: SELECT * FROM `mediaservices` WHERE `socialmedianame` IN (?,?,?,?);
array ( 0 => 'ssss', 1 => 'Facebook', 2 => 'Twitter', 3 => 'Twitch', 4 => 'House', )
array (
// whatever column names and values you have in the row
)
array (
// whatever column names and values you have in the row
)
array (
// whatever column names and values you have in the row
)
...