Jaume Mal
Jaume Mal

Reputation: 658

Echoing to separated html sections from single loop in PHP

What are common patterns in PHP when dealing with a loop that has to echo to separated html sections?

Consider I have a cart() function which returns product items as arrays. For example a product:

$aProduct = ['details' => 'this details', 'frames' => 2, 'price' => 58]

Now I have to loop over cart() echoing each product's data in different html sections.


  <section class="details">
    //each product's details
  </section>

  <section class="frames">
    // each product's frames
  </section>

  <section class="price">
    // each product's price
  </section>

...enclosing this whole structure into a loop is concise but would duplicate the sections which is not desired:

<?php foreach(cart() as $product): ?>

  <section class="details">
    <?= $product['details'] ?>
  </section>

  <section class="frames">
    <?= $product['frames'] ?>
  </section>

  <section class="price">
    <?= $product['price'] ?>
  </section>

<?php endforeach ?>

...it seems then the only alternative is to duplicate the loop within each section:

  <section class="details">
    <?php foreach(cart() as $product): ?>
      <?= $product['details'] ?>
    <?php endforeach ?>
  </section>

  <section class="frames">
    <?php foreach(cart() as $product): ?>
      <?= $product['frames'] ?>
    <?php endforeach ?>
  </section>

  <section class="price">
    <?php foreach(cart() as $product): ?>
      <?= $product['price'] ?>
    <?php endforeach ?>
  </section>

...but this is both repetitive and may make things difficult when the data gets more complex, such as nested arrays whose elements need to be popped in sync between sections.

Is there any PHP alternative, best practice or common pattern in cases such as this one, or is this something that is probably better resolved in the HTML structure?

Upvotes: 1

Views: 100

Answers (1)

El_Vanja
El_Vanja

Reputation: 3993

A good rule of thumb is to avoid whatever logic can be avoided inside templates. To achieve something like that, always prepare data for your view in the exact form that is needed. This will keep your templates simple and to the point.

So, instead of taking a single array that has data for all the sections:

[
    ['details' => 'this details', 'frames' => 2, 'price' => 58],
    ['details' => 'those details', 'frames' => 4, 'price' => 69],
    ['details' => 'that details', 'frames' => 6, 'price' => 93],
]

and iterating it multiple times only to get the fraction that you need, you should split it into several arrays holding all the details for a single section, so you end up with something like this:

$details = ['this details', 'those details', 'that details'];
$frames = [2, 4, 6];
$prices = [58, 69, 93];

After that, the output of each section is trivial.

This example is simple enough that array_column would do the job of separating the cart array into individual ones presented above. You might have to apply a custom function if the cart array structure is a bit more complex.

Upvotes: 2

Related Questions