Set variable from SELECT PHP - php

I simply want to define the variable "$read" as whatever its value is in the database. How can I do this?
$read = "SELECT `read` FROM `users` WHERE `id` = '$id'";

$read = mysql_result(mysql_query("SELECT read FROM users WHERE id = $id"),0);

Beware of the answers given using mysql_query, as they're vulnerable to SQL injection.
If $id is supplied by a user, you should never directly put it into the SQL query, but rather use a prepared statement.
One way of doing this, is by using PDO, in a manner similar to this:
$dbh = new PDO($connStr, $user, $pass);
$sql = "SELECT `read` FROM `users` WHERE `id` = :id";
$statement = $dbh->prepare($sql);
$statement->execute( array('id' => $id) );
$read = $statement->fetchColumn();
For more information on how to use PDO, see the following:
Are there good tutorials on how to use PDO?

One way to accomplish this is as follows:
// Run the query
$db_result = mysql_query("SELECT read FROM users WHERE id = $id");
// Get the first row (in this case you'll only get one row)
$row = mysql_fetch_array($db_result, MYSQL_NUM);
// Get the first column (you should only have one column anyway) and put it into your variable
$read = $row[0];
As pointed out below, I should add that if you don't trust $id to be properly escaped, you could be vulnerable to SQL injection. To overcome this, you should either make sure you properly escape and validate $id or use some kind of binding or prepared statement to do it for you, like in this question or in the example below.

I know it's almost impossible to teach someone something, especially if they don't want to learn. But in hope it will be useful for someone else
All modern programming languages supports such a thing called "user defined functions".
A very handy feature.
A programmer, who wants to have their code real neat, can make a function out of some repetitive code and make calling this code REAL small, just almost as it was phrased in the OP:
$read = dbgetvar("SELECT `read` FROM `users` WHERE `id` = %d",$id);
another benefit from such an approach - your code could contain all necessary things, like parameter sanitization and error handling. And still calling this code would be shorter than all codes above, made ugly and unmantainable in pursue for shortness.
An example of such a function
function dbgetvar(){
$args = func_get_args();
$query = array_shift($args);
$query = str_replace("%s","'%s'",$query);
foreach ($args as $key => $val) {
$args[$key] = mysql_real_escape_string($val);
}
$query = vsprintf($query, $args);
$res = mysql_query($query);
if (!$res) {
trigger_error("dbget: ".mysql_error()." in ".$query);
return FALSE;
}
$row = mysql_fetch_row($res)
if (!$row) return NULL;
return $row[0];
}

I would do the following:
// leave the single quotes around $id because it most probably is an INT
// LIMIT 1 will make the query a bit faster
$result = mysql_query("SELECT `read` FROM `users` WHERE `id` = $id LIMIT 1");
$row = mysql_fetch_row($result);
$read = $row[0];
Hope it works for you.

Assuming there is only 1 result:
$read = mysql_fetch_array(mysql_query("SELECT read FROM users WHERE id = $id"));
$read = $read[0];

Related

Cannot echo result from mysql

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 */ }

How to solve Illegal string offset ['id'] in php?

I'm sorry if this is a duplicate question but I don't know how to solve my problem. Every time I try to correct my error I fail. My code is:
if (isset($_GET["comment"])) {$id = $_GET["comment"];}
$query = "SELECT * FROM posts WHERE id = {$id['$id']};";
$get_comment = mysqli_query($con, $query);
Can anybody correct the code to not show an error anymore and tell me what did I wrong?
Try this:
$id = isset($_GET['comment']) ? $_GET['comment'] : 0;
$query = "SELECT * FROM `posts` WHERE `id` = " . intval($id);
The use of intval will protect you from SQL injection in this particular case. Ideally, you should learn PDO as it is extremely powerful and makes prepared statements much easier to handle to prevent all injections.
An example using PDO might look like:
$id = isset($_GET['comment']) ? $_GET['comment'] : 0;
$query = $pdo->prepare("SELECT * FROM `posts` WHERE `id` = :id");
$query->execute(array("id"=>$id));
$result = $query->fetch(PDO::FETCH_ASSOC); // for a single row
// $results = $query->fetchAll(PDO::FETCH_ASSOC); // for multiple rows
var_dump($result);
First of all you should prevent injestion.
if (isset($_GET["comment"])){
$id = (int)$_GET["comment"];
}
Notice, $id contanis int.
$query = "SELECT * FROM posts WHERE id = {$id}";
Assuming your $id is an integer and you only want to make the query if it is set, here's how you could do it using prepared statements, which protect you from MYSQL injection attacks:
if (isset($_GET["comment"])) {
$id = $_GET["comment"];
$stmt = mysqli_prepare($con, "SELECT * FROM posts WHERE id = ?");
mysqli_stmt_bind_param($stmt, 'i', $id);
mysqli_stmt_execute($stmt);
mysqli_stmt_bind_result($stmt, $get_comment);
while (mysqli_stmt_fetch($stmt)) {
// use $get_comment
}
mysqli_stmt_close($stmt);
}
Most of these functions return a boolean indicating whether they were successful or not, so you might want to check their return values.
This approach looks a lot more heavy duty and is arguably overkill for a simple case of a statement containing a single integer but it's a good practice to get into.
You might want to look at the object-oriented style of mysqli which you might find a little cleaner-looking, or alternatively consider using PDO.

unable to execute update statement in while loop php mysqli

I have the following query
$products = $this->mysqliengine->query("select * from temp_all_product where download_status = 0") or die($this->mysqliengine->error());
$temp_status_update = $this->mysqliengine->prepare("update temp_all_product set download_status = ? where id = ?") or die($this->mysqliengine->error);
$temp_status_update->bind_result($download_status, $id);
while($product = $products->fetch_assoc()) {
$id = $product['id'];
$download_status = 1;
$temp_status_update->execute();
}
In the above statement I can select the values from temp table but unable to update the status. What is the problem here
You need to use bind_param in your update statement instead of bind_result.
$temp_status_update->bind_param('dd', $download_status, $id);
The 'dd' just tells the system that each input is a number.
http://www.php.net/manual/en/mysqli-stmt.bind-param.php
#eggyal was merely suggesting that you could replace all your code with a single update statement. Your remark about LIMIT does not make much sense.
Suggestion: If you don't have much invested in mysqli then switch to PDO. It allows using named parameters which can make your code more robust and easier to maintain:
$sql = "UPDATE temp_all_product SET download_status = :status where id = :id";
$stmt = $pdo->prepare($sql);
$stmt->execute(array('status' => 1, 'id' => $product['id']));
Plus you can configure it to throw exceptions so you don't need all this error checking.
http://www.php.net/manual/en/book.pdo.php
http://net.tutsplus.com/tutorials/php/pdo-vs-mysqli-which-should-you-use/

Best way to avoid preparing the same PDO statement more than once?

Currently I save prepared statements into a private variable, because I ignore how they really work in the deepness, and do it just in case.
So the question is really simple, if I iterate over the same $PDO->prepare(), will it prepare again the same query?
foreach( $arr as $docid ) {
if( $this->dbLink === null ) { // PDO resource, saved in the object.
throw new Exception( 'Must first connect to DB' );
}
if( $this->queryCheckAccess === null ) {
$query = 'SELECT * from something where id = :id';
$this->queryCheckAccess = $this->dbLink->prepare($query);
}
else {
$result = $this->queryCheckAccess->execute(array(':id'=>$docid));
}
}
Will it matter ? Or the DB Engine / PHP is smart enough to know that it is the same prepared statement?
Thanks a lot.
----------------- EDIT --------------
I think I was misunderstood.
What I ask is what happens if I do:
$query = 'SELECT * from something where id = :id';
$this->queryCheckAccess = $this->dbLink->prepare($query);
$query = 'SELECT * from something where id = :id';
$this->queryCheckAccess = $this->dbLink->prepare($query);
$query = 'SELECT * from something where id = :id';
$this->queryCheckAccess = $this->dbLink->prepare($query);
$query = 'SELECT * from something where id = :id';
$this->queryCheckAccess = $this->dbLink->prepare($query);
And what happens if I do:
if( $this->queryCheckAccess === null ) {
$query = 'SELECT * from something where id = :id';
$this->queryCheckAccess = $this->dbLink->prepare($query);
}
Will the engine prepare the query 4 times in the first example? Or will notice it is the same query and just "jump" that?
Your code only prepares the query once, because after the first loop iteration, it's not NULL so it the conditional block won't run. But it's a waste of time to check the condition every time through the loop.
But to answer your question, if you prepare() the same query, it does do redundant work, even if the query is identical to the one you prepared before. So you should avoid that.
But you don't need to prepare inside the loop at all. Prepare once before you start the loop, and bind a variable to the parameter. You don't need to bind every time in the loop, just change the value of that variable.
if( $this->dbLink === null ) { // PDO resource, saved in the object.
throw new Exception( 'Must first connect to DB' );
}
$query = 'SELECT * from something where id = :id';
$this->queryCheckAccess = $this->dbLink->prepare($query);
$this->queryCheckAccess->bindParam(':id' => $docidparam);
foreach( $arr as $docid ) {
$docidparam = $docid;
$result = $this->queryCheckAccess->execute();
}
I'm not sure if you can bind the variable and also use it as the loop variable, there might be a scope conflict.
Another suggestion for this query: why not just run one query to search for a list of values?
$list = implode(",", array_fill(1, count($arr), "?"));
$query = "SELECT * FROM something WHERE id IN ( $list )";
$this->queryCheckAccess = $this->dbLink->prepare($query);
$this->queryCheckAccess->execute($arr);
PS: Also you should check for errors. If you enable PDO error mode EXCEPTION, then errors will automatically throw exceptions. If you don't enable that mode, you need to check the return value of prepare() and execute(), which return false if there's an error.
I just RUN a code similar to your example, and enabled MySQL Query LOG I found that all prepare requests are sent to MySQL Server
Prepare SELECT * FROM test_table WHERE username = ?
Close stmt
Prepare SELECT * FROM test_table WHERE username = ?
Close stmt
Prepare SELECT * FROM test_table WHERE username = ?
Close stmt
Prepare SELECT * FROM test_table WHERE username = ?
Close stmt
Test code:
$sth = $dbh->prepare($sql);
$sth = $dbh->prepare($sql);
$sth = $dbh->prepare($sql);
$sth = $dbh->prepare($sql);
$sth = $dbh->prepare($sql);
$sth->bindParam(1, $user);
$sth->execute();
Then, the best way is to prepare once, and Bind different values and then execute.
$sth = $dbh->prepare($sql);
$user = "test";
$sth->bindParam(1, $user);
$sth->execute();
$user = "test2";
$sth->bindParam(1, $user);
$sth->execute();
$user = "test";
$sth->bindParam(1, $user);
$sth->execute();
No, that's one of the main features of prepared statements. If you're going to run the same query multiple times but with different variables then preparing the query will give you a speed increase. Especially if you make use of transactions (requires InnoDB storage engine).
To answer the question from the title (which is quite different from questions in the body), the best way to avoid preparing the same statement more than once, apparently would be to avoid running multiple similar queries at all.
To answer the question from the question body - no, DB Engine / PHP is not "smart" enough to know that it is the same query were prepared again. With every new prepare() call another statement is created. And I would be first to hate such a "smart" behavior. The "smarter" your tool, the more unpredictable results you get.
To answer the real problem in the code, a smart developer would use a right tool to save himself a trouble.
With safeMysql whole mess will be reduced to one query and one line of code
$data = $this->dbLink->getAll('SELECT * from somth where id IN (?a)', $arr);
S0 - no multiple queries, no multiple preparations, no multiple questions.
By the way, you are losing first id with your code.
Yet you're losing all of them but last one if you don't use the result in place.

php query-loop does not work

I have this code:
public function updateOrder($num, $ufood, $uquan) {
$response = array();
mysql_query("SET NAMES 'utf8'");
foreach ($ufood as $index => $f) {
$result = mysql_query("SELECT food, quantity, uquantity FROM table1 WHERE food ='".$f."'") or die(mysql_error());
$no_of_rows = mysql_num_rows($result);
$response['number rows'] = $no_of_rows;
if ($no_of_rows>0) {
while ($row = mysqli_fetch_array($result)); {
if (!$row['uquantity']) {
$w = "INSERT INTO table1(uquantity) VALUES ('$uquan[$index]')";
mysql_query($w);
$e = (int)$row['quantity'];
$q = (int)$uquan[$index];
$sum = $e+$q;
$s = (string)$sum;
$d = "UPDATE table1 SET quantity = '$s' WHERE food = ".$row['$food']." ";
mysql_query($d);
} else if($row['uquantity']) {
$c = (int)$row['uquantity'];
$q = (int)$uquan[$index];
$sumq = $c+$q;
$sq = (string)$sumq;
$d = "UPDATE table1 SET uquantity = '$sq' WHERE food = ".$row['$food']." ";
}
}
} else {
$string ="INSERT INTO table1(food,uquantity) VALUES ('".$f."','".$uquan[$index]."')";
$z = mysql_query($string);
}
}
}
Well i can not make this work, and i am trying all kinds of things put still it doesn't work.
So i have some questions:
Is this structure of foreach and while valid?
Though the $result query returns some rows from the database, when i try to use $row['quantity'], as a value, i get null.
In this code i receive some data from an android app, and i try to "see", if there are already entries for the type food of my db_table(table1). If there are entries i want the db to sum the quantity entry of the android sent, data with the one that are inside my db, and update the field. This is the basically it. But as i said when i try to use the data that comes from the database, i get null values.
Please if someone could give me some hint, cause I'm really stuck..
There are many problems with your code. I'm marking this answer as Community Wiki, and I invite others to edit and add things as they find them.
You may also consider posting to https://codereview.stackexchange.com/ instead, when you have so many mistakes, until you have a more specific question.
Bad variable interpolation
This line won't do what you want it to:
$w = "INSERT INTO table1(uquantity) VALUES ('$uquan[$index]')";
This is not quite valid PHP syntax. You can either concatenate expressions:
$w = "INSERT INTO table1(uquantity) VALUES ('".$uquan[$index]."')";
Or you can embed expressions in curly braces:
$w = "INSERT INTO table1(uquantity) VALUES ('{$uquan[$index]}')";
Or you can use a query parameter placeholder:
$w = "INSERT INTO table1(uquantity) VALUES (?)";
$stmt = mysqli_prepare($w) or die(mysqli_error());
$uqi = $uquan[$index];
mysqli_stmt_bind_param($stmt, "i", $uqi);
mysqli_stmt_execute($stmt);
Mixing MySQL APIs
You can't mix mysql_query() with mysqli_fetch_array(). PHP has more than one API for MySQL, and you can't mix them. You should standardize on using the mysqli API, because the older mysql API is now deprecated.
Semicolon defeats while loop
The semicolon after the while statement makes the loop a no-op, and when it terminates, the $row contains nothing.
while ($row = mysqli_fetch_array($result)); {
Should be:
while ($row = mysqli_fetch_array($result)) {
Using variables inappropriately
Referencing a $row key with a single-quoted variable is probably not what you mean, in multiple ways:
$d = "UPDATE table1 SET quantity = '$s' WHERE food = ".$row['$food']." ";
The column name in the select-list of your earlier SELECT query is 'food', not '$food'.
Also, even if you meant to use a variable name $food as the key, putting it in single quotes would not use the value of the variable, it would be the literal string '$food'.
Failure to quote string literal?
Furthermore, you use a quoted literal for comparing to the food column in your SELECT query, which makes me think it might be a string.
So the UPDATE should be something like:
$d = "UPDATE table1 SET quantity = '$s' WHERE food = '".$row['food']."' ";
Or:
$d = "UPDATE table1 SET quantity = '$s' WHERE food = " . intval($row['food']);
Or preferably use parameters and a prepared query, then you don't need to worry about quotes or types:
$d = "UPDATE table1 SET quantity = ? WHERE food = ?";
. . .
Failure to check for errors
Every query might fail, either because you have a syntax error (e.g. a string without quoting), or because the table doesn't have a column by the name you reference, or privileges issues, etc.
Always check the return status of the query function when you run a SQL query. The function returns false if there's an error, and if that happens you must check the error message.
mysqli_query($mysqli, $d) or trigger_error(mysqli_error($mysqli), E_USER_ERROR);
Failure to execute the UPDATE
Your second update assigns a SQL query string to the variable $d, but then does not execute that update query at all!

Categories