1

In my code, I use a public load_snippet function of a class when I need to include HTML or PHP snippets. (I do this instead of a direct include_once because the directory structure varies depending on certain variables).

I had some issues with variable scopes, so I've narrowed down the problem to this: let's say I define a variable within my page:

$variable = 'Hello World!";

Then, I need load in a snippet:

$APP->load_snippet("slider");

The snippet renders perfectly, except that PHP gives an undefined variable error if I try to reference $variable in the slider code. If I directly include the php file, it works as expected, so I don't understand why I'm having this problem, since this is the load_snippet function:

public function load_snippet($snippet){  
if(file_exists("app/".$this->APP_TYPE."/snippets/".$snippet.".php")){  
        include "app/".$this->APP_TYPE."/snippets/".$snippet.".php";  
    }  
    else{  
        include 'common/txt/404.txt';  
    }  
}

Any help you can give me is much appreciated.

4
  • I think I might know the problem, but can you post the slider code so I can be sure, or just the part of the code that references $variable Commented Jul 4, 2011 at 16:16
  • @Tomas All there is is some HTML in a .php file, and within it is <?php echo $variable;?>. It's not just this snippet, for some reason it happens anytime I use my load_snippet function. Commented Jul 4, 2011 at 16:19
  • ok that crushes my idea (my idea was that the slider was in a function and the function hadn't declared that $variable is global)... Commented Jul 4, 2011 at 16:21
  • wait, load snippet is in a class. So including in a class means that this is the problem. To fix it simply put global $variable; above the include Commented Jul 4, 2011 at 16:23

6 Answers 6

1

The file is being included within the context of the load_snippet() function, and therefore has only those variables which exist within that function. One way to modify this is to make your function accept two variables: the filename and an array of values.

public function load_snippet($snippet, $content) {  
    if (is_array($content)) extract($content);
    if (file_exists("app/".$this->APP_TYPE."/snippets/".$snippet.".php")) {  
        include "app/".$this->APP_TYPE."/snippets/".$snippet.".php";  
    } else {  
        include 'common/txt/404.txt';  
    }  
}

Then

$arr = array('variable' => 'Hello world!');
load_snippet('slider', $arr);
Sign up to request clarification or add additional context in comments.

3 Comments

I see... but wouldn't it be redundant to have to type each variable I've already defined into an array?
If you want the load_snippet() function to be generic, and not have a whole bunch of global stuff defined in it, this is, I think, the only way. Don't define your variables and then put them in an array. In my code, generally in this case the array is a database row, $row = Db_Load_Array($sql); Render::snippet('snippet_name', $row); does the job quite neatly.
Thanks, this solution works the best. I defined my variables straight into the $arr array so it wasn't redundant defining them, and now I can access all of them in the snippets I use.
1

I think include inside a function makes no sense to me... I think that you should put in function

global $variable;

Note that include will put the code inside the function(include will be replaced by code) as i know..

5 Comments

You can include whenever you want (it does not make sense from a point of view of a clean code), and the include will be replaced by the content of the file durring compilation. I've seen such approach in Joomla modules (some early version of Joomla), and there was a scope issue because the module was using global, but the variable was not in the global scope, it was in the function's scope (in the scope of the function that includes the file, and the file was declaring class/methods that were referencing global $variable)
I know, includeing inside a function seems awkward to me, too... but the thing is, there must be a better DRY & MVC method of doing this, instead of constantly going include("app/game/snippets/snippet.php").
In terms of putting global $variable in the function, when I have many different variables I need to reference in different snippets, wouldn't that be redundant?
You could create a function to output your stuff inside snippet.php .and call that instead of including.. however it might require extra code.
@Chromium what do you mean with redurant ?Well its not the best way to keep a variable
0

The way you are doing it is an ugly one, but you can use global $variable inside the snipped to refer to the variable. However if you include the snipped inside a function or a method, you'll have to make the variables in that function/method global as well

Comments

0

If you need $variable inside of the App::load_snippet() method, it would probably be best to pass it in:

public function load_snippet($snippet, $var='Hello world'){
   if(file_exists("app/".$this->APP_TYPE."/snippets/".$snippet.".php")){
           include "app/".$this->APP_TYPE."/snippets/".$snippet.".php";
       }else{
           include 'common/txt/404.txt';
       }
   }
   //do something with $var
}

You can set a default for when $variable hasn't been set. No globals, no out of scope variables.

2 Comments

That would most definitely work. However, I'm going to be loading many different snippets with many other variables, and my code would be unmanageable if I had to keep adding variables separately to a function with 50+ parameters. Is there a way to do this that is more DRY?
@Chromium, I'm a bit confused as to why you'd need 50+ parametres? If each call to snippet needs different information in $var, then pass different information. If you need to pass a set of variables, then define $var as an array and use named indices. Or, if all your information is related, define $var as an object of, say, Class SnippetAuxData. In any of these cases, you only pass one $var. However you do it, if $var or your $variable will be of substantially different forms, then your load_snippet function will need conditional logic to deal with those forms.
0

Instead you can use the constants like define('VARIALABLE','value'). which will be available to you anywhere in your file

Comments

-1

You are including inside a class. Which means that the included file has the same variable scope as the line of code which includes it has. TO fix this all you need to do is put

global $variable;

Above the include.

1 Comment

Avoid globals like the plague! Always a safer solution such as passing arguments or a static class!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.