PHP PDO Select query returns double values - php

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>';

Related

Why can't I execute two queries?

session_start();
require 'db-conn.php';
$u1 = $_POST['ricevente'];
$u2 = $_POST['richiedente'];
if(isset($_POST['accetta'])){
$sql = "UPDATE amici SET amicizia=1 WHERE utenteDue='$u2' AND utenteUno = '$u1';";
$sql55 = "INSERT INTO notifiche (idRichiedente, idRicevente, tipoNotifica) VALUES ('$u2', '$u1', '2');";
$result55 = $conn->query($sql55);
$result = $conn->query($sql);
}elseif(isset($_POST['rifiuta'])){
$sql = "DELETE FROM amici WHERE utenteDue='$u2' AND utenteUno = '$u1'";
$result = $conn->query($sql);
}else echo "Si รจ verificato un errore";
This is my code, it only computes the $sql variable while not the $sql55. Can you please tell me why? The variables are fine and just okay (the first query goes well).
You are inserting post data directly into your query instead of using prepared statements, this is highly undesirable.
When should I use prepared statements?
https://www.php.net/manual/en/pdo.prepared-statements.php
But if you must do it this way, you need to concat the values into your query string as such ...
$sql55 = "INSERT INTO notifiche (idRichiedente, idRicevente, tipoNotifica) VALUES ('".$u2."', '".$u1."', '2');";

Error doing db2 insert with PHP parameterized query

I'm trying to run a db2 parameterized query in PHP and upon the execution of the insert, I get the error:
Invalid parameter number., SQL state S1002 in SQLDescribeParameter
This is my script:
$getItems = "
SELECT
ID,
EXPIRATION_TIMESTAMP
FROM table1
";
$stmt = odbc_exec($DB2connDEV, $getItems);
$prepInsert = odbc_prepare($DB2connPROD, "INSERT INTO table2 (originalID, expiration_timestamp) VALUES(?,?)");
while($gettingDevItems = odbc_fetch_array($stmt)){
$rows[] = $gettingDevItems;
}
foreach($rows as $row){
$originalID = $row['ID'];
$expiration_timestamp = $row['EXPIRATION_TIMESTAMP'];
$getIdentity = "SELECT IDENTITY_VAL_LOCAL() AS LASTID FROM SYSIBM.SYSDUMMY1";
$insertTable = odbc_execute($prepInsert, array($originalID, $expiration_timestamp));//error at this line
$insertTable = odbc_exec($DB2connPROD, $getIdentity);
$row = odbc_fetch_array($stmt);
$ret = $row['LASTID'];
}
When I do a var_dump on the array of params, I get this:
array(2) {
[0]=>string(1) "2"
[1]=>string(26) "2019-10-03 00:00:00.000000"
}
What am I doing wrong here? Even if I take one value out to only insert one or the other I still get it, so It's not specific to one column.
Maybe odbc can't support reuse of prepared statement, or your driver, or other part of your code, or another thing.
Anyway, move the prepared statement inside your foreach loop to make sure you will rebuild it:
foreach($rows as $row){
$prepInsert = odbc_prepare($DB2connPROD, "INSERT INTO table2 (originalID, expiration_timestamp) VALUES(?,?)");
...

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";
}

Fetch data from db using PDO

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>';
}

How do I get my database results in an array?

I want to create this array with data from my database..
| Day | Comment | OtherComment |
|-----|---------|--------------|
| 1 | hallo | hallohallo |
|-----|---------|--------------|
| 2 | hey | heyhey |
|-----|---------|--------------|
| 3 | hello | hellohello |
|_____|_________|______________|
I tried a lot of things, but could get the result I wanted, this is my latest code:
$sql = "select DiaryOpmerkingen, DiaryDoctorcomment from tblDiary
WHERE fk_UserId = ".$p_iUserid."
AND DiaryDay = '".$this->Day."';";
$rResult = mysqli_query($link, $sql);
return $rResult;
$dim = array();
while ( $row = mysql_fetch_assoc($result) )
$dim[$row['DiaryOpmerkingen']][$row['DiaryDoctorcomment']] = $row;
Using MySQLi
Okay since we plan to do this using MySQLi, I'd like to introduce you to the object oriented way of using mysqli, so you don't have to keep passing the database link around in your calls. We'll need to make a change to how we connect:
$mysqli = new mysqli('localhost', 'my_user', 'my_password', 'my_db');
if ($mysqli->connect_error) {
// So the user an error instead of exiting like this
// in your production code!
echo "Connect Error ({$mysqli->connect_errno}) {$mysqli->connect_error}";
exit;
}
As noted in the comment inline, instead of exiting and showing the user a very ugly looking single line error, you should instead show them a more friendly error page. Next we're going to use something called a prepared statement to make sure our data is sanitized:
$sql = "SELECT DiaryOpmerkingen, DiaryDoctorcomment FROM tblDiary
WHERE fk_UserId = ?
AND DiaryDay = ?";
$stmt = $mysqli->prepare($sql);
if(!$stmt) {
// Let the user know the query failed!
}
This is a bit unfamiliar looking for those of us used to your standard queries with variables inlined:
$sql = "SELECT DiaryOpmerkingen, DiaryDoctorcomment FROM tblDiary
WHERE fk_UserId = ?
AND DiaryDay = ?";
Basically the question marks act as placeholders that we will fill with the actual values we want. Please note that for string values, you don't need to put quotes around the value:
$sql = "SELECT DiaryOpmerkingen, DiaryDoctorcomment FROM tblDiary
WHERE fk_UserId = ?
AND DiaryDay = '?'"; <-- This is wrong!!
Next is the core of prepared statements:
$stmt->bind_param('is', $p_iUserid, $this->Day);
Here, we are telling MySQLi what we want to replace the question mark placeholders with. The first argument to bind_param indicates the type of data we're replacing. This allows MySQLi to perform sanity checks.
In this case i represents an integer value, and s represents a string value. Then we list our values in the order they appear in the query. $p_iUserid replaces the first ? and $this->Day replaces the second ?. Now we execute this statement so we can get the actual data:
$stmt->execute();
The next part is a very interesting feature:
$stmt->bind_result($diaryOpmerkingen, $diaryDoctorcomment);
This looks complicated at first, but its actually makes things very easier when working with the query. What this function does is create the variables $diaryOpmerkingen and $diaryDoctorcommen fills them with the actual column data when we loop through our results:
$dim = array();
while ($stmt->fetch()) {
$dim[$diaryOpmerkingen][$diaryDoctorcomment] = array($diaryOpmerkingen, $diaryDoctorcomment);
}
Notice how we don't have to use associative arrays and can instead utilize cleaner variable names? Finally, since with prepared statements, you can keep swapping in different values, we need to free our prepared statement once we're done with it:
$stmt->close();
Finally, we close our main database connection:
$mysqli->close();
Here is the full code listing for reference:
$mysqli = new mysqli('localhost', 'my_user', 'my_password', 'my_db');
if ($mysqli->connect_error) {
// So the user an error instead of exiting like this
// in your production code!
echo "Connect Error ({$mysqli->connect_errno}) {$mysqli->connect_error}";
exit;
}
$sql = "SELECT DiaryOpmerkingen, DiaryDoctorcomment FROM tblDiary
WHERE fk_UserId = ?
AND DiaryDay = ?";
$stmt = $mysqli->prepare($sql);
if(!$stmt) {
// Let the user know the query failed!
}
$stmt->bind_param('is', $p_iUserid, $this->Day);
$stmt->execute();
$stmt->bind_result($diaryOpmerkingen, $diaryDoctorcomment);
$dim = array();
while ($stmt->fetch()) {
$dim[$diaryOpmerkingen][$diaryDoctorcomment] = array($diaryOpmerkingen, $diaryDoctorcomment);
}
$stmt->close();
$mysqli->close();
Using Standard MySQL
$sql = "select DiaryOpmerkingen, DiaryDoctorcomment from tblDiary
WHERE fk_UserId = ".$p_iUserid."
AND DiaryDay = '".$this->Day."';";
Only selecting columns you need. Very good. However since we're already using double quotes, we don't need the concatenation operator. Also it's a good idea to break out SQL keywords from column and values consistently:
$sql = "SELECT DiaryOpmerkingen, DiaryDoctorcomment FROM tblDiary
WHERE fk_UserId = $p_iUserid
AND DiaryDay = '{$this->Day}'";
Onward:
$rResult = mysqli_query($link, $sql);
You're mixing up the $link and $sql parameters, and also mixing mysqli and mysql series of functions up. Also unless you have another connection somewhere else, you can just use $sql as the sole parameter:
$rResult = mysql_query($sql);
Now you're returning the result:
return $rResult;
but by doing the the next pieces of code don't get called, so we can get rid of that. Finally we loop through the results:
$dim = array();
while ( $row = mysql_fetch_assoc($rResult) )
{
$dim[$row['DiaryOpmerkingen']][$row['DiaryDoctorcomment']] = $row;
}
Here's the final code:
// Make sure $this->Day is sanitized if it's user input data
$day = mysql_real_escape_string($this->Day);
$sql = "SELECT DiaryOpmerkingen, DiaryDoctorcomment FROM tblDiary
WHERE fk_UserId = $p_iUserid
AND DiaryDay = '$day'";
$rResult = mysql_query($sql);
if(!$rResult) {
//Do something with the error
}
$dim = array();
while ( $row = mysql_fetch_assoc($rResult) )
{
$dim[$row['DiaryOpmerkingen']][$row['DiaryDoctorcomment']] = $row;
}
Check out this page, for some sql functions 5 useful PHP functions for MySQL data fetching
Try:
while ( $r = mysql_fetch_assoc($result) )
$dim[$r['day']] = ["DiaryOpmerkingen" => $r['DiaryOpmerkingen']], 'DiaryDoctorcomment' => [$r['DiaryDoctorcomment']];
$i=0;
while ( $row = mysql_fetch_assoc($result) )
{
extract($row);
$arr[$i]=$DiaryOpmerkingen;
$i++;
$arr[$i]=$DiaryDoctorcomment;
$i++;
}
Please try this code

Categories