Protecting Variables from "Enable Pollution" in PHP

tl; dr: Is there a way to prevent (essentially locking) the variables declared / defined before the include() call when the file is included? Also a somewhat related question .


I am wondering what measures can be taken to avoid variable pollution from the included files. For example, given this little function:

 /** * Recursively loads values by include returns into * arguments of a callback * * If $path is a file, only that file will be included. * If $path is a directory, all files in that directory * and all sub-directories will be included. * * When a file is included, $callback is invoked passing * the returned value as an argument. * * @param string $path * @param callable $callback */ function load_values_recursive($path, $callback){ $paths[] = path($path); while(!empty($paths)){ $path = array_pop($paths); if(is_file($path)){ if(true === $callback(include($path))){ break; } } if(is_dir($path)){ foreach(glob($path . '*') as $path){ $paths[] = path($path); } } } } 

I know that he skips some type checks and other explanations, let him ignore them.

In any case, this function is mainly sifted through a bunch of data files that simply return values โ€‹โ€‹(usually configuration arrays or routing tables, but whatever), and then calls the passed callback so that the value can be filtered, sorted, or used as- that. For instance:

 $values = array(); load_values_recursive('path/to/dir/', function($value) use(&$values){ $values[] = $value; }); 

And path/to/dir/ can have several files following this pattern:

 return array( // yay, data! ); 

My problem arises when these โ€œconfigurationโ€ files (or something else, trying to keep this portable and cross-functional) begin to contain even rudimentary logic. It is always possible to pollute variables local to the function. For example, a configuration file that is used for convenience:

 return array( 'path_1' => $path = 'some/long/complicated/path/', 'path_2' => $path . 'foo/', 'path_3' => $path . 'bar/', ); 

Now this $path turns out to be a visible directory relative to the current one, the function will be clumsy:

 // ... if(is_file($path)){ if(true === $callback(include($path))){ // path gets reset to break; // some/long/complicated/path/ } } if(is_dir($path)){ // and gets added into the foreach(glob($path . '*') as $path){ // search tree $paths[] = path($path); } } // ... 

This will probably have bad results. The only solution I can imagine is wrapping the include() call with another anonymous scope function:

 // ... if(true === call_user_func(function() use($callback, $path){ return $callback($path); })){ break; } // ... 

Thus, the protection of $path (and more importantly, $callback ) from the occurrence of side effects with each iteration.

I am wondering if there is an easier way to โ€œblockโ€ variables in PHP under such circumstances.

  • I just want to record a record here; I know that I could use, for example, elseif to alleviate one of the problems related to this function, however my question is more interested in thoroughly agnostic solutions, nevertheless, if you want.
+4
source share
2 answers

I went with the following solution to enable pollution:

 $value = call_user_func(function(){ return include(func_get_arg(0)); }, $path); 

$path nowhere to be seen when turned on, and it seems the most elegant. Of course, calling func_get_arg($i) from the included file will give the passed values, but, well ...

+1
source

take a look at Providing the parent variable scope of include () 'd files , it has a rather unique approach to the problem that can be used here.

this means the cancellation of all defined vars before switching on and their subsequent reset after.

he, of course, is not elegant, but he will work.

+1
source

Source: https://habr.com/ru/post/1379725/


All Articles