1

I am trying to learn web app MVC in PHP.Most of the articles discussed about 1-to-1 MVC pattern given bellow

  • Controller: gets user request & update model,
  • Model: receives orders form Controller & update the data.
  • View: receives the updated data from Model & display it.

However, in my MVC project I need to create a hierarchy of Views that displays their corresponding data from the Model layer like the structure given below: [Note:here, all the Model and View types are same.So no different type exist.]

$models = array();
$models[0] = array("id"=>1, "parent_id"=>null,    "title"=>"R1","content"=>"This is Root content 1");
$models[1] = array("id"=>2, "parent_id"=>1,       "title"=>"c2","content"=>"This is content 2");
$models[2] = array("id"=>3, "parent_id"=>1,       "title"=>"c3","content"=>"This is content 3");
$models[3] = array("id"=>4, "parent_id"=>2,       "title"=>"c4","content"=>"This is content 4");
$models[3] = array("id"=>5, "parent_id"=>3,       "title"=>"c5","content"=>"This is content 5");
<div class="top-view-1"> 

 <div class="child-2">
   <div class="child-4">
         <!-- And next <div>s Continues So on .... -->
   </div>
 </div>

 <div class="child-3">
           <div class="child-5">
         <!-- And next <div>s Continues So on .... -->
   </div>
 </div>
</div>

I have the data & List of child Models inside Model layer like given below:

//Model Layer 
public $Models = array(); // array of child models
public $data = array("id"=>1, "parent_id"=>null, "title"=>"C1","content"=>"This is a content");

However, the problem occurs at the view layer where i need to send Model data in a recursive view function that generate that hierarchy of <div>s

//View Layer:

function ShowAsChild($nextChildModel)
    {

        echo '<div class="data".' .$nextChildModel->data["content"]';
                   $this->ShowChild($nextChildModel);
        echo '</div>';

    }

    function ShowChild()
    {

        if (count($this->controller->model->childModels ) > 0)
        {
            echo '<div class="child">';
            foreach ($this->controller->model->childModels  as $child){
                /* below code line is the key problem.
                   it should be like $child-->ShowAsChild();
                */
                $this->ShowAsChild($child);
            }
            echo '</div>';
        }
        else
          return;
    }

If you observe the above code, then you will notice that same view is calling itself with different model data!. So as a result, the recursion becomes infinite.I think, What needed is to transfer from current view to the next view, which will call it's own functions with own model. Moreover, these functions can't move to model layer, because they directly create HTML view display. So at this point, I don't know how do i solve this problem.

So please please help me to fix this problem.Please show some code samples.Thanks

  • Does this question belong here? As soon as I see code, I think of stackoverflow.com – Mawg Jul 27 '18 at 9:27
1

The main problem is that each time you enter ShowChild() you are restarting the count on the array of models.

Recursive functions must always have a way to stop recursing when they reach the end.

I think what you want is to pass an array of model data to the view, but instead of displaying one view per model, you want each view to be nested within the other.

The snippet below shows a recursive loop that will stop. I ran this from command line PHP. You should be able to adapt this for your application - if I understood your need correctly.

<?php

$models = array();
$models[0] = array("id"=>1, "title"=>"D1","content"=>"This is content 1");
$models[1] = array("id"=>2, "title"=>"D2","content"=>"This is content 2");
$models[2] = array("id"=>3, "title"=>"D3","content"=>"This is content 3");
$models[3] = array("id"=>4, "title"=>"D4","content"=>"This is content 4");

class View {
    private $models=array();

    public function setModelArray($Models){  // the controller passes the array of model data to view
        $this->models = $Models;
    }

    public function ShowHierarcyOfViews ($level){  
        if (current($this->models) != false){
            $model = current($this->models);
            for ($n=0; $n<$level; $n++) echo "\t"; // for indenting
            echo '<div class="data">'.'content= '.$model["content"].PHP_EOL;
            next($this->models);
            $this->ShowHierarcyOfViews ($level+1); // recursive call
            for ($n=0; $n<$level; $n++) echo "\t";    // for indenting    
            echo '</div>'.PHP_EOL;;
        }
    }
}

$view = new View;
$view->SetModelArray($models);
$view->ShowHierarcyOfViews(0);
  • @ bcperth thanks .Answer is almost near.However, i have to print the model trees in the view that maintain the parent child order.So please check the <div> structure mapping with data in my post (also added new notes). So please help me. Its almost done.please re-edit your answer & let me accept it as an answer. – user5005768 Jul 27 '18 at 5:06
  • There are is a comment above that this question should be in Stackoverflow. I can continue to help here for now but please put coding questions like this on Stackoverflow in future. – bcperth Jul 27 '18 at 23:50
  • A general solution to a question like this may first require constructing a tree (like in Composite design pattern). That is especially true if a view can have any number of children and more so if you can meet a node whose parent node is not yet constructed. This would require scanning the full model data array first and building the tree. – bcperth Jul 27 '18 at 23:56
  • However, are there rules like "every view has exactly 2 children or none" and "child views are never mentioned before their parent"? eg meeting parent_id = 9 before id=9 has been met?. Can you state any rules that constrain the view tree? Any rules like this would make the tree easier to construct probably. – bcperth Jul 28 '18 at 0:05

Your Answer

By clicking "Post Your Answer", you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.