Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Including file Inside class

Status
Not open for further replies.

thepixel

Programmer
Sep 8, 2008
18
US
I'm trying to setup a class that will allow a file to be included on the page. It goes something like:

Code:
<?php
class myClass {
     ... ... ...
     function includeFile(){
          if(file_exists($this->include_file)){
               include($this->include_file);
          } else {
               $this->error("file missing");
          }
     }
     ... ... ...
}

$foo = "bar";

$page = new myClass();
$page->include_file = "the_file.php";
$page->includeFile();
?>

// the_file.php
<?php  echo $foo;  ?>

It has something to do with variable scope and accessing globals or something, I'm not sure. My question is how should I setup my class so that I do not have to use "return" at the bottom of any files I want to include with my class? I want the includes to function just like normal includes.

I tried

Code:
<?php
class myClass {
     ... ... ...
     function includeFile(){
          global $GLOBALS;
          global $HTTP_SERVER_VARS;
          if(file_exists($this->include_file)){
               include($this->include_file);
          } else {
               $this->error("file missing");
          }
     }
     ... ... ...
}

but that still doesn't make $foo print "bar".

Thanks for any help on how to accomplish this.
 
Well, you're right - your problem is with variable scope. When you include a file, the variables in the included file have the same scope as where you called include. In your example, $foo is in the global scope and the include is in the local scope of the method call.

Your attempted solution doesn't work because, frankly, it really doesn't make sense. The line "global $GLOBALS" does absolutely nothing because $GLOBALS is a superglobal, which means that it is automatically always in scope. You use $GLOBALS by accessing global variables as elements of it.

As for $HTTP_SERVER_VARS, it's not a superglobal, but it doesn't matter, because it's been deprecated for years and you shouldn't be using it at all. Instead, use $_SERVER, which contains the same data and is a superglobal.

As to accessing $foo, you have a few options for bringing a variable in the global scope into the local scope. They are:
Code:
# Method 1:
# Use a global declaration to bring a [i]particular [/i]
# variable into scope.
function includeFile(){
     global $foo;
     if(file_exists($this->include_file)){
     ...
}

# Method 2: 
# Reference the superglobal in your include file.
// the_file.php
<?php  echo $GLOBALS['foo'];  ?>

# Method 3: 
# Use [url=http://us.php.net/manual/en/function.extract.php]extract()[/url] to bring the global 
# variables into the local scope.
function includeFile(){
     extract($GLOBALS);
     if(file_exists($this->include_file)){
     ...
}
Method 3 is probably the closest to what you're looking for. The extract() function will just take an associative array and turn each element into a local variable with the same name as the key. When used with $GLOBALS, that has the effect of putting everything in the global scope into the local scope.
 
Wow, #3 is exactly what i was looking for. And it seems much better than my recently discovered solution:
Code:
<?php

reset($GLOBALS);
while(list($key,$val)=each($GLOBALS)){
	if(($key==strstr($key,"HTTP_")) || (strstr($key,"_")==$key))
		continue;
	//eval("global $".$key.";");
	global ${$key};
}
reset($GLOBALS);
?>

Now, my last step would be to somehow get any newly created variables inside my include file available after the include file (i guess to put those into the global variable scope as wel). Is that possible?

Thanks a bunch!
 
No, there is no easy way to reverse this. At least, no way that doesn't require you to individually reference the particular variables you've changed. If you don't mind keeping track of that, you can always just assign those variables back to $GLOBALS['varname']. But at that point, I'd say it's just easier to modify your include file to reference all global variables through $GLOBALS.

As a side note, I question whether this is even a good idea. I'm not sure exactly what you're trying to accomplish by including files through a class method, but I assumed you were using it as an ad hoc template system. If that's the case, modifying global variables (or, really, any variables) from templates is generally not a good practice. The entire point of a templating system is to separate your display from your business logic. If the display code is making changes that need to be propogated back to the business layer, that kind of defeats the purpose.

If, on the other hand, you're just including arbitrary scripts, I would question the need for a class method at all. It adds a layer of complexity and, from what you've posted, doesn't buy you anything. So why not just use include directly?
 
Well, that's not exactly how i'm using it.

I have a file above the headers called process.php which allows me to process forms on any given page. It keeps all of this similar code in one file and separate from other stuff.

Then I'm including my page content. The issue comes when the page is a form and the form is submitted and the form processor finds errors such as missing fields, etc. So I guess I could add 2 additional variables 2 my class and then move my class above the process.php file include. then instead of setting $process (true/false) or $err (some error string) i can just set it in the main class and that's what will determine the form was submitted successfully.

I'm sure there is much more to doing this than i'm digging into, but i've been using this static system for a while and decided it was time for an upgrade so I thought i could put it all in a class and it still work very much like it did before (even a little better).

This system is mainly just for myself to allow me to throw sites and applications up quickly with mod_rewrite enabled and the site/app driven by a database.

Would compact() perform the opposite at the end of my include?

like:

extract($GLOBALS);
include($this->includeFile);
compact($GLOBALS);

And also, btw, I really have no need for usage of variables beyond the include, but I want to keep an open mind for the future.
 
No, compact doesn't work that way. It takes a bunch of variable names as paramaters and converts them into an array. In fact, go ahead and try that code - on my box it makes PHP segfault.

You could do something like:
Code:
$data = compact(array_keys($GLOBALS));
foreach ($data as $key=> $val) {
    $GLOBALS[$key] = $val;
}
However, if all you want to do is set status variables, then your comment about setting them in the class sounds much better. If you're including the file from the class method, then the class member variables will be in scope, so you can set $this->err instead of just $err. That way you can still get the value through an instance of your class, but you don't have to worry about putting things in the global scope.
 
Yeah, i'll probably do that for now, although the compact code you sent me doesn't seem to work. It's not that important because I think i've gotten plenty of good suggestions to code the the "right way".

As for my solution, any other variables on the page I may need (other than the 2 i will move to the class), i guess it's not too bad to just declare global $var at the top of the include.

Thanks for the help.
 
Adahacker said:
At least, no way that doesn't require you to individually reference the particular variables you've changed.
i have not followed this thread too carefully but have you had a look at get_defined_vars()? within the scope a function or method you could use this to grab all set variables. then unset the arraykeys for the superglobals (to save memory). then you can pass the results around as you wish.
Code:
$_vars = get_defined_vars();
$unset = array('_POST', '_GET', '_SERVER', '_SESSION', 'argv', '_COOKIES', '_FILES', 'GLOBALS');
foreach ($unset as $u){
 if (isset($_vars[$u])) unset ($_vars[$u]);
}
//do something with $_vars
global $functionVars;
$functionVars = $_vars;
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top