3

For example, I have this function:

function foo($whaaaat){

  $var1 = 'a';  
  $a = 1;
  $b = 2;

  ...


  // here unset all variables defined above (including arguments) 
  require 'somefile.php';
}

So, can I unset all those variables before the require point?

Obviously without calling unset manually on each variable, because that I figured out myself :)

Is there some function that does this?

Alex
  • 66,732
  • 177
  • 439
  • 641

8 Answers8

8

You can wrap the require in an anonymous function:

function foo($a){
  $b = 2;

  call_user_func(function() {
   require 'somefile.php';
  });
}
phihag
  • 278,196
  • 72
  • 453
  • 469
7

Assuming none of those in-function variables are declared global, you could try something like

array_diff(get_defined_vars(), $GLOBALS)

to get a list of the local variables, then loop over the results to unset them.

Marc B
  • 356,200
  • 43
  • 426
  • 500
  • 1
    `var_dump(array_diff(get_defined_vars(), $GLOBALS));` appears to be missing locally created arrays... – lpd Feb 27 '13 at 15:13
  • Great point however it's true that is missing locally created arrays! – hatef Oct 26 '15 at 13:17
4

You could do it like so:

function require_noscope($filename)
{
    // Required file cannot see variables from other function
    require $filename;
}

function foo($whaaaat){

  $var1 = 'a';  
  $a = 1;
  $b = 2;
  require_noscope('somefile.php');
}
2

This might work (untested):

$allVars = get_defined_vars(); // Returns array of all defined variables
foreach ($allVars as $allVars) { unset($allVars); }

Edit: As I said, never tested nor ever used this, but it could lead Alex in the right direction.

Seralize
  • 1,117
  • 11
  • 27
  • 3
    That includes $GLOBALS as of PHP 5.0, however, so you'd be unsetting everything in the parent scope, including the SUPERGLOBALS - very bad. – Marc B Oct 20 '11 at 18:59
  • This doesn't work, as unset($allVars) is "unsetting" the value of the variable, not the name of it, or the variable itself, as it needs. – Svish Aug 10 '17 at 19:34
2

Here's a solution:

echo('Before: ' . $test1 . '<br>');

$vars = array_keys(get_defined_vars());
foreach($vars as $var) {
    if($var == 'GLOBALS' || $var == '_POST' || $var == '_GET' || $var == '_COOKIE' || $var == '_FILES' || $var == '_REQUEST' || $var == '_SERVER' || $var == '_ENV')
        continue;
    unset($$var);
}
echo('After: ' . $test1 . '<br>');

My test outputs this:

Before: here?

After:

Community
  • 1
  • 1
Jeff Lambert
  • 24,395
  • 4
  • 69
  • 96
1

I agree with Whetstone. get_defined_vars() is just perfect for "multi-unset" tricks. This method below, unsets ALL variables. All except those found within nameless array inside foreach loop.

foreach(get_defined_vars() as $k=>$y){ 
 if( !in_array( $k, 
 array(
  'myRequredVariableName1',
  'myRequredVariableName2',
  '_ENV',
  '_SESSION',
   '_COOKIE',
  'HTTP_SESSION_VARS',
  'HTTP_COOKIE_VARS'
  )))
  { $$k=null; unset($$k);} 
    unset($y, $k);
} 

// Check for leftovers
header('Content-type:text/plain; charset=utf-8'); 
var_export(get_defined_vars()); 
exit;

The values are actually variable names without '$', where variable variable unset($$k); matches the REAL and defined one, and destroys it, if it is present. So, on this way, You can have complete control over what is left for system.

Note that some shared hosting setups are relying only on _SERVER superglobals, therefore _ENV, HTTP_SESSION_VARS, HTTP_COOKIE_VARS are not required at all. Most probably You'll always want to keep _COOKIE and _SESSION but not _GET and _POST as well or _FILES. The decision varies. Test and see for Your self what should stand within array before putting this trick on Your production environment.

Spooky
  • 1,235
  • 15
  • 17
1

There's nothing built in, but you can use the get_defined_vars() function to get an array of all defined variables, then use a foreach loop to unset them. You'll get it all done in 4 lines that way, and it's flexible.

$list_of_vars =  array_diff(get_defined_vars(), $GLOBALS); // Was just get_defined_vars() before Marc B corrected me in his post.
foreach($list_of_vars as $var){
    unset($var);
}

Edit: As Marc B pointed out, this will unset your $GLOBAL variables too. I've edited my example to show how to properly get the list of variables.

Whetstone
  • 1,199
  • 8
  • 8
  • 1
    That includes $GLOBALS as of PHP 5.0, however, so you'd be unsetting everything in the parent scope, including the SUPERGLOBALS - very bad. – Marc B Oct 20 '11 at 18:59
  • 1
    Very true, good catch. I've given yours the up and made note in mine. – Whetstone Oct 20 '11 at 19:06
  • This doesn't work, as unset($var) is "unsetting" the value of the variable, not the name of it, or the variable itself, as it needs. – Svish Aug 10 '17 at 19:35
0

Needed this, and the existing answers here weren't really helpful. The following is short, to the point, and works:

foreach(get_defined_vars() as $k => $v)
    unset($$k);
unset($k, $v);

If calling var_dump(get_defined_vars()) after this, you will get an empty array.


Note: Unless in global scope (which the question is not, it's in a function), the get_defined_vars won't return any globals, so no need to filter or check anything, just unset it all.

Svish
  • 152,914
  • 173
  • 462
  • 620