0

In PHP, variables defined in a loop are not local to the loop. Is there any way of destroying/un-setting every variable declared after each iteration?

The trouble comes if I declare a variable in an if statement in a foreach loop. This variable is not necessarily declared on each iteration, so there's the possibility of it hanging around and having the same value as last time, when I want it destroyed!

Specifically, here is my (simplified) code. It parses and events.xml file that contains <event> elements that all have a <startDate> child element, and may or may not have an <endDate> child element, and then forms html showing the events after looping over them all.

<html>

  <?php
  $events = simplexml_load_file("events.xml");
  foreach ($events as $value):
    // get the start date of the current event from the xml file
    $startDate = strtotime($value->startDate);
    // get the end date if it exists (it might not)
    $endDate = strtotime($value->endDate);
    // get day of the week from the start date
    $startDay = date("D", $startDate);
    if ($endDate) {
      $endDay = date("D", $endDate);
      $dash = "-";
    }
  ?>

    <div class="event"> <!-- this is still in the foreach loop -->
      <!-- insert the start day (always) followed by a dash and end day (if they exist) -->
      <?php echo $startDay, $dash, $endDay; ?>
    </div>
  <?php endforeach; ?>

</html>

The problem being, if in the events.xml file, I have an event with an end date followed by an event without an end date, the div for the latter will have the end day from the former (because the $endDay variable was not unset), when I don't want it to have an end date at all. (If there is an event without an end date at the top of the xml file, its div won't have an end date.)

Interestingly, for an event with no end date, the $endDate variable does seem to get destroyed at this line: $endDate = strtotime($value->endDate);, presumably because it tries to read it from the xml and finds nothing. But if I put the $endDay declaration outside of the if statement, then it would go to 01 by default, which I don't want.

1 Answer 1

1

You have to reset the vars on your own. They are all visible in the current scope and loops or conditions dont have their own var scope.

In your case you have to reset $dash and $endDay on each iteration - i.e.

  foreach ($events as $value):
      $dash = null;
      $endDay = null;
      //...
  ?>

$startDate and $endDate are overwritten in each iteration. If $value->start/endDate is unset or an invalid date, they will become false as value.

Sign up to request clarification or add additional context in comments.

3 Comments

I'd have to reset $endDay as well. But why set equal to null as opposed to unset($dash)?
the difference between unset and $var = null doesn't matter in your case - you could use both. Using unset just also removes $var from the symbol table
The $endDate var gets overriden in each iteration - apply an invalid date to strtotime will result in false as return value.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.