PHP can't fetch last id inserted correctly - php

I have two possible solutions for my my probrem i want to echo last id inserted to know how many people fill the form, but it affects the data on the table below. Note: this doesn't affect the database itself, just the output from the browser.
connect.php
#$db = new mysqli('127.0.0.1', 'blop', 'blop', 'blop');
if ($db->connect_errno) {
die ('Sorry, we are having some problems.');
}
displaying the results:
function returnData() {
global $db;
echo ('<style> td {border: 1px solid #000; background:#ed8043;} th {border:1px solid #000; background:#fff</style>
<table style="width:100%; text-align:center;">
<tr>
<th>Line</th>
<th>id</th>
<th>Name</th>
<th>Email</th>
<th>Visited</th>
</tr>');
$result = $db->query("SELECT * FROM `people` ORDER BY `created` DESC");
$count = $result->num_rows;
echo 'Number of visits: ' .$count.'<br><br>';
/*$visits1 = $result->fetch_assoc();
echo $visits1['id']. '<br>';
$visits2 = $db->insert_id;
echo $visits2. '<br>';*/
$row_num = 1;
while ($row = $result->fetch_object()) {
echo ('
<tr>
<td>' .$row_num. '</td>
<td>' .$row->id. '</td>
<td>' .$row->first_name. '</td>
<td>' .$row->mail. '</td>
<td>' .$row->created.'</td>
</tr>'
);
$row_num++;
}
echo ('</table><br>');
$result->free();
}
The problem is that when i try like this: 1.
$result = $db->query("SELECT * FROM `people` ORDER BY `created` DESC");
$visits1 = $result->fetch_assoc();
echo $visits1['id']. '<br>';
i actualy have one more id than what appears on the table like the image below show:
As you can see i have "756" witch is fine, because it's the last id inserted but i don't want the respective row (with the id 756), it disapeared from the table below it. When i coment the code above it works fine the first row is the last id inserted.
I have an alternative code to resolve this, the problem is this doesn't work either: 2.
$result = $db->query("SELECT * FROM `people` ORDER BY `created` DESC");
$visits2 = $db->insert_id;
echo $visits2. '<br>';
This time the table it's correct, it shows all rows but the number of total id's it's 0.

That's what fetch_* methods are doing, and that's what you need so you can iterate over them. It's simple logic of programming loops. To execute a function n times, you put it in a loop, or call it manually n times. You call it manually one time, so you have already fetched the first item from this resultset. Putting it in a while() loop will fetch the remaining elements from the resultset.
To avoid this, you'd better switch to already fetched resultset and manipulate over it.
Right now, you are breaking the single responsibility principle, because returnData gets data, makes HTML and so on.
Make a function getData() with the query, and then use it with foreach to get all the resultset.
Use it only once to get the last Id (first).
function getData() {
global $db;
$result = $db->query("SELECT .......");
while ($row = $result->fetch_object()) {
$rows[] = $row;
}
return $rows;
}
Now in returnData() you can use
getData()[0]->id
To fetch the last id, as you can also iterate through the method without losing the resultset:
foreach (getData() as $data) {
echo $data->id;
}
You'd better make function for each thing you will need in this application. Fetching the last id, fetching the whole resultset, getting the rowcount, etc. It's rarely good practice to make it from a single query/method.
To be honest, there are a lot of issues to be fixed in your code, starting from global variables, ending to dropping the functional/procedural style in favor of OOP

Try to use:
SELECT `AUTO_INCREMENT`
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'blop'
AND TABLE_NAME = 'people';

In the first example, you should not do the second 'fetch_...' straight away. That's because you're discarding the first row, you've already fetched.
A quick (untested, sorry for typos) fix below:
...
$row = $result->fetch_object();
echo $row->id. '<br>';
$row_num = 1;
while ($row_num == 1 || $row = $result->fetch_object()) {
echo ('
<tr>
<td>' .$row_num. '</td>
<td>' .$row->id. '</td>
<td>' .$row->first_name. '</td>
<td>' .$row->mail. '</td>
<td>' .$row->created.'</td>
</tr>'
);
$row_num++;
}
...

From php documentation:
The mysqli_insert_id() function returns the ID generated by a query on a table with a column having the AUTO_INCREMENT attribute. If the last query wasn't an INSERT or UPDATE statement or if the modified table does not have a column with the AUTO_INCREMENT attribute, this function will return zero.
So SELECT queries do not return the last inserted id.
In general this query should work for the last row of a table ordered by a column:
select column_name from table_name order by column_name desc limit 1;
For id you can also use:
select LAST_INSERT_ID() from table;
which doesn't force you to make an INSERT or UPDATE query before this query.

Related

Display dynamic Table in php/HTML from SQL Query [duplicate]

I created table in php and want to show only some of column names in this table. I used SHOW Statement, but it shows all columns. This is my code:
$result = mysqli_query($con, "SHOW COLUMNS FROM habits ");
if ($result->num_rows > 0) {
// output data of each row
while ($row = $result->fetch_assoc()) {
echo '<tr>
<td scope="row">' .$row['Field'].'</td>
</tr>';
}
}
How can show only some of them ? Does anybody know the solution?
By the way, SELECT Statement doesn't work for this code. It shows this:
Notice: Undefined index: Field
in:\xampp\htdocs\diagnoVisProject\HabitsPharmacotherapies.php on line 70
If you know the names of the columns you'd want to show you could add an array with those names. Then before you print a row you'd verify if the name of the column is in the array. If it isn't you don't print the row.
Something like this:
$result = mysqli_query($con, "SHOW COLUMNS FROM habits ");
$allowedColums = ["column1", "column2", "etc."];
if ($result->num_rows > 0) {
// output data of each row
while ($row = $result->fetch_assoc()) {
if (in_array($row['Field'], $allowedColums)) {
echo '<tr>
<td scope="row">' . $row['Field'] . '</td>
</tr>';
}
}
}
You can use
SELECT column_name FROM information_schema.tables WHERE table_name = 'habits' AND (column_name='your column 1' OR column_name='your column 2')
But I'm not sure what would youdo with it if you already know the column name

Displaying individual data from a count query(mySQL/php)

I have a database called 'Telcel' and a table called 'calls'
columns in my table are id,call_from,call_to,date_time,duration,network,cost,status
I have the following code:
$conn = mysqli_connect("localhost", "daven", "H3x^g0n", "Telcel");
$query = "SELECT id, COUNT(id), call_from,ROUND(SUM(cost), 2) FROM calls GROUP BY call_from ORDER BY COUNT(id) DESC;";
$result = mysqli_query($conn, $query);
while($row = mysqli_fetch_assoc($result))
{
echo '
<tr>
<td>'. $row['call_from'] .'</td>
<td>'. $row['COUNT(id)'] .'</td>
<td>'. $row['ROUND(SUM(cost), 2)'] .'</td>
</tr>
';
}
which returns for example:
Call From Calls Cost
Shannon 10 50.2
Tom 3 7.6
I'd like when a name is selected to display all the calls, duration for each call and cost of each call made by the selected caller on the next page,So if Tom is selected display all the relevant information for Tom only, and if Shannon is selected same thing etc. Thank you.
You can sent GET requrest with url like total.php?call_from=Tom
So, you need to generate a href link with call from name :
while($row = mysqli_fetch_assoc($result)) {
<td>'. $row['call_from'] .'</td>
...
}
And total.php use $_GET["call_from"] for receiving id from url to use in query :
$call_from = $_GET["call_from"];
$query = "SELECT * FROM calls WHERE call_from = ". $call_from;
... //Display the table
Hope this help :)

How can i show only certain columns of data table in sql?

I created table in php and want to show only some of column names in this table. I used SHOW Statement, but it shows all columns. This is my code:
$result = mysqli_query($con, "SHOW COLUMNS FROM habits ");
if ($result->num_rows > 0) {
// output data of each row
while ($row = $result->fetch_assoc()) {
echo '<tr>
<td scope="row">' .$row['Field'].'</td>
</tr>';
}
}
How can show only some of them ? Does anybody know the solution?
By the way, SELECT Statement doesn't work for this code. It shows this:
Notice: Undefined index: Field
in:\xampp\htdocs\diagnoVisProject\HabitsPharmacotherapies.php on line 70
If you know the names of the columns you'd want to show you could add an array with those names. Then before you print a row you'd verify if the name of the column is in the array. If it isn't you don't print the row.
Something like this:
$result = mysqli_query($con, "SHOW COLUMNS FROM habits ");
$allowedColums = ["column1", "column2", "etc."];
if ($result->num_rows > 0) {
// output data of each row
while ($row = $result->fetch_assoc()) {
if (in_array($row['Field'], $allowedColums)) {
echo '<tr>
<td scope="row">' . $row['Field'] . '</td>
</tr>';
}
}
}
You can use
SELECT column_name FROM information_schema.tables WHERE table_name = 'habits' AND (column_name='your column 1' OR column_name='your column 2')
But I'm not sure what would youdo with it if you already know the column name

php foreach loop SQL table name query

I have this php code to do a query foreach loop going through the table name in variable $rowA but I got an "Array to string conversion" error. Does anyone know why? Can we do a query loop this way?
$sql = "SELECT `id`, `first_name` FROM `clients` ORDER BY `id` DESC";
$result = $DB_CON_C->query($sql);
$sql_email = "SELECT `email` FROM `clients` ORDER BY `id` DESC";
$account = $DB_CON_C->query($sql_email);
foreach($result as $row) {
foreach($account as $rowA) {
$stmt = "SELECT SUM(value) AS total_amount FROM `".$rowA."`";
$amount = $DB_CON_C->query($stmt);
$sum = $amount->total_amount;
$data_row .= '<tr>'
. '<td>' .$row['id'].'</td>'
. '<td>' .$row['first_name'].'</td>'
. '<td>' .$sum.'</td>';
}
}
}
$data_row .= '</tbody>'
. '</table>';
echo $data_row;
There seems to be a fundamentally odd issue with the way you are handling your data values.
Take your first query, $result, this will (obviously depending on the exact $DB_CON_C class method) output an array of values for id and first_name
Yet on the second call, $account using the same method you are then calling the values as if they're class variables $amount->total_amount.
I would suspect that one of these syntax is wrong, but without seeing your class I can't say which.
Do you realise that your two SQL calls are both returning the whole database?
Do you realise that you're using the data value (email address) in one table as the column name in another table? This can work, but this really isn't best practise.
You do not need to use the concaenator . for strings over new lines.
$string = "Hello
this string works fine";
as white space is reduced to one character length in HTML so it doesn't matter (much).
Solving your issue:
var_dump($account) once the value has been populated, same with $results, do var_dump($results) and see what is in the value, if these are class variables or arrays of data?
Seeing that both your variables are calling different parts of the same table, I have rewritten your code below:
$sql = "SELECT `id`, `first_name`, `email` FROM `clients` ORDER BY `id` DESC";
$result = $DB_CON_C->query($sql);
/***
* $result is assumed to be an array, within which is a set of values such as:
* $result[0]['id']
* $result[0]['first_name']
* $result[0]['email']
* $result[1]['id'], etc.
***/
foreach($result as $row) {
$stmt = "SELECT SUM(value) AS total_amount FROM `".$row['email']."`";
$amount = $DB_CON_C->query($stmt);
/***
* this is inconsistent, your data structure must be like $result as it
* uses the same methods, therefore you will need to enter the first
* "row" before getting the 'total_amount' value
***/
$sum = $amount[0]['total_amount'];
$data_row .= '<tr>
<td>' .$row['id'].'</td>
<td>' .$row['first_name'].'</td>
<td>' .$sum.'</td>
</tr>'; //you forgot your /tr !!
}
// Always clean up after foreach loops.
unset($row);
$data_row .= '</tbody>
</table>';
echo $data_row;
You're trying to parse a database row to a string, even though it contains only one thing.
Change the following line
$stmt = "SELECT SUM(value) AS total_amount "
. "FROM `".$rowA."`";
to
$stmt = "SELECT SUM(value) AS total_amount "
. "FROM `".$rowA['email']."`";
$rowA is a database row and contains the email field from the database.

php mysql query whitin While loop

I have a Mysql table which is use in php, first I use while loop to fetched the rows that as below
$q1 = "SELECT * FROM same_table WHERE `t_type`=1 AND `status`=0 AND `accept`='0'";
while($row1 = $q1->fetch_assoc()){
...table to output records
echo '<tr>
<td>$row1['col1']</td>
<td>$row1['col2']</td>
</tr>';
}
this will come out necessary records successfully.
secondly, there is another row with different purpose located under each of the above query row if the condition is true, with same table (within while loop),
while($row1 = $q1->fetch_assoc()){
echo '<tr>
<td>$row1['col1']</td>
<td>$row1['col2']</td>
</tr>';
$q2 = "SELECT * FROM same_table WHERE `t_type`=1 AND `status`=0 AND `bonus_accept`='0'";
$row2 = $q2->fetch_assoc();
if(($row2['col3'] == true){
echo '<tr>
<td>$row2['col1']</td>
<td>$row2['col2']</td>
</tr>';
}
}
so far the $q2 rows is show but always repeat the first record's data only even there is several row for $q1. if the data for $row2['col1'] is 100, the rest all show 100.
Please kindly help.

Categories