I'm trying to select a row from a table using mysqli but all I can get is a bunch of null values and I don't really know why. The same query works using normal php mysql and if I try to perform the same query on phpMyAdmin using the parameter I pass goes through fine.
Here's the code:
$con = mysqli_connect('localhost', 'user', 'pass',"db");
if (mysqli_connect_errno()){
die("Failed to connect to MySQL: " . mysqli_connect_error());
}
$coupon = $_GET['coupon'];
$sql = mysqli_prepare($con, "SELECT * FROM coupon WHERE coupon=?");
$sql->bind_param('s', $coupon);
$sql->execute();
$sql->store_result();
echo $sql;
returns
"affected_rows":null,
"insert_id":null,
"num_rows":null,
"param_count":null,
"field_count":null,
"errno":null,
"error":null,
"error_list":null,
"sqlstate":null,
"id":null
I already tried to search for an answer either here and on google but I couldn't find anything close to my problem.
What am I doing wrong?
You must decide if you're using procedural or OOP approach. From your code, it seems you call the procedural version of mysqli extension and afterwards you try using objects. See the documentation examples, both object oriented and procedural and decide on a single one.
author's final solution (moved from question content):
As suggested by user #RiggsFolly I wasn't fetching the results at all, plus I was mixing procedural and OOP approaches as suggested by user #Alex . Here's the working code for future reference to anyone who will arrive here with a similar problem:
$coupon = $_GET['coupon'];
if ($sql = mysqli_prepare($con, "SELECT * FROM coupon WHERE coupon=?;")){
mysqli_stmt_bind_param($sql, 's', $coupon);
mysqli_stmt_execute($sql);
mysqli_stmt_bind_result($sql, $ID, $coupon, $discount, $uses);
mysqli_stmt_fetch($sql);
$data = array(
'ID' => $ID,
'coupon' => $coupon,
'discount' => $discount,
'uses' => $uses
);
echo json_encode($data);
}else{
echo json_encode(FALSE);
}
Related
I'm trying to use PDO for the first time but I can't get any result out. I've tryed several variants of script examples that I found but I don't get any result out. No errors either. This is my latest attempt.
$db = new PDO('mysql:host=localhost;dbname=mydb;charset=utf8', 'myuser', 'mypass');
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$sql = " SELECT * FROM pages WHERE seo=:seo ";
$stmt = $db->prepare($sql);
$values= array( 'seo' => $_REQUEST['p1'] );
$stmt->execute($values);
while($result = $stmt->fetch()){
echo $result['text'];
}
Is there a column named "text" in your table? Are you sure that the value you're supplying for the bind parameter exists in the seo column of the pages table?
For debugging, I suggest you try modifying the query a bit, to see if you are returning any rows:
SELECT * FROM pages WHERE 1=1 OR seo=:seo LIMIT 10
Also, echo out that value you are supplying for the bind parameter:
echo "bind parameter value = ", $_REQUEST['p1'];
You might also try dumping out the results after the fetch:
var_dump($result);
That should help narrow down the problem.
A few keep telling me that my code for updating data in my mysqli query is extremely insecure. Actually, several people on this site. So I would like to know what they say would secure my code below so it is secure when updating my database. I would like to know how the would secure my mysqli query.
Okay, in my code for my database entries, this is what I do. Let me start by saying that I always send via POST method to avoid browser url complications.
When I get the POST data, this is my code.
$ID = 1;
$DATA = htmlentities(addslashes($_POST['data']));
$FIELD = "lifename";
$DBQUERY = "UPDATE `lifetable` SET `$FIELD` = '$DATA' WHERE `id` = $ID";
$DBRESULT = $MYSQLI->query($DBQUERY);
I am currently using this on my local site.
How is this unsafe if I have escaped all quotes, all slashes, all ampersands (from javascript through ajax) and all semi colons? How is this vunerable?
So can you tell me what I should change when adding information to my database.
Thanks
PS ... I am using mysqli and will continue to use it. Thanks
A few suggested that I change from mysqli to pdo, but I am not willing to completely 100% change how I access data from my databases. Someone posted another link before about prepare and bind_param and this is what I am going to use. So thank you.
This is now my code, and binding params is supposed to make it so that each param is only for the one part of my query and can not be for anything else, nothing else at all.
$DBQUERY = "UPDATE `lifetable` SET `lifename` = ? WHERE `id` = ?"; // EACH ? IS A PART OF bind_param BELOW IN ORDER AFTER TYPE.
$STMT = $MYSQLI->prepare($DBQUERY);
$STMT->bind_param('si', $DATA, $ID); // THIS MAKES SURE THAT THE VARIABLES ARE ONLY USED FOR THERE PLACE HERE AND NOTHING ELSE. ? in order.
$DATA = htmlentities($_POST['data']); // I STILL USE MY CODE HERE TO REMOVED ANY OTEHR CHARACTERS, JUST INCASE. AND BEFORE IT GETS HERE, IT USES encodeURIComponent TO OUTPUT FROM AJAX.
$ID = $COLUMN[1];
$STMT->execute();
$STMT->close();
My code worked before and it works now, just more secure, or so I am told.
Use PDO Class like:
$db = new PDO('mysql:host=localhost;dbname=<SOMEDB>', '<USERNAME>', 'PASSWORD');
$query = $db->prepare('UPDATE `lifetable` SET :FIELD = :DATA WHERE `id` = :ID');
$query->execute(array(
':FIELD' => $field,
':DATA' => $data,
':ID' => $id
));
$query->commit();
For more info Are there good tutorials on how to use PDO?
i think your security lies in the SQL injection, and the best way i know to make the query secure is using mysql_real_escape_string on the var. Here an example taken from php.net
$mysqli = new mysqli("localhost", "my_user", "my_password", "world");
$city = $mysqli->real_escape_string($city);
$mysqli->query("INSERT into myCity (Name) VALUES ('$city')")
you can apply the same procedure to your query
$ID = 1;
$DATA = $MYSQLI->real_escape_string($_POST['data']));
$FIELD = "lifename";
$DBQUERY = "UPDATE `lifetable` SET `$FIELD` = '$DATA' WHERE `id` = $ID";
$DBRESULT = $MYSQLI->query($DBQUERY);
I edited the above because I forgot the quotes for lifename in my question. They should be there as they are in my original code.
now tour query should be secure :D
here the reference to php.net documentation :
http://cn2.php.net/manual/en/mysqli.real-escape-string.php
I'm making a query using PHP/MySqli like this:
$sql = $mysqli->prepare("SELECT * FROM rooms
WHERE 1
LIMIT 0, 30 ");
$result = "['Number', 'Status', 'Category', 'Pbx Number', 'Price for today'],";
$sql->execute();
$sql->bind_result($id, $number, $status, $category, $pbx);
while ($sql->fetch()) {
$result .= " ['$number', '$status', '$category', '$pbx'," . priceForRoom($mysqli, $number, time()) . "],";
}
$sql->free_result();
return ($result);
It all works fine, as long as priceForRoom() doesn't need to connect to the mysqli db to return a value. But, as soon as I implement priceForRoom() and use mysqli I get this error:
Commands out of sync; you can't run this command now
So many people got the same error, but I still don't understand how can I fix this. I don't want to store the results in an array, how can I use mysqli_store_result without going procedural-style? I'd like to keep my code object oriented: where should I ask mysqli to store the result?
You need to store the results fetched to your variables before you can use them again.
Hence
$sql->bind_result($id, $number, $status, $category, $pbx);
while ($sql->fetch()) {
$sql->store_result();
Read up more about store_result() on php.net.
After being advised that the old method of access a database were not correct. I have now started using the PDO object. I am setting up a simple query but I am not getting any results back. Any help or advise would be appreciated. It is not even printing the query back to me. Would turning on error messages help?
<?php
//print_r(PDO::getAvailableDrivers());
$config['db'] = array( //This is the config array with the database details
'host' => 'localhost',
'username' => 'root',
'password' => '',
'dbname' => 'website'
);
$db = new PDO('mysql:host=' . $config['db']['host'] . ';dbname' . $config['db']['dbname'], $config['db']['username'], $config['db']['password']); //Instanciate an PDO Object
$query = $db->query("SELECT 'articles'.'title' FROM 'articles'");//running a query from the database
print_r($query); //printing a query
//while ($row = $query->fetch(PDO::FETCH_ASSOC)){
// echo $row['title'], '<br>';
//}
I would recommend you read up on PDO and error handling and reporting.
http://php.net/manual/en/pdo.error-handling.php
and
http://php.net/manual/en/pdo.errorinfo.php
They should show you how to easily get proper errors from your sql query so you can see whats going wrong.
In you're case your query is wrong it should be $query = $db->query("SELECT title FROM articles");
No need to specify the tabl to pull from in your select param section and no need for single quotes. You should be using the back tick quote not single quote anyway `
PHP manual :
<?php
function getFruit($conn) {
$sql = 'SELECT name, color, calories FROM fruit ORDER BY name';
foreach ($conn->query($sql) as $row) {
print $row['name'] . "\t";
print $row['color'] . "\t";
print $row['calories'] . "\n";
}
}
?>
You don't need quotes on table or column names.
Why dont you prepare your statements first and then execute them?
$stmt = $db->prepare($sql);
$stmt->execute();
$results = $stmt->fetchAll();
I am trying to apply a multiple WHERE conditions to my query just like this:
$hotel="Hotel Name";
$data1=explode('/',$data1);
$newdata1=mktime(0, 0, 0, $data1[0], $data1[1], $data1[2]);
$newdata1=date("Y-m-d", $newdata1);
$data2=explode('/',$data2);
$newdata2=mktime(0, 0, 0, $data2[0], $data2[1], $data2[2]);
$newdata2=date("Y-m-d", $newdata2);
$filtro=mysql_query("SELECT *
FROM hotels_rates_flat
WHERE htl_name = $hotel AND
given_date>=$newdata1 AND
given_date<=$newdata2
ORDER BY htl_name, city_zone, given_date")
or die(mysql_error());
It is returning the following error:
*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 'do Hotel AND given_date>=2012-09-01 AND given_date<=2012-09-05 ORDER BY htl_nam' at line 1.*
This is really bothering me because I can't see any clear mistake.
I would appreciate any help.
Thank you
Use PDO to avoid SQL injections and error reporting:
<?php
$db = new PDO('mysql:host=localhost;dbname=testdb;charset=UTF-8', 'username', 'password', array(PDO::ATTR_EMULATE_PREPARES => false, PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION));
$hotel="Hotel Name";
$data1=explode('/',$data1);
$newdata1=mktime(0, 0, 0, $data1[0], $data1[1], $data1[2]);
$newdata1=date("Y-m-d", $newdata1);
$data2=explode('/',$data2);
$newdata2=mktime(0, 0, 0, $data2[0], $data2[1], $data2[2]);
$newdata2=date("Y-m-d", $newdata2);
try {
$stmt = $db->query("SELECT * FROM `hotels_rates_flat` WHERE `htl_name` = :hotel AND (`given_date` BETWEEN :date1 AND :date2) ORDER BY `htl_name`, `city_zone`, `given_date`");
$stmt->execute(array(':hotel' => $hotel,':date1' => $newdata1,':date2' => $newdata2));
$results = $stmt->fetchAll(PDO::FETCH_ASSOC);
} catch(PDOException $ex) {
echo $ex->getMessage();
}
// use $results
?>
The source of your problem is quoting. You should use a prepared statement with placeholders, and let the mysql driver figure out how to insert the values in a syntactically valid way.
You can use mysqli_ functions similarly to mysql_ ones, and just add a couple extra calls to handle the parameters. You do need an explicit database handle (I call it $dbh below; it's returned from mysqli_connect()) instead of relying on an implicit one like the mysql_ functions let you do.
$stmt = mysqli_prepare($dbh, 'SELECT * FROM hotels_rates_flat'
. ' WHERE htl_name = ?'
. ' AND given_date BETWEEN ? AND ?'
. ' ORDER BY htl_name, city_zone, given_date');
# the 'sss' means treat all three parameters as (s)trings
mysqli_bind_param($stmt, 'sss', $hotel, $newdata1, $newdata2) or die(mysqli_error($dbh));
$filtro = mysqli_stmt_execute($stmt) or die(mysqli_error($dbh));
Or you could use PDO, as in Mihai's answer, which is a bit different.
You need to encase $hotel, $newdata1 and $newdata2 with single quotes.
SELECT * FROM hotels_rates_flat WHERE htl_name = '$hotel' AND ...
You can also use the BETWEEN operator instead of writing out less than & greater than:
AND given_date BETWEEN '$newdata1' AND '$newdata2'
You should also stop using mysql_ functions.