Include with helper method - global variables

148 views Asked by At

In PHP7 app, I have created helper method to include my template files.

class Templates
{
    public static function Load($name)
    {        
        include Config::template_dir."/tpl.{$name}.php";
    }
}

$var = "Item";
Templates::Load("menu");

and tpl.menu.php is only

<?=$var?>

However, this is not working (Undefined variable $var) , since $var is not visible inside Load. How can I use this solution with a Load method, but be able to use global variables in included file? I dont like putting include directly into my code, since it just does not look clean.

3

There are 3 answers

0
Martin Perry On BEST ANSWER

I have solved this with variarible-length argument list

public static function LoadWithParams($name, ...$args)
{
     foreach ($args as $n)
     {
         ${key($n)} = array_pop($n);
     }
     include Config::template_dir."/tpl.{$name}.php";
}

And call with

Templates::LoadWithParams("head", ["x" => $x]);
0
Barmar On

Since you're including the file inside a function, it doesn't get access to global variables. You need a global declaration. tpl.menu.php needs to be:

<?php global $var; echo $var; ?>
0
symcbean On

When you call include, the included code inherits the scope of where it was included. So if you want to read data created outside the include code, the data needs to be in the local scope and you can bring global variables into the local scope using the global keyword or by referencing the $_GLOBAL superglobal. However this the wrong way to solve the problem. Another behaviour when you include code is that the code is evaluated immediately. Leaving aside the problem of polluting the global namespace, this potentially creates security issues in your application - if the include files are accessible directly by a URL, someone can invoke the functionality, bypassing the constraints (such as checking authentication) in the code which calls "include" by just specifying the URL of the include file, e.g.

HTTPS://example.com/include/user_admin.inc.php

The right way to solve the problem is to minimize the inline code in the include file, declare the desired functionality in classes or functions, the invoke that functionality in the calling code explicitly after including it. Note that you can return a value from the inline code executed when it is included, hence one way to solve the problem without having to implement the specifics of each bit of included functionality is this:

  $fn=include Config::template_dir."/tpl.{$name}.php";
  $fn($var);