Possible memory leak in PHP script

- 1 answer

Ad

I'm developing a web app using OctoberCMS where a user can select an item and see a list of material needed to craft it. Some materials can also be crafted and the user can see a "+" sign near the craftable material, that could be clicked to show an other list with the material needed to create the material.

See example

The problem is that while there is only one nested submaterial (like in the example image) there are no problem, but when there are more than one nested submaterial (for example a craftable submaterial that has craftable submaterials) the server returns me an "Internal server error" and the error_log reports:

PHP Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 65536 bytes) in /home/federico/federicoxella.com/vendor/composer/ClassLoader.php on line 412

This is the script i'm using to extract data from database (The database is on the same machine of the server)

public function onExpand()
{
    $itemID = post('item_id');

    $this->page['subitemMaterials'] =
        Item::select('federicoxella_lootbot_items.id', 'name', 'craftable')
           ->join('federicoxella_lootbot_crafts', function($join) use ($itemID)
           {
               $join->on('federicoxella_lootbot_crafts.material_1', '=', 'federicoxella_lootbot_items.id')
                    ->orOn('federicoxella_lootbot_crafts.material_2', '=', 'federicoxella_lootbot_items.id')
                    ->orOn('federicoxella_lootbot_crafts.material_3', '=', 'federicoxella_lootbot_items.id');
           })
           ->where('federicoxella_lootbot_crafts.material_result', '=', $itemID)
           ->get();
}

This function should take the ID of an item, extract all needed material from database and insert them in a page variable (subitemMaterial) that looks like this [{"id":3,"name":"Colla","craftable":0},{"id":4,"name":"Accendino","craftable":0},{"id":23,"name":"Metallo","craftable":0}]

If an item has "craftable":1 a new partial is created to host the material needed to create the item.

And this is the partial in where I use the variable

<ul class="no-bullet-list">
    {% for i in 0..2 %}
    <li>
        {% if subitemMaterials[i].craftable == 1 %}
        <b>{{ itemMaterial[i].name }}</b>
        <form style="display:inline;">
            <input type="hidden" name="item_id" value="{{ subitemMaterials[i].id }}" />
            <a data-request="{{ __SELF__ }}::onExpand"
                data-request-update="'{{ __SELF__ }}::subItems': '#{{ subitemMaterials[i].id }}_materials'">+</a>
        </form>
        <div id="{{ subitemMaterials[i].id }}_materials">
            {% partial __SELF__~'::subItems' %}
        </div>
        {% else  %}
        {{ subitemMaterials[i].name }}
        {% endif %}
    </li>
    {% endfor %}
</ul>

And the partial in where I declare the previous partial

<div class="callout">
    <h3>{{ itemToCraft.name }}</h3>
    <ul class="no-bullet-list">
        {% for i in 0..2 %}
        <li>
            {% if itemMaterial[i].craftable == 1 %}
            <b>{{ itemMaterial[i].name }}</b>
            <form style="display:inline;">
                <input type="hidden" name="item_id" value="{{ itemMaterial[i].id }}" />
                <a data-request="{{ __SELF__ }}::onExpand"
                    data-request-update="'{{ __SELF__ }}::subItems': '#{{ itemMaterial[i].id }}_materials'">+</a>
            </form>
            <div id="{{ itemMaterial[i].id }}_materials">
                {% partial __SELF__~'::subItems' %}
            </div>
            {% else  %}
            {{ itemMaterial[i].name }}
            {% endif %}
        </li>
        {% endfor %}
    </ul>
</div>

Can you guys help me understand why server returns this error code?

Ad

Answer

Ad

Found the problem (that not is exactly a problem):

Pratically I'm recursively adding partials that print the value of the variable injected in the page.

<ul class="no-bullet-list">
    {% for i in 0..2 %}
    <li>
        {% if subitemMaterials[i].craftable == 1 %}
        <b>{{ itemMaterial[i].name }}</b>
        <form style="display:inline;">
            <input type="hidden" name="item_id" value="{{ subitemMaterials[i].id }}" />
            <a data-request="{{ __SELF__ }}::onExpand"
                data-request-update="'{{ __SELF__ }}::subItems': '#{{ subitemMaterials[i].id }}_materials'">+</a>
        </form>
        <div id="{{ subitemMaterials[i].id }}_materials">
            {% partial __SELF__~'::subItems' %}    <--- Incriminate line of code.
        </div>
        {% else  %}
        {{ subitemMaterials[i].name }}
        {% endif %}
    </li>
    {% endfor %}
</ul>
Ad
source: stackoverflow.com
Ad