PDO subquery using variable within a loop - php

I am trying to write a query within a While loop using a dynamic variable but can't seem to get it working correctly. I am new to PDO so I'm not 100% if this is even the correct way to go about doing this. The connection to the database ($db) works fine, and the query runs fine without the second $STH2 lines. Please help :)
<?php
//This will list player info so the user can get the correct player ID
$STH = $db->query('SELECT id, name, tag from wdlTeams');
//Setting the fetch mode
$STH->setFetchMode(PDO::FETCH_ASSOC);
//Create listbox object and populates options with team names
echo "<select name='teamID'>";
while($row = $STH->fetch()) {
$id = $row['id'];
$name = $row['name'];
$tag = $row['tag'];
$seasonId = $row['seasonId'];
$STH2 = $db->prepare('SELECT name from wdlSeasons where id=$seasonId');
$STH2->execute();
$seasonName = $STH2->fetchColumn();
echo "<option value='$id'>$tag - $name ($seasonName)</option>";
echo "<br />";
}
echo "</select>";
?>
I have also tried changing to
$STH2 = $db->prepare("SELECT 'name' from 'wdlSeasons' where id='$seasonId'");
but with no luck

Try this:
$STH2 = $db->prepare('SELECT name from wdlSeasons where id=:id');
$STH2->bindParam(':id', $seasonId);
$STH2->execute();

Related

Why does my while loop seems to always be false

I've been trying to make my php code to show entries from my mysql database. I wanted to make it automatic in a sense that i wouldn't need to print the tables manually instead they would be printed according to an alogrythm, but it doesn't work like intended.
I've tried different ways of setting up the table but none of them worked, the furthest I got was to print one entry from the table, and spitting errors after it.
$base = $_POST["base"];
$connection = mysqli_connect("localhost","login","pass") or die("Impossible to connect to the database!");
$db = mysqli_select_db($connection, "database")or die("Impossible to download the database!");
$sql = "SELECT * FROM $base";
$mysqli_result = mysqli_query($connection, $sql);
$sql2 = "SHOW COLUMNS FROM $base";
$set1 = mysqli_query($connection, $sql2);
$colu = array();
while($db = mysqli_fetch_row($set1)){
$colu[] = $db[0]; }
$columns=implode("<br/>",$colu);
echo "<TABLE BORDER=1>";
echo "<TR><TH>$colu[0]</TH><TH>$colu[1]</TH><TH>$colu[2]</TH><TH>$colu[3]</TH><TH>$colu[4]</TH><TH>$colu[5]</TH></TR>";
while ($row = mysqli_fetch_array($set1)) {
$colu[0] = $row["echo $colu[0]"];
$colu[1] = $row["echo $colu[1]"];
$colu[2] = $row["echo $colu[2]"];
$colu[3] = $row["echo $colu[3]"];
$colu[4] = $row["echo $colu[4]"];
$colu[5] = $row["echo $colu[5]"];
echo "<TR><TD>$colu[0]</TD><TD>$colu[1]</TD><TD>$colu[2]</TD><TD>$colu[3]</TD><TD>$colu[4]</TD><TD>$colu[5]</TD></TR>";}
echo "</TABLE>";
mysqli_free_result($mysqli_result);
mysqli_close($connection); ?>
the $_POST[$base]; part works, Im guessing the issue is in the while loop as it doesnt complete once, and I'm lost as to why it doesnt want to work.
I see some problems in you script. If you want to fetch columns as heading and the content for the table body you are using the wrong result sets.
// next line make it possible to do sql insertion, and what if $base has no input?
$base = $_POST["base"];
// the die will never be reached
$connection = mysqli_connect("localhost","login","pass") or die("Impossible to connect to the database!");
$db = mysqli_select_db($connection, "database")or die("Impossible to download the database!");
// where is this query for?
$sql = "SELECT * FROM $base";
// where is this result being used
$mysqli_result = mysqli_query($connection, $sql);
$sql2 = "SHOW COLUMNS FROM $base";
$set1 = mysqli_query($connection, $sql2);
$colu = [];
// what if the table order chages? Best to use mysqli_fetch_assoc
while($db = mysqli_fetch_row($set1)){
$colu[] = $db[0];
}
// where do you use $comumns?
$columns = implode("<br/>", $colu);
echo "<TABLE BORDER=1>";
echo "<TR><TH>$colu[0]</TH><TH>$colu[1]</TH><TH>$colu[2]</TH><TH>$colu[3]</TH><TH>$colu[4]</TH><TH>$colu[5]</TH></TR>";
// you already fetched all record from set1
while ($row = mysqli_fetch_array($set1)) {
$colu[0] = $row["echo $colu[0]"];
$colu[1] = $row["echo $colu[1]"];
$colu[2] = $row["echo $colu[2]"];
$colu[3] = $row["echo $colu[3]"];
$colu[4] = $row["echo $colu[4]"];
$colu[5] = $row["echo $colu[5]"];
echo "<TR><TD>$colu[0]</TD><TD>$colu[1]</TD><TD>$colu[2]</TD><TD>$colu[3]</TD><TD>$colu[4]</TD><TD>$colu[5]</TD></TR>";
}
echo "</TABLE>";
mysqli_free_result($mysqli_result);
mysqli_close($connection); ?>
This biggest issue you have right now is this:
$base = $_POST["base"]
$sql = "SELECT * FROM $base";
$sql2 = "SHOW COLUMNS FROM $base";
This is a huge SQL Injection vulnerability, even if they pass just an empty string to this it's all bad. For example that would result in a query error and depending on your settings on the server and for error reporting, you may expose quite a bit of info. Just one example is a stack trace could contain DB passwords etc.
Instead of directly using user input make a whitelist like this:
$tables = ['user', 'user_meta', 'states']; //etc
$base = !empty($_POST["base"]) && false !== ($index = array_search($_POST["base"], $tables)) ? $tables[$index] : false;
if(!$base) die('Unknown table '.$_POST["base"]);
This way you are only using data you know the value of.
Variable reuse
Other then that, your variable names are causing a bunch of "code confusion". This is what happens if you have to generic of a variable name. Some examples:
$db = mysqli_select_db(...)
while($db = mysqli_fetch_row($set1)){ //overwriting db
...
}
//....................
while ($row = mysqli_fetch_array($set1)) {
$colu[0] = $row["echo $colu[0]"]; //overwriting $colu
This last one is also wrong because the row key will be something like:
$colu[0] = $row["echo name"];
Or something with a column name. Because you are re-using this variable ("variable confusion" ) on the next loop it will be the value of $row["echo $colu[0]"]; which will get put back into that. So lets assume this is correct without the echo and will use Name as the value.
//loop 1
$colu[0] = 'name';
$row['name'] = 'Tom';
//result
$colu[0] = 'Tom'
//loop 2
$colu[0] = 'Tom';
$row['Tom'] doesn't exist.
//result
$colu[0] = null; //undefined index warning
Cursor Reuse
You are also reusing the DB cursor $set1 and looping over it 2 times. I'm not sure about MySqli, but PDO won't allow you to do that. This is probably why the second loop is failing. I believe the second one should be $mysqli_result. It's a bit confusing because you do both queries then loop though one then the other. Instead of doing a query, looping through it. Then doing the other, and looping though that.
Instead you can do something like this:
//you can even query the DB for the table names
$tables = ['user', 'user_meta', 'states']; //etc
$base = !empty($_POST["base"]) && false !== ($index = array_search($_POST["base"], $tables)) ? $tables[$index] : false;
if(!$base) die('Unknown table '.$_POST["base"]);
$connection = mysqli_connect("localhost","login","pass") or die("Impossible to connect to the database!");
$db = mysqli_select_db($connection, "database")or die("Impossible to download the database!");
//---------query for the columns
$sql = "SHOW COLUMNS FROM `$base`";
$mysqli_result = mysqli_query($connection, $sql);
$columns = [];
while($row = mysqli_fetch_row($mysqli_result)){
$columns[] = $row[0];
}
//---------query for the data
//use the column result in the select part of query, because the column names
//come from the DB they are safe to use.
$sql = "SELECT `".implode('`,`', $columns)."` FROM `$base`"; //reuse sql (no longer needed)
$mysqli_result = mysqli_query($connection, $sql); //reuse results (no longer needed)
//fetch all data as assoc array. because we tied it to the results
//of the first query, the column names. We no longer need to map it.
$data = mysqli_fetch_all($mysqli_result, MYSQLI_ASSOC);
///output table and headers
echo "<table>";
echo "<thead>";
echo "<tr>";
//we can just loop over the columns and put them in the table head
foreach($columns as $key ){
echo "<th>$key</th>";
}
echo "</tr>";
echo "</thead>";
echo "<tbody>";
//loop over each row of data
foreach($data as $row){
echo "<tr>";
//loop over each "correlated" column
foreach($columns as $key ){
echo "<td>{$row[$key]}</td>";
}
echo "</tr>";
}
echo "</tbody>";
echo "</table>";
BONUS For getting the table names from the DB:
$sql = 'SELECT `TABLE_NAME` FROM `information_schema`.`TABLES` WHERE `TABLE_SCHEMA` LIKE "'.$database.'"';
$mysqli_result = mysqli_query($connection, $sql);
$tables = mysqli_fetch_all($mysqli_result, MYSQLI_NUM);
Hope that makes sense.

how grab field value from a PHP query (PDO)

Super new to PHP here, only using PHP to create my json data and having a hard time to understand the syntax. Here is some partial code:
All I am trying to do is to retrieve the value '2af8ddda-2be4-11e5-9453-b82a72d52c35' and put it in variable #sharepointID:
function selectWithSharepointID($table, $columns, $where){
try{
//Get Sharepoint file ID first
$stmt = $this->db->prepare("SELECT ID FROM table1 ORDER BY DownloadedTimeStamp DESC LIMIT 1");
$stmt->execute();
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
//$data[] = array("ID" => $rows['ID']);
//$sharepointID = $data[0];
//$sharepointID = $rows[0];
$where = array('id'=>$sharepointID);
//$where = array('id'=>'2af8ddda-2be4-11e5-9453-b82a72d52c35'); //this works fine
...
PS: also tried to use print_r and echo but cant see anything in the console.
Thank you
You don't need to fetchAll if you only have one record. Try:
$stmt = $this->db->prepare("SELECT ID FROM table1 ORDER BY DownloadedTimeStamp DESC LIMIT 1");
$stmt->execute();
$row = $stmt->fetch(PDO::FETCH_ASSOC);
$sharepointID = $row['ID'];
If you have multiple records the fetchAll makes sense but then you iterate through that to get each row, and its values.
For a rough example where I'd use fetchAll...
$stmt = $this->db->prepare("SELECT name, userid FROM users");
$stmt->execute();
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
foreach($rows as $row){
echo 'Name: ' . $row['name'] . ' userid :' . $row['id'];
}
This expression returns array of rows:
$stmt->fetchAll(PDO::FETCH_ASSOC);
So, you can get data from row 0 in your case:
$sharepointID = $rows[0]['ID'];

values are not being returning from the database PHP

new here and I am at my wits end with this problem. The pretence is simple; I am trying to select a user id from the database BASED on a value from a session cookie. I have confirmed that the SQL works as I have run it through sql itself, and the only thing I can think of is that it's not executing or my fetch or bind is wrong.
<?php
session_start();
$cart = $_SESSION["cart"];
try{
require "connect.php";
$id = "SELECT id_no FROM eCustomer WHERE surname = :uid";
echo $id . '<br />';
$idfetch=$dbh->prepare($id);
$idfetch->bindValue(":uid", $_SESSION["uid"]);
$idfetch->execute();
$customer_id = $idfetch["id_no"];
echo $customer_id;
$dbh=null;
} catch (PDOExeption $e){
echo $e;
}
?>
This should echo to my browser
SELECT id_no FROM eCustomer WHERE surname = :uid
1
But it's only outputting
SELECT id_no FROM eCustomer WHERE surname = :uid
I have also tried putting the session variable directly into the sql statement without the bindValue
$id = "SELECT id_no FROM eCustomer WHERE surname = '" . $_SESSION["uid"] . "'";
Which outputs to my browser
SELECT id_no FROM eCustomer WHERE surname = 'Mclellan'
(Mclellan being in my session cookie)
Any help would be greatly appreciated.
You have actually executed the statement, but you haven't actually ->fetch()ed it yet. You missed that part:
$results = $idfetch->fetchAll(PDO::FETCH_ASSOC);
// print_r($results);
foreach($results as $row) {
echo $row['id_no'];
}
Sidenote:
If you only require one row, then a single ->fetch() invocation should suffice:
$row = $idfetch->fetch(PDO::FETCH_ASSOC);
echo $row['id_no'];
It looks like you are missing the actual fetching of the results
you would need a line like below following your $idfetch->execute();
$customerid = $idfetch->fetch(PDO::FETCH_ASSOC);
after that your echo $customerid["id_no"]; should work.
The reason being is that all you have had php do is execute the query without telling it to fetch the results from the query.
Also, the above is for using PDO as that is what it looks like you are using. If you are using mysqli then this probably wont help.

printing the value of a query using php

I'm trying to print out the value of a query but what appears on the screen is the query itself!
mysql_select_db($database_databasestudents, $databasestudents);
$result = mysql_query("Select name from country where id = '$s';",$databasestudents);
$r = mysql_fetch_array($result) ;
echo $r;
where $s is an integer
This is what I get on the screen:
SELECT name FROM country WHERE id='3'
3 is the value of $s
You need to run the query first
http://www.php.net/manual/en/mysqli.query.php
and then loop though the results
http://www.php.net/manual/en/mysqli-result.fetch-array.php
You need to run the query in order to get the result. Maybe this will get you started:
$pdo = new PDO('mysql:host=YOURHOST;port=YOURPORT;dbname=YOURDB', 'YOURUSER', 'YOURPASSWORD');
$sql = 'SELECT name FROM `country` WHERE id=?';
$stmt = $pdo->prepare($sql);
$stmt->execute(array($s));
while ($result = $stmt->fetchObject())
{
echo $result->name;
}
$r is an array, not a string. You need print_r($r); or var_dump($r);, not echo
You have created a string containing your query.
You must instantiate a database connection and then execute your query.

Dropdown menu , displaying two columns but only when clicked

I have a drop down menu populated from a mysql database , is it possible to display two columns from the database but only when clicked ?
By this I mean, when you click you see a list of items on the left and a brief description on the right. The description column should only be visible when clicking on the dropdown.
Is this possible ?
My code is as follow, this queries the DB to check the current selection for the user.
I have tried adding a second column but it shows at all times which looks terrible.
<?php
require_once('db_connect.php');
$id = $_GET['id'];
$qry = "SELECT issue FROM issuetbl WHERE issueid =?";
$stmt = $mysqli->prepare($qry);
$stmt->bind_param('s', $id);
$stmt->execute();
$result = $stmt->get_result();
$client_result = $result->fetch_assoc();
$qry2 = "SELECT data FROM issdd";
$stmt = $mysqli->prepare($qry2);
$stmt->execute();
$resultdata = $stmt->get_result();
echo '<select name="enqiss">';
while($row = $resultdata->fetch_assoc()) {
if($client_result['issue']==$row['data']){
$selectCurrent='selected';
}else{
$selectCurrent='';
}
echo '<option value="'.$row['data'].'" '.$selectCurrent.'>'.$row['data'].'</option>';
}
echo '</select>';
?>
Many thanks

Categories