Handle empty variable in a prepared statement - php

Sometimes my script receives a $_POST["is_searchfield"] request from a form. Then I want to use this variable as a part of a "Where" clause of a MySQL query. Otherwise this part of the "Where" clause shouldn't afflict the rest of the query.
For the query I use a prepared statement.
If the $_POST["is_searchfield"] has a value the query works as expected, but if no variable is sent the whole query doesn't give me any results.
How can I achieve that an empty variable doesn't destroy the whole query and only this certain part of the "where" clause will be ignored. Also the prepared statement should continue to work.
I tried to check if the variable is set with !empty but it doesn't change this behavoiur.
$conn = new mysqli("localhost", "xxxx", "xxxx", "xxxx");
$conn->set_charset("utf8");
// Variables to bind
$classid = "4";
if(!empty($_POST["is_searchfield"]))
{
$searchfield = $_POST["is_searchfield"];
}
else {
$searchfield= "";
}
$fileid = "10";
$sqlitemsparse = "SELECT * FROM itemSparse INNER JOIN item ON item.id = itemSparse.id";
$sqlitemsparse .= " WHERE item.ClassID = ?";
$sqlitemsparse .= " AND itemSparse.Display_lang = ?";
$sqlitemsparse .= " AND itemSparse.fileid = ?";
$sqlitemsparse2 = " LIMIT 0, 10";
$stmt = $conn->prepare($sqlitemsparse . $sqlitemsparse2);
$stmt->bind_param('sss', $classid, $searchfield, $fileid);
$stmt->execute();
$resultitemsparse = $stmt->get_result();
$rowsitemsparse = $resultitemsparse->fetch_all(MYSQLI_ASSOC);

The idea is to change the query to match the data provided
$conn = new mysqli("localhost", "xxxx", "xxxx", "xxxx");
$conn->set_charset("utf8");
// Variables to bind
$classid = "4";
$fileid = "10";
if(!empty($_POST["is_searchfield"]))
{
$sqlitemsparse = "SELECT *
FROM itemSparse
INNER JOIN item ON item.id = itemSparse.id
WHERE item.ClassID = ?
AND itemSparse.Display_lang = ?
AND itemSparse.fileid = ?
LIMIT 0, 10";
$stmt = $conn->prepare($sqlitemsparse);
$stmt->bind_param('sss', $classid, $_POST["is_searchfield"], $fileid);
} else {
$sqlitemsparse = "SELECT *
FROM itemSparse
INNER JOIN item ON item.id = itemSparse.id
WHERE item.ClassID = ?
AND itemSparse.fileid = ?
LIMIT 0, 10";
$stmt = $conn->prepare($sqlitemsparse);
$stmt->bind_param('ss', $classid, $fileid);
}
$stmt->execute();
$resultitemsparse = $stmt->get_result();
$rowsitemsparse = $resultitemsparse->fetch_all(MYSQLI_ASSOC);

Related

Prepared statements in DataTables

I want to use prepared statements inside DataTables for the code stated below. It has two queries (query and query1).
Query has two "where conditions" which variables are $classid and $searchfield.
Query1 is a "Limit" statement and also has two variables $start and $end.
The results of both queries should be stored in the $data array. At the moment I don't get any results. How do I bind the paramteres correctly in this case and store the results in the array so DataTables gets a working json?
My try:
$connect = mysqli_connect("localhost", "xxxx", "xxx", "xxx");
$columns = array('itemOverview.id', 'itemOverview.Display_lang');
// Variables to bind
$classid = 4;
$searchfield = $_POST["is_searchfield"];
$start = $_POST['start'];
$end = $_POST['length'];
$query = "SELECT * FROM itemOverview INNER JOIN item ON item.id = itemOverview.id";
$query.= " WHERE item.ClassID = ? AND ";
if(!empty($searchfield)) {
$query .= "itemOverview.Display_lang = ? AND ";
}
$query1 = '';
if($_POST["length"] != -1) {
$query1 = 'LIMIT ?, ?';
}
$stmt = mysqli_stmt_init($connect);
if (!mysqli_stmt_prepare($stmt, $query. $query1)) {
echo "SQL Failed";
} else {
// bind paramaters to the placeholder
mysqli_stmt_bind_param($stmt, "ssss", $classid, $searchfield, $start, $end);
// run parameters inside database
mysqli_stmt_execute($stmt);
$result = mysqli_stmt_get_result($stmt);
$data = array();
while($row = mysqli_fetch_array($result))
{
$sub_array = array();
$sub_array[] = $row["id"];
$sub_array[] = $row["Display_lang"];
$data[] = $sub_array;
}
}
$output = array(
"draw" => intval($_POST["draw"]),
"data" => $data
);
echo json_encode($output);

How to write MySQL query in prepare method when search?

how can I secure my search query with the prepare method?
DB Connection
// connect to database
$con = new mysqli("localhost", "root", "", "chat");
// Check connection
if ($con->connect_error) {
die("Connection failed: " . $con->connect_error);
}
MySQL Query
if (isset($_POST['query'])) {
$search_string = trim($_POST['query']);
$query = mysqli_real_escape_string($con, $search_string);
//MySQL order by best match
$sql = "SELECT reply FROM question_answer WHERE question
LIKE '%$query%'
ORDER BY CASE
WHEN question = '$query' THEN 0
WHEN question LIKE '$query%' THEN 1
WHEN question LIKE '%$query%' THEN 2
WHEN question LIKE '%$query' THEN 3
ELSE 4
END, question ASC";
$res = mysqli_query($con, $sql);
if (mysqli_num_rows($res) > 0) {
$row = mysqli_fetch_assoc($res);
$html = $row['reply'];
} else {
$html = "Sorry not be able to understand you";
$added_on = date('Y-m-d h:i:s');
mysqli_query($con, "INSERT INTO unknown_question(question,added_on,type) VALUES('$query','$added_on','user')");
}
echo $html;
die();
}
An example of using prepared queries with mysqli in your code could be like this:
if (isset($_POST['query'])) {
$sql = "SELECT reply FROM question_answer WHERE question LIKE ?
ORDER BY CASE
WHEN question = ? THEN 0
WHEN question LIKE ? THEN 1
WHEN question LIKE ? THEN 3
ELSE 2
END, question ASC";
$query = trim($_POST['query']);
$params = [
'%' . $query . '%',
$query,
$query . '%',
'%' . $query
];
$stmt = $con->prepare($sql);
$stmt->bind_param(str_repeat('s', count($params)), ...$params);
$stmt->execute();
$result = $stmt->get_result();
$row = $result->fetch_assoc();
if (!empty($row)) {
$html = $row['reply'];
} else {
$html = "Sorry not be able to understand you";
$added_on = date('Y-m-d h:i:s');
$sql = "INSERT INTO unknown_question(question,added_on,type) VALUES(?,?,'user')";
$stmt = $con->prepare($sql);
$stmt->bind_param('ss', $query, $added_on);
$stmt->execute();
}
echo $html;
}

Database Error HY000

My code working fine , but i got this error :
SQLSTATE[HY000]: General error
I searching on google and someone say that it's may SQLi
What is this ? And how can i fix that ?
thanks and sorry for my poor english
try{
$db_con = new PDO("mysql:host={$db_host};dbname={$db_name}",$db_user,$db_pass);
$db_con->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
// Anti Brute Forced
$stmt = $db_con->prepare("
SELECT * FROM users
");
$stmt->execute();
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)){
$users_username = $row["users_username"];
$users_password = $row["users_password"];
$users_wrong_password = $row["users_wrong_password"];
if ($users_wrong_password <= 3 && isset($_GET["username"],$_GET["password"]) && $_GET["username"] == $users_username && $_GET["password"] != $users_password){
$u = $users_wrong_password + 1;
$g = 0;
$g = $_GET['username'];
$stmt = $db_con->prepare("
UPDATE users
SET users_wrong_password = $u
WHERE users.users_username = '$g'
");
$stmt->execute();
}
if ($_GET["username"] == $users_username && $users_wrong_password >= 4){
echo "Your Account Was Banned For 1 Hours";
die;
}
}
$g = $_GET['username'];
$stmt = $db_con->prepare("SELECT * FROM users where users_username = '$g'");
$stmt->execute();
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)){
$ss = $row["users_wrong_password"];
}
if($ss <= 3){
$g = 0;
$g = $_GET['username'];
$stmt = $db_con->prepare("
UPDATE users
SET users_wrong_password = 0
WHERE users_username = '{$_GET['username']}'
");
$stmt->execute();
}
// Anti Brute Forced
[Solved]
Edit:
$g = $_GET['username'];
$p = $_GET['password'];
$stmt = $db_con->prepare("
SELECT * FROM users where users_username = '$g' and users_password = '$p'
");
I found this problem in a similar another way
"errorInfo":["HY000"]
How does "HY000" error happen?
It happens when you are updating, deleting or inserting data with PDO, and you try to fetch it's result.
The solution, just do not use fetch or fetchAll methods after executing an updating, deleting or inserting. Surely, it does not make sense to fetch it's result!
Example:
$stmt = $db_con->prepare("
UPDATE users SET name = 'Renato' WHERE ID = 0
");
$stmt->execute();
$stmt->fetch(PDO::FETCH_ASSOC); // The mistake is here, just remove this line
$stmt->fetchAll(PDO::FETCH_ASSOC); // It will cause troubles too, remove it
Solving the problem in a loop
The solution is changing the statement variable name inside loop, or fetch all before starting loop:
Solution: Changing variable name
$stmt = $db_con->prepare("
SELECT * FROM users
");
$stmt->execute();
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)){
// ...
// This is another statment
$another_stmt = $db_con->prepare("
UPDATE users
SET users_wrong_password = $u
WHERE users.users_username = '$g'
");
$another_stmt->execute();
}
Solution: Fetch all data from query before loop
$stmt = $db_con->prepare("
SELECT * FROM users
");
$stmt->execute();
// Everything is fetched here
$results = $stmt->fetchAll(PDO::FETCH_ASSOC)
foreach($results as $row){ // Another way to loop through results
$stmt = $db_con->prepare("
UPDATE users
SET users_wrong_password = $u
WHERE users.users_username = '$g'
");
$stmt->execute(); // Be happy with no troubles
}
I think there are multiple preparations of the same query.
Solution Get the query preparation out of the while.
code:
//... your code
$stmt1 = $db_con->prepare("
UPDATE users
SET users_wrong_password = $u
WHERE users.users_username = '$g'
");
$stmt->execute();
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)){
$users_username = $row["users_username"];
$users_password = $row["users_password"];
$users_wrong_password = $row["users_wrong_password"];
if ($users_wrong_password <= 3 && isset($_GET["username"],$_GET["password"]) && $_GET["username"] == $users_username && $_GET["password"] != $users_password){
$u = $users_wrong_password + 1;
$g = 0;
$g = $_GET['username'];
$stmt1->execute();
//...
}

PHP issue... output stops after loop

ive got this code and somehow it stops after the first entry even though there should be way more.
If i take both foreach loops out, its doing fine. So the issue should be there but im either blind or stupid :(
// Main Agenda
$stmt = $mysqli->prepare("
SELECT
agenda.id,
agenda.title,
agenda.timeStart,
agenda.timeEnd,
agenda.description,
agenda.speakers,
agenda.moderators,
agenda_locations.name,
agenda_days.dayDate,
agenda_categories.name
FROM agenda
LEFT JOIN agenda_locations ON agenda.location = agenda_locations.id
LEFT JOIN agenda_days ON agenda.dayDate = agenda_days.id
LEFT JOIN agenda_categories ON agenda.category = agenda_categories.id
WHERE agenda.active = '1'
AND agenda.deleted = '0'
ORDER BY agenda.timeStart ASC
");
$stmt->execute();
$stmt->store_result();
$stmt->bind_result($agendaId, $agendaTitle, $agendaStart, $agendaEnd, $agendaDescription, $agendaSpeakers, $agendaModerators, $agendaLocation, $agendaDate, $agendaCategory);
while ($stmt->fetch()) {
$speakersText = "";
$moderatorsText = "";
if( strlen($agendaSpeakers)>0 ){
foreach(explode('###', $agendaSpeakers) as $speakerId) {
$stmt = $mysqli->prepare("
SELECT
name
FROM speakers
WHERE id = ?
");
$stmt->bind_param('i', $speakerId);
$stmt->execute();
$stmt->store_result();
$stmt->bind_result($speakerName);
$stmt->fetch();
$speakersText .= $speakerName.", ";
}
$speakersText = substr_replace($speakersText, "", -2);
}
if( strlen($agendaModerators)>0 ){
foreach(explode('###', $agendaModerators) as $moderatorId) {
$stmt = $mysqli->prepare("
SELECT
name
FROM speakers
WHERE id = ?
");
$stmt->bind_param('i', $moderatorId);
$stmt->execute();
$stmt->store_result();
$stmt->bind_result($moderatorName);
$stmt->fetch();
$moderatorsText .= $moderatorName.", ";
}
$moderatorsText = substr_replace($speakersText, "", -2);
}
$var0 = $agendaId;
$var1 = stripslashes($agendaTitle);
$var2 = strtotime($agendaStart);
$var3 = strtotime($agendaEnd);
$var4 = stripslashes($agendaDescription);
$var5 = $speakersText;
$var6 = $moderatorsText;
$var7 = $agendaLocation;
$var8 = strtotime($agendaDate);
$var9 = $agendaCategory;
$agendaMain[] = array ($var0,$var1,$var2,$var3,$var4,$var5,$var6,$var7,$var8,$var9);
}
You have to rename you $stmt variable in your foreach loops.

My database didn't update

<?php
$db = new mysqli('localhost', 'root', 'root', 'chatting');
$query = "SELECT * FROM user WHERE state = 1 AND getp = 0";
$result = $db->query($query);
$num_result = $result->num_rows;
$mems = "";
for ($i = 0; $i < $num_result; $i++) {
$row = $result->fetch_assoc();
$mems = $row["userName"] . " " . $mems;
$query = "update `user` set `getp` = 1 where 'userName` = ".' $row["userName"] ';
$result = $db->prepare($query);
}
echo $mems;
?>
What I want I want to get all records that state = 1 and getp = 0, then inside loop and for every record I want to change the value of getp to 1, It's correct but don't know where is the wrong.
You forgot to execute() the update statement..
Also, note that this is not the correct way to prepare statements.. you will have to do something like this:
$query = $db->prepare("update `user` set `getp` = 1 where `userName` = :userName");
$query->bind_param(':userName',$row["userName"]);
$result = $query->execute();
Why doing it in a for loop? You could just do UPDATEuserSET getp = 1 WHERE state = 1 AND getp = 0;
While looping with for $i++? Why not while($row = $result->fetch_assoc()) { ... }?
However change the query to
$query = 'update `user` set `getp` = 1 where userName = "'. $row["userName"] .'"';
and don't forget to execute() it.
Please set your update command to:
$query = "update `user` set `getp` = 1 where `userName` = '". $row["userName"]. "'";

Categories