jakubplus
jakubplus

Reputation: 317

pass a variable from controller, through a model to a view file

I'm trying to understand how passing variables work exactly.

I've set a controller:

class indexController
{
    public function calling()
    {
        $route = new Route():
        $route->title = 'Register user';
        $route->getview('users','register');
    }
}

And a model:

class Route
{
    public function getview($module,$filename)
    {
        require_once('templates/'.$module.'/'.$filename.'.phtml');
    }
}

And a view file which has something like this:

<div class="title"><?php echo $this->title; ?></div>

How to set title for the view? Should I 'public' this var in controller, and get it while constructing model to use in my view file?

Upvotes: 0

Views: 235

Answers (2)

tereško
tereško

Reputation: 58444

What gave you an impression that you are implementing MVC? Because from where stand, it looks like you have mixed up the responsibilities for each part of the pattern.

Here are the basics ..

MVC is an architectural design pattern, that is an expression of SoC principle. It separates the model layery (that is responsible for implementing domain business logic) from presentation layer. And within presentation layer it separates the parts that handle user input (controller) from logic that generates the user interface (view).

When applying this pattern to Web, the flow of information goes something like this:

  • controller receives request from users
  • controller alters the state of model layer and (maybe) the current view
  • view request necessary information from model layer
  • view produces a response to the user

What you have there is NOT a view, but simply a template. And what you have there is NOT model, but simply a class.

And now you questions:

How to set title for the view?

Your view should request the information, that it needs, from model layer:

namespace Views;

class Doclument 
{
    // ... some code

    public function foobar()
    {
        $library = $this->serviceFactory->acquire('Library');

        $title = $library->getCurrentDocument('title');
        $content = $library->getCurrentDocument('content');
        
        $this->template['main']->assign([
           'title' => $title,
           'body'  => $content,
        ]);
    }

    // ... some more code 

    public function render()
    {
       /*
           if any templates have been initialized,
           here you would put code for combining them and
           return html (or some other format)
       */
    }
}

Off course, you would need to know, which document the user wanted to see .. that should be done in a controller:

namespace Controllers;

class Document
{
    // ... again, some code, that's not important here

    public function getFoobar( $request )
    {
        $library = $this->serviceFactory->acquire('Library');
        $library->useLanguage( $request->getParameter('lang') );
        $library->locateDocument( $request->getParameter('id') );
    }
}

The $serviceFactory would be shared between both controllers and views, since it's how you interact with the model layer. This also gives you a way to initialize each service only once, without creating a dependence on global state.

Should I 'public' this var in controller, and get it while constructing model to use in my view file?

No.

Model layer (yes, it should be layer and not a class) should not be aware of anything from implementation of presentation layer. An actually, view should not be aware of controller's either.

Actually, having public variables in OOP is considered to be a bad practice (unless you are creating data structures .. think: stuff like binary trees). It causes your code to leak encapsulation.

P.S.

I'm trying to understand how passing variables work exactly.

That's basics of OOP. You should not be playing around with high-level constructs like MVC pattern, if you do not have a good grasp on OOP concepts, practices and methodology.

Look up thing called "dependency injection".

Upvotes: 1

Galen
Galen

Reputation: 30170

There are problems with your design but forgetting those this is a way you could do it.

public function var( $var, $val ) {
    $this->vars[$var] = $val; // should disallow _view as a $var
}

public function getview($module,$filename)
{
    $_view = 'templates/'.$module.'/'.$filename.'.phtml';
    extract( $this->vars );  //creates variables for 
    require_once( $_view );
}

Use it like this

    $route = new Route():
    $route->var( 'title', 'Register user' );
    $route->getview('users','register');

Upvotes: 1

Related Questions