Error with mysql statement - php

I'm trying to blind my MySql query I noob in this, I want prevent to SQL Injection on my query. This is my statement but have one error
$sql = $conn ->prepare("SELECT * FROM Personas WHERE concat(nombre1,' ',apellido1) LIKE '% :name %'");
$sql-> bind_param('name', $q);
Warning: mysqli_stmt::bind_param(): Number of variables doesn't match
number of parameters in prepared statement in
this work fine but that is a bad way
$sql="SELECT * FROM Personas WHERE concat(nombre1,' ',apellido1) LIKE '%".$q."%';
Please help me with this and what other way Can I use to protect my query in my PHP Code
Thank you for all, that was my solution
$sql = $conn ->prepare('SELECT * FROM Personas WHERE concat(nombre1," ",apellido1) LIKE ? ');
$key = "%".$q."%";
$sql-> bind_param('s', $key);

Use bind_param this way:
$sql= $conn->prepare("SELECT * FROM Personas WHERE concat(nombre1,' ',apellido1) LIKE :name");
$q= "%$q%";
$sql->bindParam(':name', $q);
$sql->execute();

The mysql documentation uses question marks (?) to indicate where a subsequent bind_param value should be placed. Try replacing ":name" with the a "?" in the query and your bind_param should follow the syntax bind_param("s", $q) where "s" is a string identifying the types of values being bound: s for string, d for decimal, i for integer, etc.

Related

Using PHP variable in SQL query

I'm having some trouble using a variable declared in PHP with an SQL query. I have used the resources at How to include a PHP variable inside a MySQL insert statement but have had no luck with them. I realize this is prone to SQL injection and if someone wants to show me how to protect against that, I will gladly implement that. (I think by using mysql_real_escape_string but that may be deprecated?)
<?php
$q = 'Hospital_Name';
$query = "SELECT * FROM database.table WHERE field_name = 'hospital_name' AND value = '$q'";
$query_result = mysqli_query($conn, $query);
while ($row = mysqli_fetch_assoc($query_result)) {
echo $row['value'];
}
?>
I have tried switching '$q' with $q and that doesn't work. If I substitute the hospital name directly into the query, the SQL query and PHP output code works so I know that's not the problem unless for some reason it uses different logic with a variable when connecting to the database and executing the query.
Thank you in advance.
Edit: I'll go ahead and post more of my actual code instead of just the problem areas since unfortunately none of the answers provided have worked. I am trying to print out a "Case ID" that is the primary key tied to a patient. I am using a REDCap clinical database and their table structure is a little different than normal relational databases. My code is as follows:
<?php
$q = 'Hospital_Name';
$query = "SELECT * FROM database.table WHERE field_name = 'case_id' AND record in (SELECT distinct record FROM database.table WHERE field_name = 'hospital_name' AND value = '$q')";
$query_result = mysqli_query($conn, $query);
while ($row = mysqli_fetch_assoc($query_result)) {
echo $row['value'];
}
?>
I have tried substituting $q with '$q' and '".$q."' and none of those print out the case_id that I need. I also tried using the mysqli_stmt_* functions but they printed nothing but blank as well. Our server uses PHP version 5.3.3 if that is helpful.
Thanks again.
Do it like so
<?php
$q = 'mercy_west';
$query = "SELECT col1,col2,col3,col4 FROM database.table WHERE field_name = 'hospital_name' AND value = ?";
if($stmt = $db->query($query)){
$stmt->bind_param("s",$q); // s is for string, i for integer, number of these must match your ? marks in query. Then variable you're binding is the $q, Must match number of ? as well
$stmt->execute();
$stmt->bind_result($col1,$col2,$col3,$col4); // Can initialize these above with $col1 = "", but these bind what you're selecting. If you select 5 times, must have 5 variables, and they go in in order. select id,name, bind_result($id,name)
$stmt->store_result();
while($stmt->fetch()){ // fetch the results
echo $col1;
}
$stmt->close();
}
?>
Yes mysql_real_escape_string() is deprecated.
One solution, as hinted by answers like this one in that post you included a link to, is to use prepared statements. MySQLi and PDO both support binding parameters with prepared statements.
To continue using the mysqli_* functions, use:
mysqli_prepare() to get a prepared statement
mysqli_stmt_bind_param() to bind the parameter (e.g. for the WHERE condition value='$q')
mysqli_stmt_execute() to execute the statement
mysqli_stmt_bind_result() to send the output to a variable.
<?php
$q = 'Hospital_Name';
$query = "SELECT value FROM database.table WHERE field_name = 'hospital_name' AND value = ?";
$statement = mysqli_prepare($conn, $query);
//Bind parameter for $q; substituted for first ? in $query
//first parameter: 's' -> string
mysqli_stmt_bind_param($statement, 's', $q);
//execute the statement
mysqli_stmt_execute($statement);
//bind an output variable
mysqli_stmt_bind_result($stmt, $value);
while ( mysqli_stmt_fetch($stmt)) {
echo $value; //print the value from each returned row
}
If you consider using PDO, look at bindparam(). You will need to determine the parameters for the PDO constructor but then can use it to get prepared statements with the prepare() method.

OR operator on single column PDO

I'm shifting my database connections from mysqli to PDO.
While updating,I'm stuck on one query:
In mysql its:
$quec='designation=10 OR designation=11 OR designation=12';
$query="select firstname,mobile,email from mt where location=".$value." and cp!=".$cpa" and (".$quec.") and dept=".$usersubdept." and mstatus=1";
Its working fine in mysqli.
In PDO i wrote:
$query="select firstname,mobile,email from mt where location=:value AND cp!=:cpa AND (:quec) AND dept=:usersubdept AND mstatus=:mstatus";
Binding the values with variables using bind syntax, I'm not getting any result row.
How to rectify the problem?
I don't think you can use :quec as a parameter, since it is actually 3 things and not a value that can be bound. Otherwise, you may have something wrong with how you're binding, perhaps, but we haven't seen your code for that. Try this:
$query="SELECT firstname, mobile, email FROM mt WHERE location = :value AND
cp != :cpa AND (" . $quec . ") AND dept = :dept AND mstatus = 1";
$stmt = $db->prepare($query);
$stmt->bindValue(':value',$value);
$stmt->bindValue(':cpa',$cpa);
$stmt->bindValue(':dept',$usersubdept);
$stmt->execute();
You need to prepare a string like this: ':id0, :id1, :id2, you can do this like this:
$designationlist = ':id'.implode(',:id', array_keys($designationIds));
then your SQL will be:
$query="select firstname,mobile,email from mt where location=:value AND cp!=:cpa AND designation IN(".$designationlist.") AND dept=:usersubdept AND mstatus=:mstatus";
and:
$parms = array_combine(explode(",", $designationlist), $designationIds);
$stmt = $PDO->prepare($query);
$res = $stmt->execute($parms);

Correct way to use LIKE '%{$var}%' with prepared statements?

This does not work
$sql = 'SELECT * FROM `users` WHERE username LIKE \'%{?}%\' ';
Warning: mysqli_stmt::bind_param(): Number of variables doesn't match number of parameters in prepared statement in /home/rgero/public_html/php/searchadmins.php on line 1
This one doesn't work either
$sql = 'SELECT * FROM `users` WHERE username LIKE %{?}% ';
Fatal error: Wrong SQL: SELECT * FROM users WHERE username LIKE %{?}% Error: 0 in /home/rgero/public_html/php/searchadmins.php on line 1
How would I go about this? I'm trying to make a search for players function that updates the results as you're typing in the form, something like how google already shows answers while you're typing. I need for the username Admin , if you type dm, to show it already among other usernames that contain "dm". It should also be case insensitive
Try this
$likeVar = "%" . $yourParam . "%";
$stmt = $mysqli->prepare("SELECT * FROM REGISTRY where name LIKE ?");
$stmt->bind_param("s", $likeVar);
$stmt->execute();
you need to prepare the query using simply ? then you bind the param using bind_param.

mysqli prepared statement without bind_param

I have this code for selecting fname from the latest record on the user table.
$mysqli = new mysqli(HOST, USER, PASSWORD, DATABASE);
$sdt=$mysqli->('SELECT fname FROM user ORDER BY id DESC LIMIT 1');
$sdt->bind_result($code);
$sdt->fetch();
echo $code ;
I used prepared statement with bind_param earlier, but for now in the above code for first time I want to use prepared statement without binding parameters and I do not know how to select from table without using bind_param(). How to do that?
If, like in your case, there is nothing to bind, then just use query()
$res = $mysqli->query('SELECT fname FROM user ORDER BY id DESC LIMIT 1');
$fname = $res->fetch_row()[0] ?? false;
But if even a single variable is going to be used in the query, then you must substitute it with a placeholder and therefore prepare your query.
However, in 2022 and beyond, (starting PHP 8.1) you can indeed skip bind_param even for a prepared query, sending variables directly to execute(), in the form of array:
$query = "SELECT * FROM `customers` WHERE `Customer_ID`=?";
$stmt = $db->prepare($query);
$stmt->execute([$_POST['ID']]);
$result = $stmt->get_result();
$row = $result->fetch_assoc();
The answer ticked is open to SQL injection. What is the point of using a prepared statement and not correctly preparing the data. You should never just put a string in the query line. The point of a prepared statement is that it is prepared. Here is one example
$query = "SELECT `Customer_ID`,`CompanyName` FROM `customers` WHERE `Customer_ID`=?";
$stmt = $db->prepare($query);
$stmt->bind_param('i',$_POST['ID']);
$stmt->execute();
$stmt->bind_result($id,$CompanyName);
In Raffi's code you should do this
$bla = $_POST['something'];
$mysqli = new mysqli(HOST, USER, PASSWORD, DATABASE);
$stmt = $mysqli->prepare("SELECT `fname` FROM `user` WHERE `bla` = ? ORDER BY `id` DESC LIMIT 1");
$stmt->bind_param('s',$_POST['something']);
$stmt->execute();
$stmt->bind_result($code);
$stmt->fetch();
echo $code;
Please be aware I don't know if your post data is a string or an integer. If it was an integer you would put
$stmt->bind_param('i',$_POST['something']);
instead. I know you were saying without bind param, but trust me that is really really bad if you are taking in input from a page, and not preparing it correctly first.

how to use mysqli_fetch_array with prepared statements

so everyone told me to use prepared statements, but i have no idea what to do now.
$stmt = mysqli_prepare($con, "SELECT * FROM search WHERE `name2` LIKE '?' AND `approved`='approved'");
mysqli_stmt_bind_param($stmt, 's', $name);
/* execute prepared statement */
mysqli_stmt_execute($stmt);
That is my code, how do i make an array from it like
while ($row=mysqli_fetch_array($result))
from non-prepared
Glad to see you are deciding to use PDO!
//using MySQL
//refer here for reference http://www.php.net/manual/en/ref.pdo-mysql.php
$pdo = new PDO('mysql:host=xxx;port=xxx;dbname=xxx', $username, $password)
//write query
$sql = "SELECT * FROM search WHERE `name2` LIKE '?' AND `approved`='approved'";
//tell query what to replace ? marks with
$fill_array = array($name); // one item in array for the one ? in $sql above
//send query to DB for preparation
$prepare = $pdo->prepare($sql);
//send variables to DB, DB will bind them to the proper place and execute query
$prepare->execute($fill_array);
//get your array. I personally recommend PDO::FETCH_ASSOC but you are using ARRAY
$result = $prepare->fetchAll(PDO::FETCH_ARRAY);
echo '<pre>'.print_r($result, true).'</pre>';
Voila!
Please not that you will have to write code to escape $name and check for things like % signs and underscores because if someone literally types in % then the LIKE statement will return all records where approved='approved'

Categories