Fetch data from db using PDO - php

I'm new to PDO, I'm using it as advised by senior users in this website.
I'm trying to get data from my table using pdo, using while, so I can get all the data "organized".
My query is working, but for some reason I can't even dump it.
Heres my code:
$sql = $conn->query("SELECT id, nivel, tipo, titulo, texto, ativa FROM account.quests_faq WHERE ativa='YES' ORDER BY nivel DESC");
while($row = $conn->fetch(PDO::FETCH_ASSOC)){
if ($tipo=='main'){
echo '<li><font color="green">Nivel '$row['nivel']' - '$row['titulo']'</font></li><br>';
}else{
echo '<li><font color="red">Nivel '$row['nivel']' - '$row['titulo']'</font></li><br>';
}
}
So, in a resume.
I have a table with titles, some text and an id.
I want to get this data from it and echo it.
Hope you can help me, sorry for the newb doubt.
EDIT 1:
$username = 'sssss';
$password = 'sssss';
$conn = new PDO('mysql:host=xxxxxxxx;dbname=account', $username, $password);
$sql = "SELECT id, nivel, tipo, titulo, texto, ativa FROM account.quests_faq WHERE ativa='YES' ORDER BY nivel DESC";
$stmt = $conn->query($sql);
while($row = $stmt->fetch(PDO::FETCH_ASSOC)){
echo '<li><font color="green">Nivel '.$row['nivel'].' - '.$row['titulo'].'</font></li><br>';
}else{
echo '<li><font color="red">Nivel '.$row['nivel'].' - '.$row['titulo'].'</font></li><br>';
}
}

Well, advise you were given is wrong.
Not use but learn.
You have to learn something before using it.
There are many tutorials on PDO around (all of them crappy ones though) but at least you can learn proper syntax from there
$sql = "SELECT id, nivel, tipo, titulo, texto, ativa FROM account.quests_faq WHERE ativa='YES' ORDER BY nivel DESC";
// look this string contains SQL query. so, the variable is named $sql
$stmt = $conn->query($sql);
// in the next line we are getting a statement object from the function query()
// this is why variable called $stmt
while($row = $stmt->fetch(PDO::FETCH_ASSOC)){
// and now we can start iterating this statement.
// statement, Carl. Not connection to database
// which is called $conn, if you get an idea
also you have to enable error reporting for PDO.
And yes, as it was said in the other answer, your PHP syntax is also wrong. You are supposed to learn it too, instead of banging together random lines of code and then asking others to fix it for you.
Start from less complex syntax, from echoing one single variable without decoration. And ask one question per post. As for the PDO part you already got the answer

Try using a foreach loop. Once the loop is finished you can actually use the $arrRows array anywhere throughout the file! I was told by one of the senior web developers that this is a better way to do it.
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
foreach($rows as $key => $arrRows){
echo $arrRows['COLLUMN_NAME_HERE'];
}
Here is a demo function that will select values from a table using PDO
function showPost($uID){
global $numRecords, $dbConnection, $stmt;
connect(); //Run connect function (../connections/connections.php)
$sqlStr = "SELECT user_post.*, user.name, user.avatar FROM user_post JOIN user ON user_post.uID = user.uID WHERE user_post.uID = ".$uID. " ORDER BY post_time DESC";
//Run Query
try
{
$stmt = $dbConnection->query($sqlStr);
if($stmt === false)
{
die("Error executing the query: $sqlStr");
}
}
catch(PDOException $error)
{
//Display error message if applicable
echo "An error occured: ".$error->getMessage();
}
$numRecords = $stmt->rowcount();
//Close the databaase connection
$dbConnection = NULL;
}
Let me know if you have anymore questions

You were using your connection variable conn instead of your query variable sql to fetch your query results.
$sql = $conn->query("SELECT id, nivel, tipo, titulo, texto, ativa FROM account.quests_faq WHERE ativa='YES' ORDER BY nivel DESC");
while($row = $sql->fetch(PDO::FETCH_ASSOC)){
if ($tipo=='main')
echo '<li><font color="green">Nivel '$row['nivel']' - '$row['titulo']'</font></li><br>';
else
echo '<li><font color="red">Nivel '$row['nivel']' - '$row['titulo']'</font></li><br>';
}
Or you can do similarly using Prepared Statements
$sql = $conn->prepare("SELECT id, nivel, tipo, titulo, texto, ativa FROM account.quests_faq WHERE ativa='YES' ORDER BY nivel DESC");
$sql->execute();
while($row = $sql->fetch(PDO::FETCH_ASSOC)){
if ($tipo=='main')
echo '<li><font color="green">Nivel '$row['nivel']' - '$row['titulo']'</font></li><br>';
else
echo '<li><font color="red">Nivel '$row['nivel']' - '$row['titulo']'</font></li><br>';
}

Related

Php page not loading when using mysqli_fetch_assoc

I have been working on a database management page using PHP. Recently I finished the page, and was working on the security aspect, when I ran into a problem with my first SQL query. It was not prepared, and could have empty input. When I tried using the following code to prepare it, it gave an error.
$id_query = "SELECT sp.name as name, sp.sku_id as sku_id, sp.id as prod_id FROM shop_product as sp WHERE scanbarcode_barcode='?';";
$stmt1 = $conn->prepare($id_query);
$stmt1->bind_param("s", $barcode);
$stmt1->execute();
$result1 = $stmt1->get_result();
$stmt1->close();
As I understand, it was because it was not recognising the '?' as a place for parameter binding.
I then tried the following code:
if(isset($_GET["barcode"])) {
$barcode = $_GET["barcode"];
}else{
$barcode = "";
}
# array definition using $barcode
if(isset($_GET["barcode"])) {
$id_query = "SELECT sp.name as name, sp.sku_id as sku_id, sp.id as prod_id FROM shop_product as sp WHERE scanbarcode_barcode=?;";
$stmt1 = $conn->prepare($id_query);
$stmt1->bind_param("s", $barcode);
}else{
$id_query = "SELECT sp.name as name, sp.sku_id as sku_id, sp.id as prod_id FROM shop_product as sp WHERE scanbarcode_barcode='';";
$stmt1 = $conn->prepare($id_query);
}
$stmt1->execute();
$result1 = $stmt1->get_result();
$stmt1->close();
$result1 = mysqli_fetch_assoc($result1);
And the page just doesn't load.
I am using a Xampp localhost Apache and MySQL server.
If I don't use the last line, $result1 = mysqli_fetch_assoc($result1);, it fails on the line after, as it can't interpret a mysqli_result as an array. (The next line is a while loop, not shown here, as it's irrelevant)
I have thought about just adding some checks (the only thing that is passed in is an EAN13 barcode, and using normal
$result1 = mysqli_query($conn, $id_query);
$result1 = mysqli_fetch_assoc($result1);
but would prefer to use prepared statements.
Note: If I print_r() the $result1 before using the mysqli_fetch_assoc() on it, I get ~960 rows. It worked fine and fast before I tried preparing the statement.
Minimal reproducible example as requested:
<form action="dash.php" method="get">
Barcode: <input type="text" name="barcode">
<input type="submit">
</form>
<?php # Gets info about the product
$conn = mysqli_connect($hostname, $username, $password, $database);
if(isset($_GET["barcode"])) {
$barcode = $_GET["barcode"];
}else{
$barcode = "";
}
if(isset($_GET["barcode"])) {
$id_query = "SELECT sp.name as name, sp.sku_id as sku_id, sp.id as prod_id FROM shop_product as sp WHERE scanbarcode_barcode=?;";
$stmt1 = $conn->prepare($id_query);
$stmt1->bind_param("s", $barcode);
}else{
$id_query = "SELECT sp.name as name, sp.sku_id as sku_id, sp.id as prod_id FROM shop_product as sp WHERE scanbarcode_barcode='';";
$stmt1 = $conn->prepare($id_query);
}
$stmt1->execute();
$result1 = $stmt1->get_result();
$result1 = mysqli_fetch_assoc($result1);
var_dump($result1);
$stmt1->close();
I have figured it out. It was me being a little stupid and using a bunch of while loops where they ended up not being needed. The page wasn't loading because it was executing infinite while loops. Special thanks to Dharman and Barmar for giving me ideas.

PHP Mysqli Query execute from table data query

I have sql query that saved on table.
tbl_query
SELECT SUM(simpanan_wajib) AS TOTAL FROM tb_simpanan WHERE badgeid_fk = '$getBadgeID'
Then on PHP code:
$query = mysqli_query($con, "SELECT * FROM tbl_query");
while($data = mysqli_fetch_array($query))
{
//SELECT SUM(simpanan_wajib) AS TOTAL FROM tb_simpanan WHERE badgeid_fk = '$getBadgeID'
$getQuery = $data['sql_query'];
$qTotal = mysqli_query($con, $getQuery);
$dTotal = mysqli_fetch_array($qTotal);
echo $dTotal['TOTAL'];
}
When I tried to run that code, it show me result of total is 0. But if I remove this WHERE badgeid_fk = '$getBadgeID' on query data, the result is OK not 0.
How to keep execute the query even if there is an variable '$getBadgeID'
PHP treating this variable as a string, thats why result generating this query
SELECT SUM(simpanan_wajib) AS TOTAL FROM tb_simpanan WHERE badgeid_fk = '$getBadgeID' // its not converting your variable with 150502
Here you can use alternate name or you can use with delimiter like:
Your current query is:
SELECT SUM(simpanan_wajib) AS TOTAL FROM tb_simpanan WHERE badgeid_fk = '$getBadgeID'
Change your query with:
SELECT SUM(simpanan_wajib) AS TOTAL FROM tb_simpanan WHERE badgeid_fk = ':getBadgeID'
Now, you need to use str_replace to replace delimiter with your variable like:
while($data = mysqli_fetch_array($query))
{
$getQuery = str_replace(":getBadgeID", $getBadgeID , $data['sql_query']);
}
Why i am using delimiter here, because your variable $getBadgeID having defined value inside your php script and its not dynamic.
In our chat conversation, #executable suggest an another solution to use prepared statement.
Edit:
As per discussion with #Bananaapple, i am adding this comment for future visitors, Prepared Statement is an another solution which is more secure, if you want to avoid SQL injection, then choose prepared statement.
The recommend way is to use the prepared statements to sanitize the query and protect you from SQL injection. The following comic give an example of what is SQL injection.
For answering the question we discover that in your query the variable $getBadgeID was read as text and not as variable. I recommend you to use this code which use the prepared statements :
<?php
$conn = new mysqli("HOST", "USER", "SECRET", "DATABASE");
if($stmt = $conn->prepare("SELECT SUM(simpanan_wajib) AS TOTAL FROM tb_simpanan WHERE badgeid_fk = ?")) {
$stmt->bind_param("s", $getBadgeID);
$stmt->execute();
$result = $stmt->get_result();
while($row = $result->fetch_assoc()) {
$total = $row['TOTAL'];
}
$stmt->close();
}
$conn->close();
var_dump($total);
If you want more debugging :
<?php
if(isset($getBadgeID) and $getBadgeID != ""){
$conn = new mysqli("HOST", "USER", "SECRET", "DATABASE");
if($stmt = $conn->prepare("SELECT SUM(simpanan_wajib) AS TOTAL FROM tb_simpanan WHERE badgeid_fk = ?")) {
$stmt->bind_param("s", $getBadgeID);
$stmt->execute();
$result = $stmt->get_result();
while($row = $result->fetch_assoc()) {
$total = $row['TOTAL'];
}
$stmt->close();
}else{
echo "Query is wrong";
}
$conn->close();
var_dump($total);
}else{
echo 'Variable $getBadgeID is empty';
}

comparing php variable in sql query

I am trying to compare php variable in the sql query as follows:
I have used '$a' as the way to compare. Any solution will provided will be quite helpful.
<?php
$username=$_SESSION['alogin'];
$sql = "SELECT kDepartment FROM USERS WHERE kUsername=:username ";
$query= $dbh -> prepare($sql);
$query-> bindParam(':username', $username, PDO::PARAM_STR);
$query->execute();
$results=$query->fetchAll(PDO::FETCH_OBJ);
if($query->rowCount() > 0)
{
foreach($results as $result2)
$a=$result2;
{?>
<?php }}?>
<?php
$sql2 = "SELECT BudgetInput.kBudgetAvailable FROM BudgetInput WHERE BudgetInput.kDepartment='$a' ";
$query2 = $dbh -> prepare($sql2);
$query2->execute();
$results2=$query2->fetchAll(PDO::FETCH_COLUMN, 0);
print htmlentities($a);
?>
I am unable to fetch the result.
When I remove WHERE BudgetInput.kDepartment='$a'; the UI works correctly.
The main issue that I can see with your code is that you are assigning an object ($result2 is the last entry in the array of objects returned by your query) to $a and then trying to use that as a string (I'm not sure why you're using PDO::FETCH_OBJ for your fetchAll call when you are only retrieving a single value but that's another question). Anyway, the fetchAll will return an anonymous object (see the manual) with one property, kDepartment. To use that value, change:
$sql2 = "SELECT BudgetInput.kBudgetAvailable FROM BudgetInput WHERE BudgetInput.kDepartment='$a' ";
to
$sql2 = "SELECT BudgetInput.kBudgetAvailable FROM BudgetInput WHERE BudgetInput.kDepartment='{$a->kDepartment}' ";
The other (minor) issue that I see is that you are using rowCount. This is not guaranteed to work for SELECT statements (see the manual) and since you have already done a fetchAll you don't need it, you can simply change
if($query->rowCount() > 0)
to
if (count($results) > 0)
All you need is a simple join - then you need one query instead of two. A query from the result of another query is rarely the best approach.
Here we prepare a query which selects the available budget from the BudgetInput table, where it has a matching kDpeartment in the USERS table, and a username matching the variable in $username.
<?php
session_start();
$username = $_SESSION['alogin'];
$stmt = $dbh->prepare("SELECT bi.kBudgetAvailable
FROM BudgetInput bi
JOIN USERS u ON u.kDepartment=bi.kDepartment
WHERE u.kUsername=?");
$stmt->execute([$username]);
if ($result = $stmt->fetch()) {
echo $result['kBudgetAvailable'];
} else {
echo "No results found";
}

PHP PDO Select query returns double values

For my inhome temparature sensor i'm using a raspberry pi with php, sqlite, PDO, and HTML.
I've create a table in sqlite
Using
BEGIN;
CREATE TABLE waarden (datum TEXT, tijd TEXT, zone TEXT, lucht REAL, temperatuur REAL);
COMMIT;
My rpi with DHT22 records everything fine so no i've created a webpage accessing the data via AJAX using the following php.file
<?php
function datumConversie($datum){
$delen = explode('/',$datum,3);
$geconverteerd = $delen[2].$delen[0].$delen[1];
return $geconverteerd;
}
ini_set('display_errors', 'On');
error_reporting(E_ALL | E_STRICT);
$db = new PDO("sqlite:/home/pi/sensor.db");
$result_array = array();
$date = $_POST["datepicker"];
$waarde = datumConversie($date);
$tijd="";
$temperatuur="";
$query = "SELECT datum, tijd, zone,lucht, temperatuur FROM waarden WHERE datum = $waarde";
$result = $db->query($query);
foreach($result as $row)
{
array_push($result_array, $row);
}
echo json_encode($result_array);
$db = null;
?>
The problem is that when I look in the browser response it seems that values are returned twice. Once with their appropriate field-name and once with their column index. (0 being datum, 1 being tijd etc). See below
{"datum":"20170601","0":"20170601","tijd":"00:01","1":"00:01","zone":"kelder","2":"kelder","lucht":"53.0","3":"53.0","temperatuur":"24.3","4":"24.3"},
{"datum":"20170601","0":"20170601","tijd":"00:06","1":"00:06","zone":"kelder","2":"kelder","lucht":"53.1","3":"53.1","temperatuur":"24.3","4":"24.3"},
{"datum":"20170601","0":"20170601","tijd":"00:11","1":"00:11","zone":"kelder","2":"kelder","lucht":"53.1","3":"53.1","temperatuur":"24.2","4":"24.2"},
How can I avoid this. I've tried several conversions which can work in the end but that is just patching some flaw without addressing the cause?
Any suggestions
Set the default fetch mode like so
$db->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_OBJ);
Or
$db->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
before running the fetch
$db->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
foreach($result as $row) {
array_push($result_array, $row);
}
Or replace with a one liners using fetchAll() and use prepared and parameterized statements as well to mitigate against SQL Injection Attack
$query = "SELECT datum, tijd, zone,lucht, temperatuur
FROM waarden
WHERE datum = :datum";
$result->prepare($query);
$result->execute([':datum'=>$waarde]);
$result_array = $result->fetchAll(PDO::FETCH_ASSOC);
The parameter to fetchAll(PDO::FETCH_ASSOC) controls how results will be returned.
Try this sample code...
$sth = $db->prepare("SELECT datum, tijd, zone,lucht, temperatuur FROM waarden WHERE datum = :datum");
$sth->execute(array('datum' => $waarde));
$result = $sth->fetchAll(PDO::FETCH_ASSOC);
echo '<pre>';
print_r($result);
echo '</pre>';

PHP prepare and execute

I was using the following code to execute the queries in the database:
$sql = "SELECT * FROM cc_topchoices WHERE location='$location' ORDER BY position asc";
$result = mysqli_query($conn, $sql);
I have read that this way to make the queries is not secure so I want to use the statements prepare() and execute() in php
Now my code looks like this:
$sql = "SELECT * FROM cc_topchoices WHERE location=:location ORDER BY position asc";
$stmt = $conn->prepare($sql);
$stmt->execute(array(":location" => $location));
$result = mysqli_query($conn, $stmt);
But this give me this error:
Fatal error: Call to a member function execute() on boolean
Any idea?
EDIT
Now my code looks like this:
// Create connection
$conn = new PDO("mysql:host=$servername;dbname=$dbname", "$username", "$password");
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$conn->exec("set names utf8"); //BECAUSE I NEED TO WORK WITH CHINESE LANGUAGE
$sql = "SELECT * FROM cc_topchoices WHERE location=? ORDER BY position asc";
$stmt = $conn->prepare($sql);
$stmt->bindParam(':location', $location);
$stmt->execute(array($location));
$result = $stmt->setFetchMode(PDO::FETCH_ASSOC);
if ($result > 0) {
// output data of each row
while($row = $stmt->fetch()) {
echo "<li><div><a href='". $row["rest_url"] ."'><img src='images/top_choices/". $row["image"] ."' alt='". $row["alt_desc"]. "' /></a></div></li>";
}
} else {
echo "0 results";
}
is working :) just need to know if this is a good and secure practice
PDO supports named parameters. MySQLi does not. $stmt is false to show you that the SQL you tried to prepare is syntactically malformed. Use ? instead of :location. Check the MySQLi manual for the correct way to use MySQLi. Or, alternately, switch to PDO.
Use below code to fetch records instead of mysqli_query when using pdo statements if your query returns single row.
$result = $stmt->fetch(PDO::FETCH_ASSOC);
echo $result['db_column'];
And if return multiple rows:
$stmt->setFetchMode(PDO::FETCH_ASSOC);
while ($result = $stmt->fetch()) {
echo $result['db_column'];
}
And one more thing, always put your prepared statement in try{}..catch{} block.
It will work for you.

Categories