How to inject a variable into a page that was required by a function

Asked

Viewed 244 times

3

I have the following problem, I am using an MVC model for a CMS in PHP study, but I would like it to be possible to use themes, for this I created a configuration variable that stores the theme name to test, and when I use my controller to call my view, is as follows:

$this->render('view_posts', $parametros);

In this role I pass to view which I will use and vector $parametros, that contains page title, description, content, etc. My render() function looks like this:

private function render($view, $parametros)
{
  require_once(_APP_ROOT . '/view/' . $view.'.php');
}

If I try to get the vector $parametros in view_posts.php works smoothly, but as I said I wanted it to support themes, so on view_posts.php I have a require_once with the theme name and the corresponding page.

require_once(_APP_ROOT . '/tema/' . _TESTE_TEMA . 'index_view.php');

And in the index_view.php of my theme it does not recognize the vector $parametros.

How can I solve this problem? I believe it’s an easy problem to solve but I’m already a little blind in this project and I can’t find a solution.

One detail I’d like to quote is that I’m not using any framework, and would not like to use because it is a study CMS.

  • 1

    is displayed error "Notice: Undefined variable: parameters" or some other?

  • Exactly, as if I had never defined.

  • 1

    no idea of possible cause, but use the function get_defined_vars() in a debug can help you

  • I found this "When you included the template file, you Did the Operation WITHIN the header Function, Thus making all $page variable in the template file referring to the local $page variable in the header Function, which apparently is not declared/defined." - http://stackoverflow.com/questions/1962321/undefined-variable-after-using-require-once - But I still do not know how I will apply to my case, because when it comes to MVC, my views are "dumb", I do not know how I would pass this to my theme.

  • 1

    I’ll give you a hint that might be useful for your purpose: Try this library (it’s not a framework, it’s just a plugin) -> http://platesphp.com/

2 answers

3


You can do it this way, and pass the parameters:

   class View
    {
        function render($file, $variables = [])
        {
            extract($variables);

            ob_start();
            include_once _APP_ROOT .
                         DIRECTORY_SEPARATOR .
                         'tema' . 
                         DIRECTORY_SEPARATOR . 
                         func_get_args(0) . '.php';
            $renderedView = ob_get_clean();
            return $renderedView;
        }
    }

    $view = new View();
    echo $view->render('view_posts', ['foo' => 'bar']);
  • 1

    Ivan, a tip instead of include $file, use include func_get_arg(0). Because Extract can cause the variable $file be superscripted.

  • is true. Now it will always take the first argument passed, regardless of the second parameter to be a ['file'=>'valor'] ...

  • 1

    could pass in the extract(func_get_args(1)); and in the method, take the parameters function render(){...}. A step towards functional programming...

  • Ivan, your tip really helped me! I thought because it was a view, it couldn’t be a class, but I was wrong, and it worked properly. I will mark your answer as a better answer, but I will also post my solution, as it may help someone.

  • 2

    Good! I’m glad you contributed to your project, good luck!

1

Ivan Ferrer’s answer helped a lot, but here’s my solution in case it fits someone else.

In my controller my render() function looks like this:

public function render()
    {   
        $template = new template(__DIR_MEU_template, __SITE_WWW);
        $view = new view($template);
        $view->render('index_view', ['output' => 'má oeeee' ]);
    }

And my view class

class view
{
    private $template;

    public function __construct($template)
    {
        $this->template = $template;
    }

    public function render($view, $vars = [])
    {
        require_once($this->template->get_diretorio() . $view . '.php');
    }
}

It’s still extremely simple and I’m using constants to test, but this is the logic, so I can call any variable that is passed to the view class in my theme.

Thanks for the answers.

  • 2

    Just a simple hint, the class method $template was injected into this class, to become clearer and reinforce the injection of dependency, put her type: public function __construct(Template $template). It is more understandable for those who will touch your code in the future.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.