How to bind unknown number of parameters with Mysqli? For example, following my code:
<?php
include 'config.php';
$query = "SELECT * FROM table WHERE";
if(isset($_POST['r1']))
$query = $query." id = '$_POST['r1']'";
if(isset($_POST['r2']))
$query = $query." AND par2 = '$_POST['r2']'";
$e = mysqli_prepare($conf, $query);
?>
How to do bind of parameters?
Prepared statements probably aren't the best way to do this. You can assemble a query just as you are doing, as long as you make sure that you escape any user input. For example:
<?php
// assuming $db is a mysqli object
$query = "SELECT * FROM table WHERE";
if(isset($_POST['r1']))
$query = $query."id = '".$db->real_escape_string($_POST['r1'])."'";
if(isset($_POST['r2']))
$query = $query." AND par2 = '".$db->real_escape_string($_POST['r2'])."'";
$result = $db->query($query);
?>
Don't forget to add any required error checking.
Related
I am in need of some help, please? I can successfully do a MySQL query using:
IP_Address/fund_list.php?Id_Number=555666
With this below:
$ID = $_GET['Id_Number'];
$sql = "SELECT * FROM fund_list WHERE Number = ".$ID;
Now I want to use 2 different things in my web call. Like:
IP_Address/fund_list.php?Id_Number=555666&Name=Billy
But I don't know how to write the 'get' line below.
$ID = $_GET['Id_Number'] & $Name = $_GET['Name']; <-- Does not work
I would think the SQL select statement would be:
$sql = "SELECT * FROM fund_list WHERE TheNumber = .$ID AND TheName = .$Name";
All the things I look up online, the syntax is overly confusing, I can't dissect it and make something work. Thank you.
To start with you should really be preparing your statements, passing data directly from a query string into a SQL query is really dangerous. You should also avoid using * in your SELECTs if you insist on not preparing them.
Your issue in this case is you need '' around TheName =
$sql = "SELECT * FROM fund_list WHERE TheNumber = {$ID} AND TheName = '{$Name}'";
Regardless, what you should be doing is this:
$sql = "SELECT Param1, Param2 FROM fund_list WHERE TheNumber = ? AND TheName = ?";
$stmt = $conn->prepare($sql);
$stmt->bind_param("is", $ID, $Name);
$stmt->execute();
$stmt->bind_result($param1, $param2);
while($stmt->fetch()) {
//Your code
}
That code prevents SQL injection attacks, and a number of other potential issues you can create not using PDO or mysqli prepared statements.
Edit per request:
$ID = $_GET['Id_Number'];
$Name = $_GET['Name'];
$sql = "SELECT * FROM fund_list WHERE TheNumber = {$ID} AND TheName = '{$Name}'";
$result = $conn->query($sql);
while($row = $result->fetch_assoc()) {
//your code
}
You need '' when comparing string parameters in SQL.
Have you tried doing this? This always works to me
$ID = $_GET['Id_Number'];
$Name = $_GET['Name'];
All I need is to produce a row. I've looked at all the samples and I cannot for the life of me get the right information. Hence help is required please.
Connection to DB in the usual way. Here is my code for the query.
$sql = "SELECT * FROM table WHERE `u_password` = $pword AND `user` = $uname LIMIT 1";
$result = mysqli_query($mdb, $sql);
$row = mysqli_fetch_assoc($result);
//Then I try to retrieve say the user name....
echo $row['seeking'];
I've got a count in there and it produces a result of 1.
The error I get is
'Warning: mysqli_fetch_array() expects parameter 1 to be mysqli_result'
Help would be appreciated.
The error
Warning: mysqli_fetch_array() expects parameter 1 to be mysqli_result
Almost always means that the query failed for some reason, thus $result = mysqli_query returns FALSE rather than a mysql_result object so anything that then tries to use $result as an object will not work for obvious reasons.
The issue with your query is that text column data must be wrapped in quotes like this
$sql = "SELECT *
FROM table
WHERE `u_password` = '$pword' AND `user` = '$uname' LIMIT 1";
Your script is at risk of SQL Injection Attack
Have a look at what happened to Little Bobby Tables Even
if you are escaping inputs, its not safe!
You should use parameterized queries to avoid this.
$sql = "SELECT *
FROM table
WHERE `u_password` = ? AND `user` = ? LIMIT 1";
$stmt = mysqli_prepare($mdb, $sql);
// its also a good idea to check the staus of a prepare
// and show the error if it failed, at least while testing
if ( $stmt === FALSE ) {
echo mysqli_error($mdb);
exit;
}
$stmt->bind_param('ss', $pword, $uname );
$stmt->execute();
$result = $stmt->get_result();
$row = $result->fetch_assoc();
echo $row['seeking'];
You need to use prepared statements (in actuality you could get it to work by quoting your strings but prepared statements are much better). Like so:
$sql = "SELECT * FROM table WHERE `u_password` = ? AND `user` = ? LIMIT 1";
$stmt = mysqli_prepare($mdb, $sql);
$stmt->bind_param("ss",$pword,$uname);
if ($stmt->execute()) {
$result = $stmt->get_result();
$row = mysqli_fetch_assoc($result);
//Then I try to retrieve say the user name....
echo $row['seeking'];
} else { /* something went wrong */ }
This question already has answers here:
How to include a PHP variable inside a MySQL statement
(5 answers)
Closed 2 years ago.
I currently have a Get varible
$name = $_GET['user'];
and I am trying to add it to my sql statement like so:
$sql = "SELECT * FROM uc_users WHERE user_name = ". $name;
and run
$result = $pdo -> query($sql);
I get an invalid column name. But that doesn't make sense because if I manually put the request like so
$sql = "SELECT * FROM uc_users WHERE user_name = 'jeff'";
I get the column data, just not when I enter it as a get variable. What am I doing wrong. I am relatively new to pdo.
Update:
Now I have the following:
$name = $_GET['user'];
and
$sql = "SELECT * FROM uc_users WHERE user_name = :name";
//run the query and save the data to the $bio variable
$result = $pdo -> query($sql);
$result->bindParam( ":name", $name, PDO::PARAM_STR );
$result->execute();
but I am getting
> SQLSTATE[42000]: Syntax error or access violation: 1064 You have an
> error in your SQL syntax; check the manual that corresponds to your
> MySQL server version for the right syntax to use near ':name' at line
> 1
For your query with the variable to work like the one without the variable, you need to put quotes around the variable, so change your query to this:
$sql = "SELECT * FROM uc_users WHERE user_name = '$name'";
However, this is vulnerable to SQL injection, so what you really want is to use a placeholder, like this:
$sql = "SELECT * FROM uc_users WHERE user_name = :name";
And then prepare it as you have:
$result = $pdo->prepare( $sql );
Next, bind the parameter:
$result->bindParam( ":name", $name, PDO::PARAM_STR );
And lastly, execute it:
$result->execute();
I find this best for my taste while preventing SQL injection:
Edit: As pointed out by #YourCommonSense you should use a safe connection as per these guidelines
// $conn = mysqli_connect(DB_HOST, DB_USER, DB_PASS, DB_NAME);
$sql = 'SELECT * FROM uc_users WHERE user_name = ?';
$stmt = $conn->prepare($sql);
$stmt->bind_param('s', $name);
$stmt->execute();
$result = $stmt->get_result();
$stmt->close();
// perhaps you'll need these as well
$count = $result->num_rows;
$row = $result->fetch_assoc();
/* you can also use it for multiple rows results like this
while ($row = $result->fetch_assoc()) {
// code here...
} */
BTW, if you had more parameters e.g.
$sql = 'SELECT * FROM table WHERE id_user = ? AND date = ? AND location = ?'
where first ? is integer and second ? and third ? are string/date/... you would bind them with
$stmt->bind_param('iss', $id_user, $date, $location);
/*
* i - corresponding variable has type integer
* d - corresponding variable has type double
* s - corresponding variable has type string
* b - corresponding variable is a blob and will be sent in packets
*/
Source: php.net
EDIT:
Beware! You cannot concatenate $variables inside bind_param
Instead you concatenate before:
$full_name = $family_name . ' ' . $given_name;
$stmt->bind_param('s', $full_name);
Try this .You didn't put sigle quote against variable.
$sql = "SELECT * FROM uc_users WHERE user_name = '". $name."'";
Note: Try to use Binding method.This is not valid way of fetching data.
$sql = "SELECT * FROM 'uc_users' WHERE user_name = '". $name."' ";
So I have two functions:
function display_name1($s){
global $db;
$query1 = "SELECT Taken From Alcohol where P_Key = $s";
$r = $db->prepare($query1);
$r->execute();
$result = $r->fetchColumn();
return $result;
}
function write_Recipe($s){
global $db;
$query1 = "SELECT Taken From Alcohol where Name = $s";
$r = $db->prepare($query1);
$r->execute();
$result = $r->fetchColumn();
return $result;
}
The only difference is that I'm matching the input "$s" with "P_Key" in the first example, and "Name" in the latter. When I put in a number for the first function, I get the appropriate return. When I put in a string that matches at least one "Name", I get nothing back. It seems to not be matches the strings for some reason. Any ideas?
There is a syntax error in the SQL query. You are missing the table name in the second query:
"SELECT Taken From where Name = '$s'"
Should be something like:
"SELECT Taken FROM `tablename` WHERE `Name` = '$s'"
Further note, that if you already using prepared statements, you should bind variables to the query instead of building the query using string concatination. Also the usage of global isn't perfect for an OOP design. Here comes an example how it can be done better:
// extend a class from PDO
class CustomPDO extends PDO {
public function display_name($s){
// use placeholder :p_key in query
$query1 = "SELECT Taken FROM `Alcohol` WHERE `P_Key` = :p_key";
$r = $this->prepare($query1);
// bind value to prepared statement
$r->execute(array(
':p_key' => $s
));
$result = $r->fetchColumn();
return $result;
}
public function write_recipe($s){
// use placeholder :name in query
$query1 = "SELECT Taken FROM `tablename` WHERE `Name` = :name";
// use $this as we are extended from PDO
$r = $this->prepare($query1);
// bind value to prepared statement
$r->execute(array(
':name' => $s
));
$result = $r->fetchColumn();
return $result;
}
}
Then use the class like a regular PDO object:
$db = new CustomPDO($connection_string, $user, $password);
But having two additional methods:
$result = $db->display_name('foo');
$result = $db->write_recipe('foo');
When querying on strings, you should surround a variable with quotes, like so:
"SELECT Taken From where Name = '$s'"
Also your second query is missing a table name.
"SELECT Taken FromTableNamewhere Name = '$s'"
Strings need to be quoted (and probably escaped if you haven't already). You seem to be using PDO, why not add a placeholder ? and execute execute(array($s)); instead, making PDO do the work for you?
function display_name1($s){
global $db;
$query1 = "SELECT Taken From Alcohol where P_Key = ?";
$r = $db->prepare($query1);
$r->execute(array($s));
$result = $r->fetchColumn();
return $result;
}
function write_Recipe($s){
global $db;
$query1 = "SELECT Taken From Alcohol where Name = ?";
$r = $db->prepare($query1);
$r->execute(array($s));
$result = $r->fetchColumn();
return $result;
}
Not sure how I can do this. Basically I have variables that are populated with a combobox and then passed on to form the filters for a MQSQL query via the where clause. What I need to do is allow the combo box to be left empty by the user and then have that variable ignored in the where clause. Is this possible?
i.e., from this code. Assume that the combobox that populates $value1 is left empty, is there any way to have this ignored and only the 2nd filter applied.
$query = "SELECT * FROM moth_sightings WHERE user_id = '$username' AND location = '$value1' AND english_name = $value2 ";
$result = mysql_query($query) or die(mysql_error());
$r = mysql_numrows($result);
Thanks for any help.
C
Use
$where = "WHERE user_id = '$username'";
if(!empty($value1)){
$where .= "and location = '$value1'";
}
if(!empty($value2 )){
$where .= "and english_name= '$value2 '";
}
$query = "SELECT * FROM moth_sightings $where";
$result = mysql_query($query) or die(mysql_error());
$r = mysql_numrows($result);
Several other answers mention the risk of SQL injection, and a couple explicitly mention using prepared statements, but none of them explicitly show how you might do that, which might be a big ask for a beginner.
My current preferred method of solving this problem uses a MySQL "IF" statement to check whether the parameter in question is null/empty/0 (depending on type). If it is empty, then it compares the field value against itself ( WHERE field1=field1 always returns true). If the parameter is not empty/null/zero, the field value is compared against the parameter.
So here's an example using MySQLi prepared statements (assuming $mysqli is an already-instantiated mysqli object):
$sql = "SELECT *
FROM moth_sightings
WHERE user_id = ?
AND location = IF(? = '', location, ?)
AND english_name = ?";
$stmt = $mysqli->prepare($sql);
$stmt->bind_param('ssss', $username, $value1, $value1, $value2);
$stmt->execute();
(I'm assuming that $value2 is a string based on the field name, despite the lack of quotes in OP's example SQL.)
There is no way in MySQLi to bind the same parameter to multiple placeholders within the statement, so we have to explicitly bind $value1 twice. The advantage that MySQLi has in this case is the explicit typing of the parameter - if we pass in $value1 as a string, we know that we need to compare it against the empty string ''. If $value1 were an integer value, we could explicitly declare that like so:
$stmt->bind_param('siis', $username, $value1, $value1, $value2);
and compare it against 0 instead.
Here is a PDO example using named parameters, because I think they result in much more readable code with less counting:
$sql = "SELECT *
FROM moth_sightings
WHERE user_id = :user_id
AND location = IF(:location_id = '', location, :location_id)
AND english_name = :name";
$stmt = $pdo->prepare($sql);
$params = [
':user_id' => $username,
':location_id' => $value1,
':name' => $value2
];
$stmt->execute($params);
Note that with PDO named parameters, we can refer to :location_id multiple times in the query while only having to bind it once.
if ( isset($value1) )
$query = "SELECT * FROM moth_sightings WHERE user_id = '$username' AND location = '$value1' AND english_name = $value2 ";
else
$query = "SELECT * FROM moth_sightings WHERE user_id = '$username' AND english_name = $value2 ";
But, you can also make a function to return the query based on the inputs you have.
And also don't forget to escape your $values before generating the query.
1.) don't use the simply mysql php extension, use either the advanced mysqli extension or the much safer PDO / MDB2 wrappers.
2.) don't specify the full statement like that (apart from that you dont even encode and escape the values given...). Instead use something like this:
sprintf("SELECT * FROM moth_sightings WHERE 1=1 AND %s", ...);
Then fill that raw query using an array holding all values you actually get from your form:
$clause=array(
'user_id="'.$username.'"',
'location="'.$value1.'"',
'english_name="'.$value2.'"'
);
You can manipulate this array in any way, for example testing for empty values or whatever. Now just implode the array to complete the raw question from above:
sprintf("SELECT * FROM moth_sightings WHERE 1=1 AND %s",
implode(' AND ', $clause) );
Big advantage: even if the clause array is completely empty the query syntax is valid.
First, please read about SQL Injections.
Second, $r = mysql_numrows($result) should be $r = mysql_num_rows($result);
You can use IF in MySQL, something like this:
SELECT * FROM moth_sightings WHERE user_id = '$username' AND IF('$value1'!='',location = '$value1',1) AND IF('$value2'!='',english_name = '$value2',1); -- BUT PLEASE READ ABOUT SQL Injections. Your code is not safe.
Sure,
$sql = "";
if(!empty($value1))
$sql = "AND location = '{$value1}' ";
if(!empty($value2))
$sql .= "AND english_name = '{$value2}'";
$query = "SELECT * FROM moth_sightings WHERE user_id = '$username' {$sql} ";
$result = mysql_query($query) or die(mysql_error());
$r = mysql_numrows($result);
Be aware of sql injection and deprecation of mysql_*, use mysqli or PDO instead
I thought of two other ways to solve this:
SELECT * FROM moth_sightings
WHERE
user_id = '$username'
AND location = '%$value1%'
AND english_name = $value2 ";
This will return results only for this user_id, where the location field contains $value1. If $value1 is empty, this will still return all rows for this user_id, blank or not.
OR
SELECT * FROM moth_sightings
WHERE
user_id = '$username'
AND (location = '$value1' OR location IS NULL OR location = '')
AND english_name = $value2 ";
This will give you all rows for this user_id that have $value1 for location or have blank values.