This question already has an answer here:
How to get column names from PDO's fetchAll result?
(1 answer)
Closed 2 years ago.
The following code works perfectly well unless there is only one result, in which case only the <tr> containing the column names displays in the web page. Further, a search for the name 'Bracker' produces the result as described above but a search for 'Bra' works correctly while 'Brac' does not. The same does not apply to the name 'Dawe' which, if there is only one result, only appears amongst many others when a search for 'Da' is undertaken.
<?php
include 'connect.php';
if (isset($_POST['submit-keyword'])) {
$keyword = ($_POST['keyword']);
$qry = "SELECT * FROM Ely_NBR WHERE Founder LIKE ? ORDER BY DATE";
$stmt = $con->prepare($qry);
$stmt->execute(["%$keyword%"]);
print "<table>";
$result = ($stmt);
//return only the first row (we only need field names)
$row = $result->fetch(PDO::FETCH_ASSOC);
print " <tr>";
foreach ($row as $field => $value){
print " <th>$field</th>";
} // end foreach
print " </tr>";
//second query gets the data
$data = ($stmt);
$data->setFetchMode(PDO::FETCH_ASSOC);
foreach($data as $row){
print " <tr>";
foreach ($row as $name=>$value){
print " <td>$value</td>";
} // end field loop
print " </tr>";
} // end record loop
print "</table>";
}
?>
You are using your first result row to display the column headings. When you call PDOStatement::fetch() it moves its internal cursor on the result set.
Therefore your loop to display the data starts printing the results from the 2nd row.
See PDOStatement::fetch() documentation: Fetches the next row from a result set.
If you want to get the column names you may want to look at:
PDOStatement::columnCount()
PDOStatement::getColumnMeta()
And print headings like this:
for ($i = 0; $i < $stmt->columnCount(); $i++) {
$columnInfos = $stmt->getColumnMeta($i);
echo '<th>' . $columnInfos['name'] . '</th>';
}
Related
The code below works as written provided a name in the database is entered in the search box. If a name not in the data base is entered, the error 'Warning: Invalid argument supplied for foreach() ….. on line 201.' Rather than this generic error I want something like “No Results” to display. Any suggestions anyone? I am aware that this question has been asked before but none of the answers seem to match the type of output I am using here.
enter code here
<?php
include 'connect.php';
if (isset($_POST['submit-keyword'])) {
$keyword = $_POST['keyword'];
}
try {
//first pass just gets the column names
print "<table>";
$result = $con->query("SELECT * FROM Bath_Wells_NBR WHERE Founder LIKE '%$keyword%' ORDER BY DATE");
//return only the first row (we only need field names)
$row = $result->fetch(PDO::FETCH_ASSOC);
print " <tr>";
foreach ($row as $field => $value){
print " <th>$field</th>";
}
// end foreach
print " </tr>";
//second query gets the data
$data = $con->query("SELECT * FROM Bath_Wells_NBR WHERE Founder LIKE '%$keyword%' ORDER BY DATE");
$data->setFetchMode(PDO::FETCH_ASSOC);
foreach($data as $row){
print " <tr>";
foreach ($row as $name=>$value){
print " <td>$value</td>";
} // end field loop
print " </tr>";
} // end record loop
print "</table>";
} catch(PDOException $e) {
echo 'ERROR: ' . $e->getMessage();
} // end try
?>
the first thing you need to do is make use of the PDO object and actually use the prepared statement to avoid sql injection like this:
$keyword = '%' . $keyword . '%';
$q = $con->prepare("SELECT * FROM Bath_Wells_NBR WHERE Founder LIKE :keyword ORDER BY DATE");
$q->bindParam(':keyword',$keyword,PDO::PARAM_STR);
$q->execute();
//here we will use fetchAll to get the full dataset of results, or an empty array
$result = $q->fetchAll();
Now you have $result which is an array either of your data, or empty so you can solve your problem by saying:
if(count($result) < 1) {
//output an error message
} else {
//output your table
}
Now you have your solution, let's streamline the code a bit. Remember, programmers want DRY code, so we don't want to do the same query twice. Lets assume our result count was greater than 0 so we are inside our else block.
{
//get all the array keys from the first entry in the result. These are the column names from the database which we want to use for our headings
$headings = array_keys($result[0]);
//now we want to do the same thing to each element, i.e. wrap it in html tags so let's make use of array_walk. We use the & symbol to pass the values by reference so we can amend them
array_walk($headings, function(&$field, &$key) {
$field = <th>$field</th>
});
//so now we have an array of table headings, so lets quickly implode them, we don't want to write a whole loop for this
echo <tr> . implode('',$headings) . </tr>;
now you can do your original loop and just output the values hey presto, dryer simpler code! You could also try and experiment with array_walk_recursive and see if you can do the same to the values for your nested loop, after all you just want to wrap them in <td> tags!
Note, I've not tested this so code, but you should be able to use it pretty much as it is, just have a little play and experiment with it.
happy coding!
So i want to get all records of a specific field in a table using mysql database
so far i tried this but it only echos the first ever record in that field
$query = ("SELECT txtpath,txtname FROM txtdocs WHERE subject='$ref'");
$result = mysql_query($query);
$count = mysql_num_rows($result);
//iterate over all the rows
while($row = mysql_fetch_assoc($result)){
//iterate over all the fields
foreach($row as $key => $val){
//generate output
echo $key . ": " . $val . "<BR />";
}
}
Also yes i have more than 1 record in my database
Edit: I added 1 more row so i can have a total of 3 rows, but it's only showing me 2 out of 3 records now.
I think this will work!
//$dbname= 'your connection to database';
$result = mysqli_query($dbname, 'SELECT txtpath,txtname FROM txtdocs WHERE subject="'.$ref.'"');
$count = mysqli_num_rows($result);
//iterate over all the rows
while($row = mysqli_fetch_assoc($result)){
echo $row['txtpath'] . ': ' .$row['txtname']. '<br/>';
}
No need to use loop inside the loop:
while($row = mysql_fetch_assoc($result))
{
echo $row["txtname"] . ": " . $row["txtpath"]. "<br/>";
}
UPDATE 1:
If value if $ref is ENGLISH than your query must return three records not two. Now you need to debug further NY checking the column value maybe you have some space around column value like " ENGLISH".
UPDATE 2:
Further more execute your SELECT query in phpmyadmin and check how many rows return.
SELECT txtpath,txtname FROM txtdocs WHERE subject="English";
Side note:
Please use mysqli_* or PDO instead of mysql_* its deprecated and not available in PHP 7.
I am pretty sure that you can't explain and can't listen. I guess:
You have 3 records in table now, yes?
Before You had 2 records and displays only one.
Next you added new record and displays 2 of 3.
In your SQL query you have WHERE statement => I guess that record which not displayed does not satisfy the condition.
The easiest way to check this is dump/echo $count.
Can you display this? If result is 2 I am right, if not we can think further.
UNFORTUNATELLY people don't think yourself, just ask and lose your time and other.
If you want to display all record of a specific field in a table, you have to remove "where" condition because if condition contain only one column in table then it will be display only one record.
$query = ("SELECT txtpath,txtname FROM txtdocs");
$result = mysql_query($query);
$count = mysql_num_rows($result);
//iterate over all the rows
while($row = mysql_fetch_assoc($result)){
//iterate over all the fields
foreach($row as $key => $val){
//generate output
echo $key . ": " . $val . "<BR />";
}
}
Hi I would like to compare two tables from two different databases.
Select from the first database
$sql= mysqli_query ("SELECT * FROM emasa.staff_detail");
$row = mysqli_fetch_array($sql);
Select from the second database
$sql2 = mysqli_query ("SELECT * FROM employee");
$row2 = mysqli_fetch_array($sql2);
Then I compare the two table
if ($row['icnum'] == $row2['emp_ic'])
{
echo "Data already exist in both database.";
}
else
{
while ($row = mysqli_fetch_assoc($sql))
{
echo "<td align='center' height='30'>" . $row ['name'] . "</td>";
echo "<td align='center'>" .$row['icnum'] . "</td>";
}
}
But my problem is it only compares the first row in the database.
My output should only display the staff name that is not available in the other database. However, this is my output.
Based on the output it only compares the first row. So how do I change my code so that it compares the whole row. Please help me, thank you!
You're not looping through the results of the query. You're simply getting back the first row and going with that.
Ex:
$sql= mysqli_query ("SELECT * FROM emasa.staff_detail");
This is returning a result set which you then need to use
$row = mysqli_fetch_array($sql);
to get the actual values. The problem comes when
$row = mysqli_fetch_array($sql);
by itself only gives you one row.
Solution 1
You must use code like this:
while($row = mysqli_fetch_array($sql))
{
//Do some comparison
}
Since you're going to have to loop through two different result sets, you're going to have to do a loop within a loop, build an array of results and then loop through the results afterwards to output your HTML.
Ex:
while($row = mysqli_fetch_array($sql))
{
while($row2 = mysqli_fetch_array($sql2))
{
if ($row['icnum'] == $row2['emp_ic'])
{
//add to array of equal data
}
else
{
//add to array of not equal data
}
}
}
foreach($array as $not_equal_or_equal_data)
{
//output your desired HTML
}
Solution 2
Depending on what you actually care about, you could do a sql statement like this
$sql = "
SELECT
*
FROM
emasa.staff_detail AS sd
JOIN db2.employee AS e
ON sd.icnum = e.emp_ic";
This would return all the rows where those two columns were equal
Basically what I'm doing is storing everything from my table into an array.
After that I go through it and select row by row and assign it to an array.
Then it goes through that array and puts it in the table, cell by cell, in a single row.
Now the last column of my table are links and they are the fourth and last column in the table and in the database. They're, just like they should, showing up as plain text, but I'd rather have them clickable (For ease of use).
Since the entire table (Except for the, in this case, 4 header items) is created by php code I would have no clue on how to change just the last bit to be a link.
Help would really be appreciated!
Code:
$sql = "SELECT * FROM Future_Mods";
$result = mysqli_query($conn, $sql) or die (mysql_error());
echo "<table>";
echo "<tr>
<th>ID</th>
<th>Mod</th>
<th>Is Available</th>
<th>Has Been Added</th>
<th>Reason</th>
</tr>";
for($i = 0; $i < mysqli_num_rows($result); $i++) {
echo "<tr>";
$row_array = mysqli_fetch_row($result);
for ($j = 0; $j < mysqli_num_fields($result); $j++) {
echo "<td>" .$row_array[$j]. "</td>\n";
}
}
echo "</table>";
Relatively simple:
while ($row = mysqlI_fetch_row($result)) {
end($row); // move array pointer to end of array
$key = key($row); // get key of current pointer element
// update last item to be a link
$row[$key] = '', $row[$key], '';
// dump out array as table cells
echo '<td>', implode('</td><td>', $row), '<td>';
}
This is a question of HTML formatting for your result set table.
If you happen to have a php variable $s that you are sure contains a URL, you can display the URL and make it clickable with php code like this:
echo sprintf ('$1', $s);
For example if $s has the value http://stackoverflow.com/ this will yield the HTML text
http://stackoverflow.com/
One of your $row items will contain that URL. So you can render it with this sort of patten.
Currently, $selection outputs the following: MIN(Bale_ID), MIN(Incoming_Moisture) which is exactly what it should be outputting (they're names from another table). However, when I put $selection into the mysql_query $data1, it seems to just be reading the last value (MIN(Incoming_Moisture)) and only displays the results for that. How do I get the query to read the entire array of elements in $selection? Thank you!!
while ($row1 = mysql_fetch_array($fieldnames1)) {
$fields = $row1['fields1'];
$explode = explode(',',$fields);
if ($row1) {
for ($i=0; $i<$minrows; $i++) {
if ($i<$minrows-1){
$comma = ", ";
}
else {
$comma = "";
}
//$selection = "MIN(".$explode[$i].")".$comma;
//echo $selection;
$data1 = mysql_query("SELECT MIN(".$explode[$i].")".$comma." from data WHERE (fchmitimestamp LIKE CONCAT(#year,'%',#month,'%',#day,'_________'))");
$all1 = mysql_num_fields($data1); //return # of columns; for some reason is returning "1" right now.
while ($row2 = mysql_fetch_array($data1)) {
for ($col=0; $col<$all1; $col++) {
echo $all1;
echo "<td>Min: " . $row2[$col] . "</td>";
}
echo "</tr>";
}
}
}
}
echo "</table>";
Look at the order of operations in your code:
loop {
... fetch data ...
... assign results to $data1 ...
}
Nowhere in your loop do you output or save the results you've got in $data1, so each iteration of the loop overwrites the results of the previous iteration - in other words, only the LAST iteration's results will be stored.
you are running the query once per for loop cycle (1 field at a time) and since first ones yields in SQL error because of the trailin comma, these will not be echoed except the last one.
-- notice the error in first query
SELECT MIN(Bale_ID), from data WHERE (fchmitimestamp LIKE CONCAT(#year,'%',#month,'%',#day,'_________'))
SELECT MIN(Incoming_Moisture) from data WHERE (fchmitimestamp LIKE CONCAT(#year,'%',#month,'%',#day,'_________'))
use var_dump($selection) instead of echo $selection to see yourself