When I get data without "prepare" and "execute", code is working fine. Example:
$this->db->query("select {$val} from {$table_name} where username={$username}")->fetch();
But this code always return False:
$this->db->prepare("select :val from :table_name where username = :username")
->execute(array(':username'=>$username,':val'=>$val,':table_name'=>$this->table_name));
HELP!:(
Thank you for your answers. Now my code is looking here:
$q=$this->db->prepare("select pass from nm_users where username = :username");
return $q->execute(array('username'=>$username));
Return value is True, but I can't get data from DB.
Don't try to use PDO as a fluent interface. You can't do this:
$db->prepare()->execute();
The reason is that fluent interfaces work only if the function is guaranteed to return an object that has in this case an execute method.
But prepare() returns false on error. The value false isn't an object, and doesn't have an execute() method.
You need to check for false after every prepare() and after every execute():
$stmt = $this->db->prepare("select :val from :table_name where username = :username");
if ($stmt === false) {
$err = $this->db->errorInfo();
error_log($err[2]);
}
$result = $stmt->execute(array(':username'=>$username,':val'=>$val,':table_name'=>$this->table_name));
if ($result === false) {
$err = $stmt->errorInfo();
error_log($err[2]);
}
If you do this, you'll find that an error was reported on your prepare():
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 ''user' where username = 'bill'' at line 1
The reason is that query parameters are only for constant values. You can't use them for table names, column names, SQL keywords, expressions, lists of values, etc.
I'm inferring that :val is also meant to be a dynamic column name, and that's not allowed either. But in that case, it won't result in an error, it'll just substitute a literal string with the value of $val for every row returned.
In other words, substituting the table name with a parameter is wrong because you can't do a query like SELECT * FROM 'user' (literal string, not table name), and that's how the parameter will act. It's simply invalid SQL.
But the dynamic column name will do a query like SELECT 'val' FROM ... and that's legal, but won't select from the column named val, it'll select the literal string constant 'val'.
Parameters cannot be set for table-names etc. and have to be set in the array without the colon:
$dbSelect=$db->prepare("select aField from aTable where username = :username")
$dbSelect->execute(array('username' => $username));
Replace aField and aTable with standard str_replace or sth similar.
The table name must be contained inside the query when you 'prepare' it, it cannot be added dynamically as the rest of the arguments. Therefore you have to use a combination of two strategies to finalize your query:
$stmnt=sprintf('select %1$s from %2$s where username=:username',
$val, $this->table_name);
if (FALSE===($query=$this->db->prepare($stmnt)))
exit('Buggy statement: '.$stmnt);
$query->execute(array(':username'=>$username));
Unfortunately this also means you have to take care that $this->table_name is escaped correctly!
Related
SOLVED: Reason Can I parameterize the table name in a prepared statement?
I have a very simple Query to collect data from a two column table in MySQL. Normally it worked but for some reason I know receive the error: Undefined offset: 1
$query_select = ("SELECT ?, ? FROM _HOOFDRUBRIEK");
$stmt = $mysqli->prepare($query_select);
$stmt->bind_param("ss", $column1, $column2);
$stmt->execute();
$stmt->store_result();
//$count = $stmt->num_rows;
//echo $count;
/die();
$stmt->bind_result( $key_hoofdrubriek ,
$descr_hoofdrubriek );
$stmt->fetch();
$hoofdrubriek[] = array('key' =>$key_hoofdrubriek ,
'descr' =>$descr_hoofdrubriek );
//Here I request the variable, what occurs the error
$var = $hoofdrubriek[1]['descr'];
echo 'Show here what's in the var: '.$var ;
Does anyone know why I get this error, because from my point of view, a multidimensional array can be called by $array_name[row][column];
You are mistinpreting how that works. Result bind parameters are just bound in order to the selected field. You still need to select normal fields as usual.
Moreover, you cannot specify field names as input parameters. In your situation, you select two constant values, namely the strings you pass as input parameters. This is why you get the field names in the result instead of the values of those fields. The parameters are just string values, so the query that is executed would look like this:
SELECT 'key_hoofdrubriek', 'descr_hoofdrubriek' FROM FROM RGS_HOOFDRUBRIEK
So, skip the question marks and the input bind parameters altogether and build the query like so:
$query_select = ("SELECT key_hoofdrubriek, descr_hoofdrubriek FROM RGS_HOOFDRUBRIEK");
Or, if you must, by using PHP variables in the statement:
$query_select = ("SELECT $column1, $column2 FROM RGS_HOOFDRUBRIEK");
For reading, you can of course still use bind_result.
You can't use placeholders for column names, they're always treated as expressions. So your prepared query is equivalent to writing:
SELECT 'key_hoofdrubriek', 'descr_hoofdrubriek' FROM RGS_HOOFDRUBIEK
This just returns those literal strings for each row in the table, not the values in the columns with those names.
If you need to determine the column names dynamically, you have to use variable substitution or concatenation, you can't use placeholders:
$query_select = "SELECT $column1, $column2 FROM RGS_HOOFDRUBRIEK";
I am writig a simple select statement, and since the connection object is mysqli, i cant use AND , && , OR like operators as it giving error
function getdata($value1,$value2)
{
global $conn;
$query = "SELECT id, name from users WHERE id!=$value1 && email==$value2 ";
$result = $conn->query($query);
}
This dosen't work :-(
Error: trying to get property of non object .. bla bla ..
Which means there something wrong with my sql statement, as when i try without logical operators it works, but of no use ofcourse .
Using prepare statement & bind parameters
I referred to This thread SELECT in MYSQLI and tried with prepare statements.. but i'm doing something wrong i guess
$query=$conn->prepare("SELECT id, name from users WHERE id!=? && email==?");
$query->bindParam("ss", $value1,$value2); // line 20 error points here
$query->execute();
Error:
Call to a member function bindParam() on a non-object in /mydir/file.php line 20
P.S. var_dump($query); returns bool(false)
SELECT id, name FROM users WHERE id <> $value1 AND email = '$value2'"
<> and != is the same. AND and && is the same. You probably see AND and <> because is the standard in SQL. The issue was the equal operator is = instead of ==.
In the second part of your question, ss is wrong. d is for type double, s is for strings.
$query=$conn->prepare("SELECT id, name from users WHERE id != ? && email = ?");
$query->bind_param('ds', $value1, $value2);
$query->execute();
You can check types on php bind_param function help.
You have multiple problems in your query.
Use ' = ' instead of ' == ' for assignments.
In the first part You have assigned the query to variable $query, and running the query with variable $sql (wrong)
A modified code will look like this:
$query = "SELECT id, name from users WHERE id!='$value1' AND email='$value2'";
$result = $conn->query($query);
replace && With AND,
replace == with "="
its returning false, but its because you have a mysql syntax error, you could also try turn on error reporting to see the exception
I am trying to retrieve one result from my database table 'members' using a prepared call.
$favid = 1;
$type = "favdeal";
$action = 1;
$user_id = 1;
$stmt = $mysqli->prepare("SELECT ? FROM members WHERE id=?");
$stmt->bind_param('ss', $type, $user_id);
$stmt->execute();
$stmt->bind_result($favs);
while ($stmt->fetch()) {
print($favs);
}
$stmt->close();
This is the only way i managed to get any kind of result.
The table has a column called 'favdeal' which has a value of '2' in it.
The result printed returns the name of the column not the value.
So my question is how do i get the value '2' instead of the name of the column?
You can't bind columns (or tables) from doing a SELECT as you have in SELECT ?.
Select an actual column.
Or, if you want to do it dynamically, you need to use a variable.
Example: SELECT $type <= that is allowed.
However, column names can be binded when using a WHERE clause.
Example: SELECT column FROM table WHERE column=?
which you are presently using => WHERE id=?
Consult the manual on bind_param()
http://www.php.net/manual/en/mysqli-stmt.bind-param.php
Footnotes:
If you happen to use an MySQL reserved word (it could happen), you will need to wrap your column's variable with backticks.
For example: (if using $type="from";) "from" being a reserved word.
SELECT `$type` FROM members WHERE id=?
For a list of MySQL reserved words, visit the following page:
http://dev.mysql.com/doc/refman/5.5/en/reserved-words.html
I'm struggling with this simple line of SQL...
Running it keeps giving me the error: Error: Unknown column 'comics' in 'where clause'.
This would normally be an easy fix... just go check to make sure "comics" exists as an entry in column "table_name". But I've already checked that...
I don't see anything wrong with my SQL:
$sql = "SELECT ip FROM votes WHERE ip = '".$_SERVER['REMOTE_ADDR']."' AND table_name = $table AND imgid = $imgid";
EDIT:
Btw, I've already tried it with quotes:
$sql = "SELECT ip FROM votes WHERE ip = '".$_SERVER['REMOTE_ADDR']."' AND table_name = '$table' AND imgid = $imgid";
But that throws the error:
Fatal error: Call to undefined method mysqli_result::num_rows() in C:\wamp\www\HTwS\scripts\likecounter.php on line 40
Can anyone help?
Thanks!
The value of table_name is a string, and must therefore be single-quoted in the query. Failing to quote it as a string value, MySQL assumes that the supplied unquoted $table is a column identifier.
$sql = "SELECT ip FROM votes WHERE ip = '".$_SERVER['REMOTE_ADDR']."' AND table_name = '$table' AND imgid = $imgid";
//------------------------------------------------------------------------------------^^^^^^^^^
If $imgid is also a non-numeric value you'll need to quote that one as well.
We assume it has already been properly filtered against SQL injection, if it is the result of user input. I'll note, since the update includes MySQLi-specific code, that you really ought to be doing this as a prepared statement rather than a constructed string call to mysqli::query().
// Recommended to do this with a prepared statement.
$stmt = $mysqli->prepare("SELECT ip FROM votes WHERE ip = ? AND table_name = ? AND imgid = ?");
if ($stmt) {
$stmt->bind_param('ssi', $_SERVER['REMOTE_ADDR'], $table, $imgid);
$stmt->execute();
// Bind results, fetch, etc...
}
Edit after question update and comment:
Call to undefined method mysqli_result::num_rows()
The error message implies that you have attempted to access the MySQLi result property num_rows as a method call with () rather than a property. You should be using:
$result->num_rows
... instead of
$result->num_rows()
Using PHP v. 5.2.14 and PDO-MySQL extension.
I am new to prepared statements. Need to create a search form (so user input) and a working query of the "Select all X where X likeā¦" variety.
Code and Results:
$sql = 'SELECT COUNT(*) as num_books from t_books where title LIKE :search_term';
// Later access as num_books
$prep = $dbh->prepare($sql);
$num = $prep->execute(array(':search_term' => '%'.$search_term. '%'));
$total=$num->fetchColumn();
Var dump of $prep:
object(PDOStatement)#2 (1) { ["queryString"]=> string(58) "SELECT COUNT(*) from t_books where title LIKE :search_term" }
Fatal error: Call to a member function fetchColumn() on a non-object
If $prep is an object, then $num should be an object. But it is boolean (true). What happened here?
But more importantly, how can I do a count?
I read Row count with PDO -. Suggestions there do not work for me because I need a Prepared Statement. Will have user input.
Thanks for your help.
PDOStatement::execute() only returns a boolean indicating success or failure, so your variable $num is not what you want to fetch from. By assigning the result to $num, you are not assigning the object $prep, but rather only the return value of the method call to execute() (TRUE).
Instead, fetchColumn() from $prep, your PDOStatement object.
$num = $prep->execute(array(':search_term' => '%'.$search_term. '%'));
if ($num) {
$total = $prep->fetchColumn();
}
Beyond that, your SQL should execute correctly and the one column it returns should contain the count you need.
In this case (especially since you are calling fetchColumn() with no argument) it doesn't matter, but for future readers, it is advisable to name the COUNT() aggregate with an alias that can then be used in an associative or object fetch:
$sql = 'SELECT COUNT(*) AS num_books from t_books where title LIKE :search_term';
// Later access as num_books