Recursively displaying json data on website I am displaying the data from a json file onto a website, with recursive and iterative tables side by side. i have the iterative code working, but I have no idea on how to make it recursive.
Here is the code:
    $dataArray = json_decode($data, true);
            if(is_array($dataArray)){ //first level
                $result = &quot;&lt;table class='arrayTable'&gt;&quot;;
                    foreach($dataArray as $key=&gt;$val){ //second level
                        $result.=&quot;&lt;tr&gt;&lt;td class ='key'&gt;&quot;.$key.&quot;: &lt;/td&gt;&lt;td class ='value'&gt;&quot;;
                        if(gettype($val)==&quot;array&quot;){
                            $result .= &quot;&lt;table class='arrayTable'&gt;&quot;;
                            foreach($val as $subkey=&gt;$subval){ //third level
                                $result.=&quot;&lt;tr&gt;&lt;td class ='key2'&gt;&quot;.$subkey.&quot;: &lt;/td&gt;&lt;td class ='value2'&gt;&quot;;
                                if(gettype($subval)==&quot;array&quot;){
                                    $result .= &quot;&lt;table class='arrayTable'&gt;&quot;;
                                    foreach($subval as $lowkey=&gt;$lowval){ //fourth level
                                        $result.=&quot;&lt;tr&gt;&lt;td class ='key3'&gt;&quot;.$lowkey.&quot;: &lt;/td&gt;&lt;td class ='value3'&gt;&quot;;
                                        if(gettype($lowval)!=&quot;array&quot;){
                                            $result.=$lowval.&quot;&lt;/td&gt;&lt;/tr&gt;&quot;;
                                        }else{
                                            $result.=&quot;&lt;/td&gt;&lt;/tr&gt;&quot;;
                                        }
                                    }
                                    $result.=&quot;&lt;/table&gt;&quot;;
                                }else{
                                    $result.=$subval.&quot;&lt;/td&gt;&lt;/tr&gt;&quot;;
                                }
                            }
                            $result.=&quot;&lt;/table&gt;&quot;;
                        }else{
                        $result.=$val.&quot;&lt;/td&gt;&lt;/tr&gt;&quot;;
                        }
                    }
                $result.= &quot;&lt;/table&gt;&quot;;
            }else{
                echo &quot;Not a valid format!&quot;;
            }
            return $result;
Your code is a pain to read, please add early returns.
To go with the point above, please follow PSR-12.
iterative tables side by side. Your code creates another table within a , so it's no exactly side by side.

Here is how I refactored your code:

I completed step 1 and 2.
I have broken everything up into methods:

&lt;?php

namespace App;

class DisplayArrayTable
{
    protected $result = '';

    /**
     * @param mixed $value
     */
    protected function setupMeaningFullName1(string $key, $data): void
    {
        $this-&gt;result .= &quot;&lt;tr&gt;&lt;td class ='key'&gt;{$key}: &lt;/td&gt;&lt;td class ='value'&gt;&quot;;

        if (!is_array($data)) {
            $this-&gt;result .= &quot;{$data}&lt;/td&gt;&lt;/tr&gt;&quot;;

            return;
        }

        $this-&gt;result .= &quot;&lt;table class='arrayTable'&gt;&quot;;

        foreach ($data as $key =&gt; $value) {
            $this-&gt;setupMeaningFullName2($key, $value);
        }

        $this-&gt;result .= &quot;&lt;/table&gt;&quot;;
    }

    /**
     * @param mixed $value
     */
    protected function setupMeaningFullName2(string $key, $data): void
    {
        $this-&gt;result .= &quot;&lt;tr&gt;&lt;td class ='key2'&gt;{$key}: &lt;/td&gt;&lt;td class ='value2'&gt;&quot;;

        if (!is_array($data)) {
            $this-&gt;result .= &quot;{$data}&lt;/td&gt;&lt;/tr&gt;&quot;;

            return;
        }

        $this-&gt;result .= &quot;&lt;table class='arrayTable'&gt;&quot;;

        foreach ($data as $key =&gt; $value) {
            $this-&gt;setupMeaningFullName2($key, $value);
        }

        $this-&gt;result .= &quot;&lt;/table&gt;&quot;;
    }

    /**
     * @param mixed $value
     */
    protected function setupMeaningFullName3(string $key, $data): void
    {
        $this-&gt;result .= &quot;&lt;tr&gt;&lt;td class ='key3'&gt;{$key}: &lt;/td&gt;&lt;td class ='value3'&gt;&quot;;

        if (!is_array($data)) {
            $this-&gt;result .= &quot;{$data}&lt;/td&gt;&lt;/tr&gt;&quot;;

            return;
        }

        $this-&gt;result .= &quot;&lt;/td&gt;&lt;/tr&gt;&quot;;
    }

    public function handle(array $data): string
    {
        foreach ($data as $key =&gt; $value) {
            $this-&gt;setupMeaningFullName1($key, $value);
        }

        return &quot;&lt;table class='arrayTable'&gt;{$this-&gt;result}&lt;/table&gt;&quot;;
    }
}


I have identified the pattern and further refactored your code

&lt;?php

namespace App;

class DisplayArrayTable
{
    const MAX_ITERATIONS = 3;
    protected $currentIteration = 1;
    protected $result = '';

    /**
     * @param mixed $value
     */
    protected function iteration(string $key, $data): void
    {
        $this-&gt;result .= &quot;&lt;tr&gt;&lt;td class ='key'&gt;{$key}: &lt;/td&gt;&lt;td class ='value'&gt;&quot;;

        if (!is_array($data)) {
            $this-&gt;result .= &quot;{$data}&lt;/td&gt;&lt;/tr&gt;&quot;;

            return;
        }

        if ($this-&gt;currentIteration === static::MAX_ITERATIONS) {
            $this-&gt;result .= '&lt;/td&gt;&lt;/tr&gt;';
            
            return;
        }

        $this-&gt;result .= '&lt;table class=&quot;arrayTable&quot;&gt;';

        foreach ($data as $key =&gt; $value) {
            $this-&gt;currentIteration++;

            $this-&gt;setupMeaningFullName2($key, $value);
        }

        $this-&gt;result .= '&lt;/table&gt;';
    }

    public function handle(array $data): string
    {
        foreach ($data as $key =&gt; $value) {
            $this-&gt;iteration($key, $value);
        }

        return &quot;&lt;table class='arrayTable'&gt;{$this-&gt;result}&lt;/table&gt;&quot;;
    }
}


Performed further refactoring to improve iteration method

&lt;?php

namespace App;

class DisplayArrayTable
{
    const MAX_ITERATIONS = 3;
    protected $currentIteration = 1;
    protected $result = '';

    public function handle(array $data): string
    {
        foreach ($data as $key =&gt; $value) {
            $this-&gt;iteration($key, $value);
        }

        return &quot;&lt;table class='arrayTable'&gt;{$this-&gt;result}&lt;/table&gt;&quot;;
    }

    /**
     * @param mixed $value
     */
    protected function iteration(string $key, $data): void
    {
        $this-&gt;result .= &quot;&lt;tr&gt;
            &lt;td class ='key'&gt;{$key}: &lt;/td&gt;
            &lt;td class ='value'&gt;&quot;;

        if (!is_array($data)) {
            $this-&gt;result .= &quot;{$data}&lt;/td&gt;&lt;/tr&gt;&quot;;

            return;
        }

        if ($this-&gt;currentIteration === static::MAX_ITERATIONS) {
            $this-&gt;result .= '&lt;/td&gt;&lt;/tr&gt;';
            
            return;
        }

        $this-&gt;setupNewTable($data);
    }

    protected function setupNewTable(array $data): void 
    { 
        $this-&gt;result .= '&lt;table class=&quot;arrayTable&quot;&gt;';

        foreach ($data as $key =&gt; $value) {
            $this-&gt;currentIteration++;

            $this-&gt;iteration($key, $value);
        }

        $this-&gt;result .= '&lt;/table&gt;';
    }
}

So, all you need to do now is call this call and pass in a valid array
use App\DisplayArrayTable;

...

$dataArray = json_decode($data, true);

if ($dataArray &amp;&amp; is_array($dataArray)) {
   $html = (new DisplayArrayTable)-&gt;handle($dataArray);
}