PHP - Count how many results are displayed in foreach - php

With the foreach loop, I wanna count how many results are displayed. For example, if it's displaying
Jack Ane
Steve Jobs
Sara Bill
I want to echo that there are 3 results.
Likewise, if it's like
Marc Kil
Bill Smith
I want to echo that there are 2 results.
It's a bit tricky for me becasue this is my code:
<div>
<?php
$container = array();
if (is_array($row))
{
foreach ($row as $data) {
if(!isset($container[$data->first_name . $data->last_name])) {
$container[$data->first_name . $data->last_name] = $data;
echo $data->first_name . " " .$data->last_name . "</div>";
}
}
}
?>
</p>
</div>
How exactly would I be able to do that? Since these values are coming straight from the database, I was thinking of doing a database count but there are duplicate values in the database since I'm logging the views of users with the first and the last name. So when I try to do it, say for example there are 20 Jack Ane in my database. Then it shows me all of the 20 Jack Ane's instead of just one because I just want it once.
Sorry if it's confusing.
Thanks.

I traditional use the count() to do that if you dont use any :
foreach ($row as $data) {
if(!isset($container[$data->first_name . $data->last_name])) {
$container[$data->first_name . $data->last_name] = $data;
echo $data->first_name . " " .$data->last_name . "</div>";
}
}
echo "Results: " . count($row);
Hope that help you.

I suggest you to rewrite your query. If you will do this in right way, you will get faster solution, with no needs to new array and unnecessary "isset" checks.
The reason you get duplicated data from query may be:
1 - Wrong query logic
2 - Query is OK, but you need to use DISTINCT or GROUP BY to remove duplicates
If you use PDO, you can then get number of returned rows just by using rowCount() method
$sql="SELECT * from table WHERE blablabla";
$result = $this->db->query($sql);
$result->rowCount(); // here
Then you can fetch $result->fetchAll(); and print data.

You can to do a SELECT DISTINCT or a GROUP BY across the two columns to have the database do the work and eliminate the duplicate checking in your PHP. To do this you can use something like the following:
SELECT DISTINCT first_name, last_name FROM users;
SELECT first_name, last_name FROM users GROUP BY first_name, last_name;
DISTINCT is more succinct while GROUP BY supports more flexibility.
In your example, since you are building an associative array, you can just do a count() after the loop, but you will have cleaner code if you have the database do it:
$count = count($container);

You could do an easy variable that increments inside your foreach that gives you the exact count, then use the variable to create actions depending on it's value. Because if you count the container and you wish to filter out the results inside the container, you won't get the filtered amount.
<?php
$container = array();
if (is_array($row))
{
$count = 0;
foreach ($row as $data) {
if(!isset($container[$data->first_name . $data->last_name])) {
$container[$data->first_name . $data->last_name] = $data;
echo $data->first_name . " " .$data->last_name . "</div>";
$count++;
}
}
}
if ($count > 0) {
echo "There were $count results.";
}
?>

use:
echo "Results: " . count($container);

Related

Updating a 4th table using 3 different tables

I've got 3 different tables and I want to update the 4th table with some specific column from each of the 3 tables, they all have a common key. I can do this from the phpmyadmin, but I want to do it using a php script.
This is what I tried but it didn't work
if (isset($_GET)) {
$update = '';
$count="SELECT * FROM test2 ";
foreach ($connect->query($count) as $row) {
$term_total1=$row['english'];
$sql = "UPDATE total set `f_test` ='$term_total1' ";
foreach ($connect->query($count) as $row) {
echo "success<br>" . $term_total1;
}
}
}else{
echo "try another method" . mysqli_error($connect);
}
Have been trying for days now.
Repeated the same code for the other two tables but it won't work.
Is it possible to do it in a single query? If Yes, then how
I'm pretty sure your method of using foreach to loop the result set is incorrect. In your updated code you've also not got a unique identifier so your code is just going to mass update your table. Here's your current code fixed up so hopefully you can understand how to loop the dataset from mysqli
$count="SELECT * FROM test2";
if($res = $connect->query($count)){
while($row = $res->fetch_assoc()){
$term_total1 = $row['english'];
$sql = "UPDATE total set `f_test` = '{$term_total1}'";
if($res2 =$connect->query($sql)){
echo "success<br>" . $term_total1;
}else{
print_r($connect->error());
}
}
}else{
print_r($connect->error());
}

How to break zero index comma separated value into individual string in php

I want to break comma seperated values which are retrieved from database and then put each individual in a string and print it in a for loop only. I am getting the values from database but i am not be able to break values. Below is the code what i have done right till now.Please help to solve my issue. Thanks in advance.
$query="select * from create_segment";
$result = mysql_query($query,$link) or die(mysql_error());
$number_of_segment=mysql_num_rows($result);
while($row=mysql_fetch_assoc($result))
{
$segments[]=$row;
}
foreach($segments as $success) {
$thePostIdArray = explode(', ', $success['subjects']);
for($i=0; $i < count($thePostIdArray); $i++)
{
echo "string...".$strings=$thePostIdArray[$i];
}
}
It output:
string...1,2,3,4,5,6,7,8,9,10
string...1,2,3,4,5,6,7,8
but i want something like this:
for(......)
{
echo "values...".$i;
}
which should output
values...1
values...2
values...3 and so on.
my database structure is like:
id subjects
1 1,2,3,4,5
2 1,2,7
Please try to use ',' instead of ', ' in your
explode(', ', $success['subjects']);
statement so it would look like:
explode(',', $success['subjects']);
Use:
explode(',', $success['subjects'])
You had a space after the comma, but there are no spaces in the database values.
If you have the opportunity to change the database structure you should convert that table into something like this:
Id Subject
1 1
1 2
1 3
2 1
etc.
It will make your queries much easier, and it the right way to go. It will also make it easier for you in the future do join this table with other tables to get the desired results. I know this doesn't answer your questions, but some good advice will never hurt. One of the other answers will answer your question directly.
$query="select * from create_segment";
$result = mysql_query($query,$link) or die(mysql_error());
$number_of_segment=mysql_num_rows($result);
while($row = mysql_fetch_assoc($result))
{
foreach (explode(',',$row['subjects']) as $value){
echo echo "string... {$row['id']} " . $value . '<br />';
}
}

While inside a while

I'm trying to count how many times a hashtag is mentioned in the database. So first while is getting all the hashtags, and the second is inside the other while to count how many times the hashtag is mentioned. But the problem is that the numbers isn't getting along correct, it is just showing 1,2,3,4,5.. etc, and when there is a hashtag mentioned two times it's showing i.e. 3+4.
How can I solve this?
$i = 0;
$popular_hashtags_query = mysql_query("SELECT * FROM " . $dbPrefix . "hashtags WHERE status=1");
while ($popular_hashtags = mysql_fetch_array($popular_hashtags_query)) {
echo "<div class='hashtag_label'><a data-hover='";
$count_hashtags_query = mysql_query("SELECT * FROM " . $dbPrefix . "hashtags WHERE status=1 AND hashtag='" . $popular_hashtags['hashtag'] . "'");
while ($count_hashtags = mysql_fetch_array($count_hashtags_query)) {
$i++;
echo $i;
}
echo "'><span>#".$popular_hashtags['hashtag'] . "</span></a></div>";
}
I suggest to use mysqli or PDO. in this case group by hashtag in the query is better way and not need to extra query and loop so.
$popular_hashtags_query = mysql_query("
SELECT
`hashtag`, count(*) AS `count`
FROM `" . $dbPrefix . "hashtags` WHERE `status` = 1 GROUP BY `hashtag`
");
while ($popular_hashtags = mysql_fetch_array($popular_hashtags_query)) {
echo "<div class='hashtag_label'><a data-hover='";
echo $popular_hashtags['count'];
echo "'><span>#" . $popular_hashtags['hashtag'] . "</span></a></div>";
}
There are a bunch of problems with your code. First, the mysql_ functions are deprecated and will eventually be removed from php entirely, so you should move over to mysqli_ functions or a PDO.
Second, your actions on $i are in the wrong place. You should be resetting $i = 0 as the first action inside the first loop, or else it's just going to count up the total number of times ANY hashtag is used.
Third, you're echoing $i inside the second while loop, which means every time the loop runs, you're going to be forever echoing increasing numbers. The echo should be outside the inner loop, after you've counted up the instances of the hashtag.
And finally, you can actually accomplish all of this with one loop by executing "SELECT hashtag, count(*) FROM " . $dbPrefix . "hashtags WHERE status=1 group by hashtag"
There's no need to loop over all records in a table to do the same thing again.
What you want is to use an aggregate function in you SQL query.
Something like the following:
SELECT hashtag, COUNT(hashtag)
FROM hashtags
GROUP BY hashtag

Sql query only printing first row

I am coding in php and the code takes data from an array to fetch additional data from a mysql db. Because I need data from two different tables, I use nested while loops. But the code below always only prints out (echo "a: " . $data3[2]; or echo "b: " . $data3[2];) one time:
foreach($stuff as $key)
{
$query3 = "SELECT * FROM foobar WHERE id='$key'";
$result3 = MySQL_query($query3, $link_id);
while ($data3 = mysql_fetch_array($result3))
{
$query4 = "SELECT * FROM foobar_img WHERE id='$data3[0]'";
$result4 = MySQL_query($query4, $link_id);
while ($data4 = mysql_fetch_array($result4))
{
$x += 1;
if ($x % 3 == 0)
{
echo "a: " . $data3[2];
}
else
{
echo "b: " . $data3[2];
}
}
}
}
First and foremost, improve your SQL:
SELECT
img.*
FROM
foobar foo
INNER JOIN foobar_img img ON
foo.id = img.id
WHERE
foo.id = $key
You will only have to iterate through one array.
Also, it appears that you're actually only selecting one row, so spitting out one row is expected behavior.
Additionally, please prevent yourself from SQL injection by using mysql_real_escape_string():
$query3 = "SELECT * FROM foobar WHERE id='" .
mysql_real_escape_string($key) . "'";
Update: As Dan as intimated, please run this query in your MySQL console to get the result set back, so you know what you're playing with. When you limit the query to one ID, you're probably only pulling back one row. That being said, I have no idea how many $keys are in $stuff, but if it spins over once, then it will be one.
You may be better off iterating through $stuff and building out an IN clause for your SQL:
$key_array = "";
foreach($stuff as $key)
{
$key_array .= ",'" . mysql_real_escape_string($key) . "'";
}
$key_array = substr($key_array, 1);
...
WHERE foo.id IN ($key_array)
This will give you a result set with your complete list back, instead of sending a bunch of SELECT queries to the DB. Be kind to your DB and please use set-based operations when possible. MySQL will appreciate it.
I will also point out that it appears as if you're using text primary keys. Integer, incremental keys work best as PK's, and I highly suggest you use them!
You should use a JOIN between these two tables. It the correct way to use SQL, and it will work much faster. Doing an extra query inside the loop is bad practice, like putting loop-invariant code inside a loop.

When listing information from a database using php and mysql how would you make the first row look different to the rest?

Basically I have articles in my database and I want to alter the way the first record displays. I want the lastest (Posted) article to be the focus and the older article just to list, (see F1.com). I need to know how to get the first of my values in the array and get it to display differently but I am not sure how to do this, I can do it so all rows display the same just not how to alter the first row. I also need to know how to tell the rest of the rows to display the same afterwards im guessing you use an if statement there and before that some kind of count for the rows.
Current code:
$result = mysql_query("SELECT * FROM dbArticle WHERE userID='".$_SESSION["**"]."' ORDER BY timestamp DESC");
while($row = mysql_fetch_array($result))
{
echo "<h2 class=\"heading1\">". $row['title'] ."</h2>";
echo "By: ".$row['username']." Type: ".$row['type']." Posted: ".$row['timestamp']."
$body = $row['body'];
echo "<br/><p>";
echo substr("$body",0,260);
echo "...<span class=\"tool\"><a class=\"blue\" href=\"index.php?pageContent=readArticle&id=".$row['id']."\">Read More</a></span></p><hr/>";
}
mysql_close($con);
Ok I have taken Luke Dennis's code and tried to test it, but I am getting this error: Warning: Invalid argument supplied for foreach() this is the line of the foreach statment. Something that has just come to mind is that I will only want 5 or so of the older articles to display. This is what I have thats creating the error:
<? $con = mysql_connect("localhost","****","***");
if (!$con)
{
die('Could not connect: ' . mysql_error());
}
mysql_select_db("******", $con);
$result = mysql_query("SELECT * FROM dbArticle ORDER BY timestamp DESC");
$first = true;
foreach($result as $row){
if($first)
{
echo"".$row['title']."";
echo"this is the headline";
$first = false;
}
else
{
echo"".$row['title']."";
}
}
?>
Do I need to add mysql_fetch_array somewhere to set the array up?
I would just iterate through the results and apply a css class to the first entry:
$first = true;
while ($row = mysql_fetch_assoc($result)) {
$cssClass = '';
if ($first) {
$cssClass = 'highlight';
}
echo '<p class="' . $cssClass . '">' . $row['text'] . '</p>';
$first = false;
}
It's a bit crude, but I often hard-code a variable to designate the first run through a loop. So something like:
$first = true;
foreach($list_of_items as $item)
{
if($first)
{
// Do some stuff
$first = false;
}
else
{
// Do some other stuff
}
}
A simple if statement when looping through your results will usually do the trick. You can use a boolean to indicate if you've output the first row of results or now. If you haven't then give it a particular style and then set the boolean to true. Then all subsequent rows get a different style.
All of the above are correct. Luke Dennis' post is of course fleshed-out a bit more.
As Brian Fisher said, add some CSS styling to the first link when you encounter it per Luke's post.
I took a look at the article list on the F1 website. Pretty well constructed site - "One would expect that." :-)
Anyway, the article listings are contained within a two row table (summary="Latest Headlines") in descending order (newest first).
Just place a class in the second column (<td class="first-news-article">). Then add the class name and appropriate styling values in the css file - probably your' modules.css. There's already quite a few class values associated with articles in that file, so you may be able to just use an existing value.
That should be about it - other than actually doing it!
By the way, judging by the quality of the underlying html, I'm assuming there's already an "article list emitter." Just find that emitter and place the appropriate conditional to test for the first record.
Darrell
I just noted your code addition. I assume that you were showing the F1 site as an example. Anyway, I think you're on your way.
I presume you have some code that loops through your resultset and prints them into the page? Could you paste this code in, and that might give us a starting point to help you.
I don't know PHP, so I'll pseudocode it in Perl. I wouldn't do it like this:
my $row_num = 0;
for my $row ($query->next) {
$row_num++;
if( $row_num == 1 ) {
...format the first row...
}
else {
...format everything else...
}
}
The if statement inside the loop unnecessarily clutters the loop logic. It's not a performance issue, it's a code readability and maintainability issue. That sort of thing just BEGS for a bug. Take advantage of the fact that it's the first thing in the array. It's two different things, do them in two different pieces of code.
my $first = $query->next;
...format $first...
for my $row ($query->next) {
...format the row...
}
Of course, you must make the first row stand out by using tags.
I'd use array_shift():
$result = mysql_fetch_assoc($resultFromSql); // <- edit
$first = array_shift($result);
echo '<h1>'.$first['title'].'</h1>';
foreach ($result as $row) {
echo '<h2>'.$row['title'].'</h2>';
}
The best way to do this is to put a fetch statement prior to the while loop.
Putting a test inside the while loop that is only true for one iteration can be a waste of time for a result of millions of rows.

Categories