Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

PHP CRUD Operations with PHP Reading and Writing Reports Summarizing Project Time

Using next() is causing a PHP Notice.

When I add the conditional:

if ( next($tasks)['project_id'] != $item['project_id'] ) {

I get a PHP Notice that reads:

Notice: Trying to access array offset on value of type bool

It seems like when calling the next() function in the conditional it doesn't just check the next array item, but actually moves the pointer to the next array item. When this happens the next($tasks) variable becomes a boolean and not an array and calling the 'project_id' key on the boolean is causing the notice.

Any advice on why this is happening will be greatly appreciated.

Here is the full code from my reports.php file for reference:

<?php
require 'inc/functions.php';

$page = "reports";
$pageTitle = "Reports | Time Tracker";
$filter = 'all';

if( !empty($_GET['filter']) ) {
  $filter = explode(':', filter_input(INPUT_GET, 'filter', FILTER_SANITIZE_STRING));
}

include 'inc/header.php';
?>
<div class="col-container page-container">
    <div class="col col-70-md col-60-lg col-center">
        <div class="col-container">
            <h1 class='actions-header'>Reports on <?php
            if(!is_array($filter)) {
              echo "All Tasks by Project";
            } else {
              echo ucwords($filter[0]) . " : ";
              switch ($filter[0]) {
                case 'project':
                  $project = get_project($filter[1]);
                  echo $project['title'];
                  break;
                case 'category':
                  echo $filter[1];
                  break;
                case 'date':
                  echo $filter[1] . " - " . $filter[2];
                  break;
              }
            }
            ?></h1>
            <form class="form-container form-report" action="reports.php" method="get">
              <label for="filter">Filter:</label>
              <select id="filter" name="filter">
                <option value="">Select One</option>
                <optgroup label="Project">
                  <?php
                  foreach( get_project_list() as $item ) {
                    echo '<option value="project:' . $item['project_id'] . '">';
                    echo $item['title'] . "</option>\n";
                  }
                  ?>
                </optgroup>
                <optgroup label="Category">
                  <option value="category:Billable">Billable</option>
                  <option value="category:Charity">Charity</option>
                  <option value="category:Personal">Personal</option>
                </optgroup>
                <optgroup label="Date">
                  <option value="date:<?php
                    echo date('m/d/Y', strtotime('-2 Sunday'));
                    echo ":";
                    echo date('m/d/Y', strtotime('-1 Saturday'));
                  ?>">Last Week</option>
                  <option value="date:<?php
                    echo date('m/d/Y', strtotime('-1 Sunday'));
                    echo ":";
                    echo date('m/d/Y');
                  ?>">This Week</option>
                  <option value="date:<?php
                    echo date('m/d/Y', strtotime('first day of last month'));
                    echo ":";
                    echo date('m/d/Y', strtotime('last day of last month'));
                  ?>">Last Month</option>
                  <option value="date:<?php
                    echo date('m/d/Y', strtotime('first day of this month'));
                    echo ":";
                    echo date('m/d/Y');
                  ?>">This Month</option>
                </optgroup>
              </select>
              <input class="button" type="submit" value="Run">
            </form>
        </div>
        <div class="section page">
            <div class="wrapper">
                <table>
                  <?php
                  $total = $project_id = $project_total = 0;
                  $tasks = get_task_list($filter);
                  foreach($tasks as $key => $item) {
                    if ($project_id != $item['project_id']) {
                      $project_id = $item['project_id'];
                      echo "<thead>\n";
                      echo "<tr>\n";
                      echo "<th>" . $item['project'] . "</th>\n";
                      echo "<th>Date</th>\n";
                      echo "<th>Time</th>\n";
                      echo "</tr>\n";
                      echo "</thead>\n";
                    }
                    $project_total += $item['time'];
                    $total += $item['time'];
                    echo "<tr>\n";
                    echo "<td>" . $item['title'] . "</td>\n";
                    echo "<td>" . $item['date'] . "</td>\n";
                    echo "<td>" . $item['time'] . "</td>\n";
                    echo "</tr>\n";

                    if ( next($tasks)['project_id'] != $item['project_id'] ) {
                      echo "<tr>\n";
                      echo "<th class='project-total-label' colspan='2'>Project Total</th>\n";
                      echo "<th class='project-total-number'>$project_total</th>\n";
                      echo "</tr>\n";
                      $project_total = 0;
                    }
                  }
                  ?>
                    <tr>
                        <th class='grand-total-label' colspan='2'>Grand Total</th>
                        <th class='grand-total-number'><?php echo $total; ?></th>
                    </tr>
                </table>
            </div>
        </div>
    </div>
</div>

<?php include "inc/footer.php"; ?>

3 Answers

Jennifer Nordell
seal-mask
STAFF
.a{fill-rule:evenodd;}techdegree
Jennifer Nordell
Treehouse Teacher

Hi there, Zane DeVault! The next() function points to the next value in an array. The Notice that you are getting is trying to tell you that when you get to the end of the array, there won't be a next. It will be essentially false. So at that point, you would be trying to access the key of a boolean. Imagine trying to do false['id']. It's not going to work, because false is a boolean.

A notice is not necessarily an error. It's trying to tell you that something could go wrong, but that doesn't mean it will. There are three "levels" in of potential errors. There are errors. These are the most severe and must be corrected. There are warnings which is the mid-range. And there are notices, which is the lowest severity.

Typically, you can disable notices on the server for just this reason. A notice is only telling you that something could be wrong... not necessarily that something is wrong :smiley:

Hope this helps! :sparkles:

Thanks Jennifer. So it is totally safe and would be fine to just ignore this Notice, since it's a notice for something that we are expecting to happen?

Jennifer Nordell
seal-mask
.a{fill-rule:evenodd;}techdegree
Jennifer Nordell
Treehouse Teacher

Zane DeVault that's exactly right. We're expecting to get to the end of the array at some point and for the next element to not exist :smiley:

if you want to get rid of this error just to keep the interface clean, you can add this code to the top of your reports.php page right under the opening PHP tags

error_reporting(E_ALL & ~E_NOTICE);

Thanks for the tip Abdulrahman Al Ani!

Mine is coming up as a Warning so added below to stop it showing. is it ok to stop the warning? php7.

error_reporting(E_ALL & ~E_WARNING);