Search code examples
phparraysforeachnested-loops

Foreach Nested Loops


So here is my code. The problem I am having is that I want the number from HP in my PHP code into my HP HTML code and the same thing with Cylinders. I have figured out the other stuff but when it comes to that part I am stuck

<?php 

    ini_set('display_errors', 1);
    ini_set('display_startup_errors', 1);
    error_reporting(E_ALL);

    $cars = array(
        array(
            "car"       =>  "Ferrari",
            "model"     =>  "Testarossa",
            "gearbox"   =>  "Manual 5 Shift",
            "designer"  =>  "Battista Pininfarina",
            "engine"    => 
        array(
            "HP"        => 390, 
            "Cylinders" => 12
            ),
        ),

    );

    ?>

    <?php foreach($cars as $cars_key => $car_val): ?>

        <ul>
            <div style="margin-bottom: 10px;">
                <li><b>Car:</b> <?php echo $car_val["car"]; ?></li>
                <li><b>Model:</b> <?php echo $car_val["model"]; ?></li>
                <li><b>Gearbox:</b> <?php echo $car_val["gearbox"]; ?></li>
                <li><b>Designer:</b> <?php echo $car_val["designer"]; ?></li>
                <li><b>Engine</b></li>
                    <ul>
                        <li><b>HP:</b></li>            
                        <li><b>Cylinders:</b></li>                                        
                    </ul>
            </div>
        </ul>
    <?php endforeach; ?>

How it looks now


Solution

  • I have a few concerns:

    1. You lose the brilliance/utility of an associative array when you hardcode values into your script that you could otherwise just call from the array.

    2. I don't like the look of the mid-list <div>. I can't think of any good reason to break up your unorder list flow with it.

    3. I don't like the floating sub-list either. It logically belongs to Engine and good markup would dictate that the sub-list exist inside of its parent.

    Here is what I would suggest considering my above points...

    *Some Notes:

    • I'm not sure how you want to layout multiple lists as your array grows in size.
    • The echoing is just my personal preference. You can bounce in and out of php if you like.
    • ucfirst() allows you to avoid hardcoding the keys.
    • My snippet will make your task clean, DRY, and concise.

    Code: (Demo)

    $cars = array(
                array(
                    "car"       =>  "Ferrari",
                    "model"     =>  "Testarossa",
                    "gearbox"   =>  "Manual 5 Shift",
                    "designer"  =>  "Battista Pininfarina",
                    "engine"    =>  array(
                                        "HP"        => 390, 
                                        "Cylinders" => 12
                                    )
                )
            );
    
    foreach($cars as $details){
        echo "<ul style=\"margin-bottom:10px;\">";
            foreach($details as $key=>$item){
                echo "<li><b>",ucfirst($key),":</b>";
                if(!is_array($item)){
                    echo " $item</li>";
                }else{
                        echo "<ul>";
                            foreach($item as $subkey=>$subval){
                                echo "<li><b>$subkey:</b> $subval</li>";
                            }
                        echo "</ul>";
                    echo "</li>";
                }
            }
        echo "</ul>";
    }
    

    Source Code Output:

    <ul style="margin-bottom:10px;">
        <li><b>Car:</b> Ferrari</li>
        <li><b>Model:</b> Testarossa</li>
        <li><b>Gearbox:</b> Manual 5 Shift</li>
        <li><b>Designer:</b> Battista Pininfarina</li>
        <li><b>Engine:</b>
            <ul>
                <li><b>HP:</b> 390</li>
                <li><b>Cylinders:</b> 12</li>
            </ul>
        </li>
    </ul>
    

    Rendered Output: (run my snippet @ phptester.net to see this)

    enter image description here