<p>This is totally normal and expected behavior. In fact, it's critical for some looping situations, and pretty standard across programming languages. Wouldn't you expect to find this same behavior in PHP?</p>

<p>Think about situations where previous loops build on each other. Here's an example of a situation where loop values <strong>need</strong> to be retained...</p>

<pre class="lang-html prettyprint-override"><code>{% set totalPets = 0 %}

{% for petOwner in craft.entries.section('petOwners').find %}

    {% set totalPets = totalPets + petOwner.numberOwned %}

{% endfor %}

&lt;p&gt;This group of people owns {{ totalPets }} pets total.&lt;/p&gt;
</code></pre>

<p>Ultimately, this is a simple scope issue. Generally speaking, <code>for</code> loops don't exist in their own scope... they are a part of the scope created by the parent script.</p>

<p>If you want to ensure that your logic takes place in a <strong>separate scope</strong>, take a look into <a href="http://twig.sensiolabs.org/doc/tags/macro.html" rel="nofollow">Twig macros...</a> A macro would probably be very helpful in your situation.</p>

CC BY-SA 3.0
2015-03-25T18:07:33.033Z
Sorry, you're right. I guess I was confused about scope. I was thinking that for blocks were scoped like functions but of course they're not. I'll try using a macro instead.
MarkPlewis
CC BY-SA 3.0
2015-03-26T07:40:25.490Z
According to Twig's documentation here: http://twig.sensiolabs.org/doc/tags/set.html variables inside a for loop in Twig is indeed scoped. Is this wrong?
Alf Vestre
CC BY-SA 3.0
2015-03-26T17:14:23.063Z
Good catch @AlfVestre! Looks like my scope answer is a half-truth. I said "generally speaking", because I knew that [the `loop` variable](http://twig.sensiolabs.org/doc/tags/for.html#the-loop-variable) couldn't exist outside of the loop. I didn't realize that loops are considered an entirely separate scope (which obviously inherit the context of the parent script). Regardless, _within_ the loop you'd still be dealing with a single scope... it wouldn't be refreshed every time the loop cycles through.
Lindsey D
CC BY-SA 3.0
2015-03-26T17:49:41.623Z
_"it wouldn't be refreshed every time the loop cycles through"_ That's true, but I'm not sure the `totalPets` variable in your answer will work if it is not declared outside (before) the `for`loop? I know this is not what the OP asked about, but since the comments brought up the behaviour of scoping I felt it was worth mentioning :)
Alf Vestre
CC BY-SA 3.0
2015-03-26T17:53:00.190Z
Another good catch. :)  I had originally defined `totalPets` outside of the loop, but felt it didn't properly address the OP's question. However, you're right... If defined this way, it won't be accessible after the loop ends. I'll go ahead and change the example, thanks!
Lindsey D
CC BY-SA 3.0
2018-01-03T01:03:08.850Z
@LindseyD I'm coming up against this problem as well but resetting to null doesn't seem to work and  I'm struggling to understand how I can use a macro to fix it. Would you be able to point me to an example of how this would work with a macro please?
patrick.altair
CC BY-SA 3.0
2018-01-03T05:47:29.327Z
@patrick.altair Sounds like a separate question, I'd recommend [asking a new question](https://craftcms.stackexchange.com/questions/ask). Feel free to link back to this thread if you feel it's relevant.
Lindsey D
CC BY-SA 3.0
2018-01-03T12:27:58.600Z
I eventually got the reset to null working, seemed a {% cache %} was the problem for me but thanks @LindseyD
patrick.altair
CC BY-SA 3.0
2015-03-25T17:20:41.540Z
2015-03-26T17:54:52.863Z
2015-03-26T17:54:52.863Z
Lindsey D
<p>Is anyone able to tell me why variables which I've defined inside of a for loop are persisting and retaining their values on into consecutive iterations? In order to overcome this, I've had to set them back to null each time. I'm relatively new to Craft and Twig but this seems like a bug. Has anyone else experienced this?</p>

<pre><code>    {% for entry in entries %}

      {# I shouldn't have to set these to null for each loop iteration, #}
      {# but they seem to be retaining their values #}

      {% set photo = null %}
      {% set width = null %}
      {% set height = null %}
      {% set orientation = null %}

      {% if entry.photo | length %}
        {% set photo = entry.photo.first() %}
        {% set width = photo.width %}
        {% set height = photo.height %}
        {% set orientation = '' %}

        {% if width &gt; height %}
          {% set orientation = 'landscape' %}
        {% elseif height &gt; width %}
          {% set orientation = 'portrait' %}
        {% elseif width == height %}
          {% set orientation = 'square' %}
        {% endif %}
      {% endif %}

      &lt;article class="entry{% if orientation %} {{ orientation }}{% endif %}"&gt;
        {% if entry.photo | length %}
          &lt;img src="{{ photo.getUrl('small') }}" width="{{ photo.getWidth('small') }}" height="{{ photo.getHeight('small') }}" alt="{{ photo.title }}"&gt;
        {% endif %}
      &lt;/article&gt;

    {% endfor %}
</code></pre>

<variable><forloop><loop>
Why are variables persisting inside of my for loop?
# Why are variables persisting inside of my for loop?

(Asked by: username_0 on 2015-03-25)

Is anyone able to tell me why variables which I've defined inside of a for loop are persisting and retaining their values on into consecutive iterations? In order to overcome this, I've had to set them back to null each time. I'm relatively new to Craft and Twig but this seems like a bug. Has anyone else experienced this?
    {% for entry in entries %}

      {# I shouldn't have to set these to null for each loop iteration, #}
      {# but they seem to be retaining their values #}

      {% set photo = null %}
      {% set width = null %}
      {% set height = null %}
      {% set orientation = null %}

      {% if entry.photo | length %}
        {% set photo = entry.photo.first() %}
        {% set width = photo.width %}
        {% set height = photo.height %}
        {% set orientation = '' %}

        {% if width > height %}
          {% set orientation = 'landscape' %}
        {% elseif height > width %}
          {% set orientation = 'portrait' %}
        {% elseif width == height %}
          {% set orientation = 'square' %}
        {% endif %}
      {% endif %}

      
        {% if entry.photo | length %}
          
        {% endif %}
      

    {% endfor %}

**Tags:** variable, forloop, loop


---

## 1 answers

### Answer by username_1 on 2015-03-25. Score: 5 | Accepted answer

This is totally normal and expected behavior. In fact, it's critical for some looping situations, and pretty standard across programming languages. Wouldn't you expect to find this same behavior in PHP?
Think about situations where previous loops build on each other. Here's an example of a situation where loop values need to be retained...
{% set totalPets = 0 %}

{% for petOwner in craft.entries.section('petOwners').find %}

    {% set totalPets = totalPets + petOwner.numberOwned %}

{% endfor %}

This group of people owns {{ totalPets }} pets total.

Ultimately, this is a simple scope issue. Generally speaking, for loops don't exist in their own scope... they are a part of the scope created by the parent script.
If you want to ensure that your logic takes place in a separate scope, take a look into Twig macros... A macro would probably be very helpful in your situation.

> **Comments:**
> **username_0**: Sorry, you're right. I guess I was confused about scope. I was thinking that for blocks were scoped like functions but of course they're not. I'll try using a macro instead.  
> **username_2**: According to Twig's documentation here: http://twig.sensiolabs.org/doc/tags/set.html variables inside a for loop in Twig is indeed scoped. Is this wrong?  
> **username_1**: Good catch @AlfVestre! Looks like my scope answer is a half-truth. I said "generally speaking", because I knew that [the `loop` variable](http://twig.sensiolabs.org/doc/tags/for.html#the-loop-variable) couldn't exist outside of the loop. I didn't realize that loops are considered an entirely separate scope (which obviously inherit the context of the parent script). Regardless, _within_ the loop you'd still be dealing with a single scope... it wouldn't be refreshed every time the loop cycles through.  
> **username_2**: _"it wouldn't be refreshed every time the loop cycles through"_ That's true, but I'm not sure the `totalPets` variable in your answer will work if it is not declared outside (before) the `for`loop? I know this is not what the OP asked about, but since the comments brought up the behaviour of scoping I felt it was worth mentioning :)  
> **username_1**: Another good catch. :)  I had originally defined `totalPets` outside of the loop, but felt it didn't properly address the OP's question. However, you're right... If defined this way, it won't be accessible after the loop ends. I'll go ahead and change the example, thanks!  
> **username_3**: @LindseyD I'm coming up against this problem as well but resetting to null doesn't seem to work and  I'm struggling to understand how I can use a macro to fix it. Would you be able to point me to an example of how this would work with a macro please?  
> **username_1**: @username_3 Sounds like a separate question, I'd recommend [asking a new question](https://craftcms.stackexchange.com/questions/ask). Feel free to link back to this thread if you feel it's relevant.  
> **username_3**: I eventually got the reset to null working, seemed a {% cache %} was the problem for me but thanks @LindseyD  

---

