Keep getting Invalid argument supplied for foreach() in - php

I keep getting this warning:
Warning: Invalid argument supplied for foreach() in
here is my full code which performe function list output from mysql and paging it 10 output per page , the error appear in last page
<?php
require_once('dbconnect.php');
$yesterday = date("Y-m-d", strtotime("yesterday"));
$page=intval($_POST['p']);
if($page=='')
{
$page=1;
}
$dbadd=($page-1)*10;
$query = "SELECT * FROM ranking";
$totalposts=mysql_num_rows(mysql_query($query));
$totalpages=ceil($totalposts/10);
$query = "SELECT r.ranking,r.screenname,r.name,r.followers,r.tweets,r.location,r.`join date`,r.avatar, h.date, r.followers-h.followers followers_diff, r.tweets-h.tweets tweets_diff FROM ranking r, ranking_hist h WHERE r.screenname=h.screenname and h.date='$yesterday' AND r.ranking>$dbadd AND r.ranking<($dbadd+11) ORDER BY ranking ASC LIMIT 10 ";
$result = mysql_query($query);
if( !$result ) {
die("Error: " . mysql_error() );
}
while($row = mysql_fetch_assoc($result) ) {
$tweep = $row['screenname'];
$tweeps[$tweep] = $row;
}
$query = "SELECT r.ranking,r.screenname,r.name,r.followers,r.tweets,r.location,r.`join date`,r.avatar FROM ranking r WHERE r.screenname NOT IN ( SELECT DISTINCT screenname from ranking_hist ) AND r.ranking>$dbadd AND r.ranking<($dbadd+11) ORDER BY ranking ASC LIMIT 10";
$result = mysql_query($query);
if( !$result ) {
die("Error: " . mysql_error() );
}
while($row = mysql_fetch_assoc($result) ) {
echo "";
$tweep = $row['screenname'];
$tweeps[$tweep] = $row;
}
mysql_free_result($result);
$i = 0;
$total_amount = count($tweeps);
foreach ($tweeps as $tweep) {
$i++;
if ($total_amount == $i) {
$class = 'divrow divrowlast';
} else {
$class = 'divrow';
}
$col5 = "";
if( $tweep['followers_diff'] > 0 ) {
$col5 = "<span style='color:green; display:inline;'> +" . $tweep['followers_diff'] . "▲ </span>";
}
else if( $tweep['followers_diff'] < 0 ) {
$col5 = "<span style='color:red; display:inline;'> -" . $tweep['followers_diff'] . "▼ </span>";
}
$html_table .= '<div class="'.$class.'"><ul>' .
"<li class='row100rank'> " . $tweep['ranking'] . "</li>" .
"<li class='row100user'>
<div class='avatar'><img width='32' height='32' src='" . $tweep['avatar'] . "' alt='" . $tweep['screenname'] ."' /></div>
<div class='feature-author'><a class='text_bigger' href='http://www.twitter.com/" . $tweep['screenname'] . "/'>#".$tweep['screenname']."</a></div>
<div class='row100description'>".$tweep['name']."<br />".$tweep['location']."</div></li>" .
"<li class='pad'><div class='stat'> <span>" . $tweep['followers'] . " $col5</span> followers</div></li>" .
"<li class='pad rowTwitte'><div class='stat'> <span>" . $tweep['tweets'] . " $col6</span> tweets</div></li>" .
"<li class='pad rowJoionDate'><div class='stat'> <span>" . date ( 'd M y', strtotime($tweep['join date'])) . "</span> joindate</div></li>" .
"</ul></div>";
}
echo $html_table;
?>
<div class="dataTables_paginate paging_full_numbers" ><span class="first paginate_button" ><a class="pagelinks" href="javascript:void(0);" pageid="1" onClick="changepage(1);">First</a></span>
<span class="previous paginate_button" ><a class="pagelinks" href="javascript:void(0);" pageid="<?php echo $page>1?($page-1):1;?>" onClick="changepage(<?php echo $page>1?($page-1):1;?>);" >Previous</a></span>
<span>
<?php
switch($page){
case 1:
$it=1;
$itl=6;
break;
case 2:
$it=1;
$itl=6;
break;
case $totalpages:
$it=$totalpages-4;
$itl=$totalpages+1;
break;
case $totalpages-1:
$it=$totalpages-4;
$itl=$totalpages+1;
break;
default:
$it=$page-2;
$itl=$page+3;
}
for(;$it<$itl;$it++){
?>
<span class="<?php echo $page== $it?'paginate_active':'paginate_button'; ?>">
<a class="pagelinks" href="javascript:void(0);" pageid="<?php echo $it;?>" onClick="changepage(<?php echo $it;?>);" ><?php echo $it; ?></a></span>
<?php
}
?>
</span>
<span class="next paginate_button" ><a class="pagelinks" href="javascript:void(0);" pageid="<?php echo $page<$totalpages?($page+1):$page;?>" onClick="changepage(<?php echo $page<$totalpages?($page+1):$page;?>);">Next</a>
</span>
<span class="last paginate_button" >
<a class="pagelinks" href="javascript:void(0);" pageid="<?php echo $totalpages;?>" onClick="changepage(<?php echo $totalpages;?>);">Last</a>
</span></div>
<div class="dataTables_info">
Showing <?php echo ($page-1)*10+1;?> to <?php echo ($page-1)*10+10;?> of <?php echo $totalposts;?>
</div>

Try the code blow. Your $tweeps might on some occasions not be an array or object, check if the array is not empty and is_array($tweeps).
$i = 0;
$total_amount = count($tweeps);
if(is_array($total_amount) && !empty($tweeps))
{
foreach ($tweeps as $tweep)
{
$i++;
if ($total_amount == $i)
{
$class = 'divrow divrowlast';
}
else
{
$class = 'divrow';
}
}
}

Your problem is likely to be that the query isn't retuning any data.
You are populating new entries into the $tweeps array inside the loop, but if there's no data, it won't ever go into that loop.
You aren't initialising the $tweeps variable anywhere else, so if it doesn't go into the loop, $tweeps won't be an array, it'll be undefined. This will then give you an error if you try to use it in a foreach().
You need to add a line to initialise the variable before you start populating it:
$tweeps = array();
This would go somewhere above the loop where you first start populating $tweeps.
Hope that helps.

Related

foreach() Loop Outputting Data and Creating Layout

I am currently trying to create a class schedule which I pull from my Sql Server database with PHP and I am trying to get the layout output as well as the data as I am grouping the resources.
These groupings are nested such as:
-DAY
--TIME
---CLASS
----STUDENTS
And should output like this:
However, I am getting this:
My current output is working, however, it is only on the first loop, then everything goes haywire. I am assuming there is an erroneous </div> tag somewhere in my code yet I cannot for the life of me find it.
My php code is a function that is delcare as such:
<div class="mainScheduleWrapper">
<?php daySchedule(); ?>
</div>
My php code is as such:
function daySchedule() {
global $conn;
$dayScheduleQuery = 'SET DATEFIRST 1
SELECT [DAY].[DAY] AS [DAY], CLASS.CLASSTIME AS CLASSTIME, CLASSLEVEL.CLASSLEVEL AS CLASSLEVEL, CLASS.MAXSTUDENT AS MAXSTUDENT, INSTRUCTOR.FIRSTNAME AS INSTRUCTOR, STUDENT.FIRSTNAME AS STUDENTFIRST, STUDENT.SURNAME AS STUDENTLAST, STUDENT.DOB AS STUDENTDOB
FROM STUDENT JOIN BOOKING ON STUDENT.ID = BOOKING.STUDENTID JOIN CLASS ON CLASS.ID = BOOKING.CLASSID JOIN CLASSLEVEL ON CLASS.CLASSLEVELID = CLASSLEVEL.ID JOIN [DAY] ON CLASS.CLASSDAY = [DAY].ID JOIN INSTRUCTOR ON CLASS.INSTRUCTORID = INSTRUCTOR.ID
WHERE [DAY].ID = (DATEPART(dw, GETUTCDATE() AT TIME ZONE \'AUS Eastern Standard Time\'))
ORDER BY CLASS.CLASSTIME ASC, INSTRUCTOR.FIRSTNAME ASC, CLASSLEVEL.CLASSLEVEL ASC';
// COUNTERS
$t = 0;
$i = 0;
//VARIABLES FOR DAY SCHEDULE
$classDay = NULL;
$classTime = NULL;
$classInstructor = NULL;
$closeClass = false;
$closeAll = false;
$queryConnector = $conn->query($dayScheduleQuery);
foreach ($queryConnector as $schedule) {
// CLASS DAY HEADER
if ($classDay != $schedule['DAY']) {
echo '<div class="grid-1">';
echo '<h1>' . $schedule['DAY'] . '</h1>';
echo '</div><!-- Day closed! -->';
$classDay = $schedule['DAY'];
}
// CLASS TIME HEADER
if ($classTime != $schedule['CLASSTIME']) {
if($classTime != $schedule['CLASSTIME'] && $t > 0) {
$closeAll = true;
goto closeAll;
}
echo '<div class="grid-12-noGutter scheduleContainer">'; //NON-CLOSED
echo '<h1>' . 'T = ' . $t . '</h1>';
echo '<div class="grid-middle-center col scheduleTimeTab">';
// FIX 3 DIGIT MILITARY TIME
if (strlen($schedule['CLASSTIME']) < 4) {
$classScheduleTime = '0' . $schedule['CLASSTIME'];
} else {
$classScheduleTime = $schedule['CLASSTIME'];
}
echo '<p>' . date('g:i A', strtotime($classScheduleTime)) . '</p>';
echo '</div>'; //CLOSE TIME TAB
echo '<div class="innerSchedule">'; // NON-CLOSED
$classTime = $schedule['CLASSTIME'];
$t += 100;
}
// INSTRUCTOR HEADER
if ($classInstructor != $schedule['INSTRUCTOR']) {
if ($classInstructor != $schedule['INSTRUCTOR'] && $i > 0) {
$closeClass = true;
goto closeClassWrapper;
}
echo '<div class="classWrapper">';
echo '<h1>' . 'I =' . $i . 'T = ' . $t . '</h1>';
echo '<div class="grid-3-middle classHeader">';
echo '<div class="col classHeaderCell' . classLevelColour($schedule['CLASSLEVEL']) . '">' . $schedule['CLASSLEVEL'] . '</div>';
echo '<div class="col classHeaderCell">' . $schedule['INSTRUCTOR'] . '</div>';
echo '<div class="col classHeaderCell">Max' . ' ' . $schedule['MAXSTUDENT'] . '</div>';
echo '</div>';
echo '<div class="grid-4-middle" id="studentHeaders">';
echo '<div class="col"><h6>Student Name</h6></div>';
echo '<div class="col"><h6>Student Birthday</h6></div>';
echo '<div class="col"><h6>Class Level</h6></div>';
echo '<div class="col"><h6>Attendance</h6></div>';
echo '</div>';
$classInstructor = $schedule['INSTRUCTOR'];
$i += 100;
}
echo '<div class="grid-4 studentRow">';
echo '<div class="col">';
echo '<span class="studentCell">' . $schedule['STUDENTFIRST'] . ' ' . $schedule['STUDENTLAST'] . '</span>';
echo '</div>';
echo '<div class="col">';
echo '<span class="studentCell">' . $schedule['STUDENTDOB'] . '</span>';
echo '</div>';
echo '<div class="col">';
echo '<span class="studentCell">' . $schedule['CLASSLEVEL'] . '</span>';
echo '</div>';
echo '<div class="col">';
echo '<span class="studentCell">--</span>';
echo '</div>';
echo '</div>';
// GOTO TAGS
closeClassWrapper: {
if ($closeClass === true) {
echo '</div>';
$closeClass = false;
$i = 0;
}
}
closeAll: {
if ($closeAll === true) {
echo '</div>';
echo '</div>';
echo '</div>';
$closeAll = false;
$t = 0;
$i = 0;
}
}
}
}
Any help would be greatly appreciated - even if it's to tell me I'm going about it the completely wrong way.
Kindest Regards
Michael Z
I wouldn't say you're going about it the completely wrong way, but a few red flags jumped out at me in your code.
The use of goto jumping is bad practice. It butchers your program flow and forces you to segregate tasks that shouldn't be kept apart. You marked the sections of code "// NON CLOSED" when there was a </div> missing, is there any purpose for that? How do you know the goto sections are reliable?
When you echo something like <div class="col">, without escaping the double-quotes (as in \" for every " character), it can be problematic. Your code can get mangled or misinterpreted, both on the PHP end or on the HTML end.
Like others have said, the use of PHP may be overkill here. Besides just sending the JSON, the rest could be handled with JavaScript.

function only returns one value multiple times

I have this function:
function get_content($text_to_match) {
$query = "SELECT * ";
$query .= "FROM table_name ";
$query .= "WHERE one_column_name LIKE '%{$text_to_match}%' OR another_column_name LIKE '%{$text_to_match}%'";
$cont = mysqli_query($connection, $query);
if($content = mysqli_fetch_assoc($cont)) {
return $content;
} else {
return null;
}
}
But when I call it like:
<div>
<?php
for ($i = 1; $i < count(get_content("text_to_match")); $i++) {
echo '<article>' .
'<h3>' . get_content("text_to_match")["string1"] . '</h3>'.
'<p>' . get_content("text_to_match")["string2"] . '</p>' .
'</article>';
}
?>
</div>
I only get the first match in the DB repeated as many times as the number of found items.
Where have I gone wrong?
use this code then fetch data properly
while($content = mysql_fetch_array($cont))
{
return $content;
}
Your logic is at fault. You are calling get_content function to get all matches for the loop, as well as to get individual elements out of the list. This is:
bad logic - the 2nd use case doesn't make sense
excessive - you shouldn't need to run a database query just to output an already retrieved result
What you probably want to do is:
foreach (get_content('text_to_match') as $content) {
echo '<article>';
echo '<h3>' . $content['string1'] . '</h3>';
echo '<p>' . $content['string2'] . '</p>';
echo '</article>';
}
With a few modifications in combination with tips from #Anant and #Unix One's answer, I arrived at this working solution:
Function definition
function get_content($text_to_match, $multiple=false) {
$query = "SELECT * ";
$query .= "FROM table_name ";
$query .= "WHERE one_column_name LIKE '%{$text_to_match}%' OR another_column_name LIKE '%{$text_to_match}%'";
$cont = mysqli_query($connection, $query);
if ($multiple) {
$content_array = [];
while($content = mysqli_fetch_array($cont)) {
$content_array[] = $content;
}
return $content_array;
} else {
if($content = mysqli_fetch_assoc($cont)) {
return $content;
} else {
return null;
}
}
}
Function calls
<?php
/* multiple items */
foreach(get_content("text_to_match", true) as $content) {
echo '<article>' .
'<h3>' . $content["string1"] . '</h3>' .
'<p>' . $content["string2"] . '</p>' .
'</article>';
}
?>
<?php
/* one item */
echo get_content("text_to_match")["string"];
?>

Dependency of HTML rendering on function's return value that executes later?

I have a function that prints "Our data" first and then inside a loop checks for all the data in the database and then prints the data.
However, if there is no data, it shouldn't print "Our data", how do I achieve this since "Our data" is already printed?
The layout is as follows :
<h1> Our Data </h1>
<p> <!-- DATA --> </p>
The function is as follows:
function cpt_info($cpt_slug, $field_name, $title) {
echo "<h1>Our" . $title . "</h1>"; //here I want to print our data
$args = array('limit' => -1);
$cpt = pods($cpt_slug, $args);
$page_slug = pods_v('last', 'url');
echo "<h1 class='projects-under-" . $cpt_slug . "'>" . $title . "</h1>";
if ($cpt->total() > 0) :
while ($cpt->fetch()) :
if (!strcasecmp($cpt->field('post_name'), $page_slug)) :
$data = $cpt->field($field_name);
foreach ((array) $data as $key => $value) {
if ($value != null) : //here I check whether data is empty
$url = wp_get_attachment_url(get_post_thumbnail_id($value['ID']));
echo "<div class='col-sm-3 col-xs-6'><div class='border-to-circle'>";
echo "<div class='circle-container' style='background: url(" . $url . ")center center, url(" . get_template_directory_uri() . '/images/rwp-banner.jpg' . ")center center;'><h4><a href='" . get_permalink($value['ID']) . "'>" . $value['post_title'] . "</a></h4></div>";
echo "</div></div>";
endif;
}
endif;
endwhile;
endif;
}
Something like below:
if(count($data)){
echo '<h1> Our Data </h1>';
}

Break If Statement in While loop without breaking the while loop PHP

Ok, So Im creating a while loop for multiple accordions in php. I marked up some php code that ALMOST works. The problem I am having is that I had to nest five different IF statements in a while loop for the five different accordions. The If statements contain the content to be in the accordion. The content is a list of songs in a particular album. What I need to happen is for the If statement containing the content for one accordion to break, but still continue with the original while statement and do this for each accordion. Here is my PHP Code.
if ($result)
{
while ($row = mysqli_fetch_array($result, MYSQLI_ASSOC))
{
echo '<div class="col-small-6 col-med-6 col-lg-4 albumContainer">';
echo '<img src=' . $row['Album_Art'] . 'alt="">';
echo '<div class="panel-group" id="accordion">';
echo '<div class="panel panel-default">';
echo '<div class="panel-heading">';
echo '<h2 class="panel-title"><a data-toggle="collapse" data-parent="#accordion" href=' . $row['direction'] . '>' . $row['Title'] . '</a></h2></div><div id=' . $row['destination'] . ' class="panel-collapse collapse"><div class="panel-body"> <ol>';
if($result1)
{
while ($row1 = mysqli_fetch_array($result1, MYSQLI_ASSOC))
{
echo '<li>' . $row1['Name'] . '</li>';
};
};
if($result2)
{
while($row2 = mysqli_fetch_array($result2, MYSQLI_ASSOC))
{
echo '<li>' . $row2['Name'] . '</li>';
}
};
if($result3)
{
while($row3 = mysqli_fetch_array($result3, MYSQLI_ASSOC))
{
echo '<li>' . $row3['Name'] . '</li>';
}
};
if($result4)
{
while($row4 = mysqli_fetch_array($result4, MYSQLI_ASSOC))
{
echo '<li>' . $row4['Name'] . '</li>';
}
};
if($result5)
{
while($row5 = mysqli_fetch_array($result5, MYSQLI_ASSOC))
{
echo '<li>' . $row5['Name'] . '</li>';
}
};
if($result6)
{
while($row6 = mysqli_fetch_array($result6, MYSQLI_ASSOC))
{
echo '<li>' . $row6['Name'] . '</li>';
}
};
echo '</ol>';
echo '<h3>available at:</h3><a href=' . $row['Location'] . '>iTunes</a>
<a href=' . $row['Location2'] . '>Amazon</a>
<a href=' . $row['Location3'] . '>United Interests</a></div>';
echo '</div></div></div></div>';
}
mysqli_free_result ($result);
}
else
{
echo '<p class="error">The current users could not be retrieved. We apologize for any inconvenience.</p>';
echo '<p>' . mysqli_error($dbcon) . '<br><br />Query: ' . $q . '</p>';
}
mysqli_close($dbcon);
?>
Any insights on how to make this work for me would be greatly appreciated. I cant use Jquery for the accordion because of how the code was previously structured.
use continue http://php.net/manual/en/control-structures.continue.php
continue is used within looping structures to skip the rest of the
current loop iteration and continue execution at the condition
evaluation and then the beginning of the next iteration.
Note: Note that in PHP the switch statement is considered a looping
structure for the purposes of continue.
also, you should probably use a switch instrad of multiple if conditions

PHP while loop split into two

I'm running a while loop which is taking rows from mySQL and echo'ing them out. Pretty standard. However, there needs to be different HTML markup for the first item, next two items, then it continues as normal into the while loop.
Currently, my while loop looking something like this:
while( ( $row = mysql_fetch_object( $result ) ) !== false )
{
// Places ad based of predefined variable frequency
if ($ad == $adFrequency){
echo '<div class="one-advertisement-article clearfix">';
echo '<div class="grid_9 suffix_2"><img src="http://placehold.it/263x75/000000/ffffff"></div>';
echo '<div class="grid_1"><a class="navigate-right-icon ss-icon" href="#">navigateright</a></div>';
echo '</div>';
$ad = 0;
}
echo '<div class="one-news-article clearfix">';
if( $row->imagelibid )
{
$imageid = intval( $row->imagelibid );
$image_result = mysql_query( "SELECT * FROM imagelib WHERE id = {$imageid}", $db );
$image_row = mysql_fetch_object( $image_result );
$image_url = "http://www.#.com/slir/w280/imagelib/" . $image_row->id . "_" . $image_row->filename;
echo '<div class="grid_4"><img src="'.$image_url.'"></div>';
}
else {
echo '<div class="grid_4"><div class="news-placeholder"><span class="ss-icon">ellipsischat</span></div></div>';
}
echo '<div class="grid_7">';
echo '<h2>'.$row->title.'</h2>';
$published_date = date('D, d M Y', strtotime($row->datein));
echo '<p class="published-date">'.$published_date.'</p>';
echo '</div>';
echo '<div class="grid_1">';
echo '<div class="news-item-vertical-sep"> </div>';
echo '<p></p>';
echo '</div>';
echo '</div>';
$ad++;
}
This works fine, but I need to take the first three news items and use this:
echo ' <div class="one-news-featured-article clearfix">';
echo ' <div class="grid_12">';
if( $row->imagelibid )
{
$imageid = intval( $row->imagelibid );
$image_result = mysql_query( "SELECT * FROM imagelib WHERE id = {$imageid}", $db );
$image_row = mysql_fetch_object( $image_result );
$image_url = "http://www.#.com/slir/w280/imagelib/" . $image_row->id . "_" . $image_row->filename;
echo '<div class="large-featured-image-container"><img src="'.$image_url.'">/div>';
}
echo ' <div>';
echo ' <h2>'.$row->title.'</h2>';
echo ' </div>';
echo ' </div>';
echo ' </div>';
echo ' <div class="grid_6">';
Any help? Essentially, it needs to apply the second code to the first three items in the query, then follow through with the code included in the current while loop - like an offset I guess.
Thanks,
R
This is quite simple. I hope I understood your question correctly:
$i = 0;
while ( ( $row = mysql_fetch_object( $result ) ) !== false ) {
if ($i < 3) {
// First code
} else {
// Second code
}
$i += 1;
}
Firstly, you should avoid using any mysql_ functions as they are all deprecated and will be removed from future versions of PHP. I'd recommend using PDO instead. See this tutorial to get started.
Then, it'll simply be a case of doing something like this:
foreach($db->query($query) as $index => $row) {
if ($index < 3) {
// first 3 items
} else {
// other items
}
}
You can do it easaly with an simple counter and an if statement:
$count = 0;
while(fetching) {
if($count < 3) {
// items 1, 2 and 3
} else {
// do normal
}
$count++;
}

Categories