function parts($part) {
$structure = 'http://' . $site_url . 'content/';
echo($tructure . $part . '.php');
}
This function uses a variable $site_url that was defined at the top of this page, but this variable is not being passed into the function.
How do we get it to return in the function?
Add second parameter
You need to pass additional parameter to your function:
function parts($site_url, $part) {
$structure = 'http://' . $site_url . 'content/';
echo $structure . $part . '.php';
}
In case of closures
If you'd rather use closures then you can import variable to the current scope (the use keyword):
$parts = function($part) use ($site_url) {
$structure = 'http://' . $site_url . 'content/';
echo $structure . $part . '.php';
};
global - a bad practice
This post is frequently read, so something needs to be clarified about global. Using it is considered a bad practice (refer to this and this).
For the completeness sake here is the solution using global:
function parts($part) {
global $site_url;
$structure = 'http://' . $site_url . 'content/';
echo($structure . $part . '.php');
}
It works because you have to tell interpreter that you want to use a global variable, now it thinks it's a local variable (within your function).
Suggested reading:
Variable scope in PHP
Anonymous functions
Alternatively, you can bring variables in from the outside scope by using closures with the use keyword.
$myVar = "foo";
$myFunction = function($arg1, $arg2) use ($myVar)
{
return $arg1 . $myVar . $arg2;
};
Do not forget that you also can pass these use variables by reference.
The use cases are when you need to change the use'd variable from inside of your callback (e.g. produce the new array of different objects from some source array of objects).
$sourcearray = [ (object) ['a' => 1], (object) ['a' => 2]];
$newarray = [];
array_walk($sourcearray, function ($item) use (&$newarray) {
$newarray[] = (object) ['times2' => $item->a * 2];
});
var_dump($newarray);
Now $newarray will comprise (pseudocode here for brevity) [{times2:2},{times2:4}].
On the contrary, using $newarray with no & modifier would make outer $newarray variable be read-only accessible from within the closure scope. But $newarray within closure scope would be a completelly different newly created variable living only within the closure scope.
Despite both variables' names are the same these would be two different variables. The outer $newarray variable would comprise [] in this case after the code has finishes.
NB: Do not forget that you would better use the immutable data structures (unlike the above) in your common web project. That would account for 99% of the use cases. So the approach above, using mutabliity, is for very seldom kind of "low level" use cases.
I suppose this depends on your architecture and whatever else you may need to consider, but you could also take the object-oriented approach and use a class.
class ClassName {
private $site_url;
function __construct( $url ) {
$this->site_url = $url;
}
public function parts( string $part ) {
echo 'http://' . $this->site_url . 'content/' . $part . '.php';
}
# You could build a bunch of other things here
# too and still have access to $this->site_url.
}
Then you can create and use the object wherever you'd like.
$obj = new ClassName($site_url);
$obj->parts('part_argument');
This could be overkill for what OP was specifically trying to achieve, but it's at least an option I wanted to put on the table for newcomers since nobody mentioned it yet.
The advantage here is scalability and containment. For example, if you find yourself needing to pass the same variables as references to multiple functions for the sake of a common task, that could be an indicator that a class is in order.
I had similar question. Answer: use global. And there are other options.
But if you need named function with usage of outside scope, here what I have:
global $myNamedFunctionWidelyAccessibleCallableWithScope;
$myNamedFunctionWidelyAccessibleCallableWithScope =
function ($argument) use ($part, $orWhatYouWant) {
echo($argument . $part . '.php');
// do something here
return $orWhatYouWant;
};
function myNamedFunctionWidelyAccessible(string $argument)
{
global $myNamedFunctionWidelyAccessibleCallableWithScope;
return $myNamedFunctionWidelyAccessibleCallableWithScope($argument);
}
It is useful for making function myNamedFunctionWidelyAccessible accissible from everywhere, but also binds it with scope. And I deliberately gave very long name, global things are evil :(
Here is documentation with a good example
You can add the below structure
$var1=5;
function sample() use ($var1){echo $var1;}
Just put in the function using GLOBAL keyword:
global $site_url;
Related
Is it possible to programatically register/create a named function in PHP, inside the global scope?
This is possible with create_function (before PHP 7+) and nowadays it's possible with anonymous/lambda functions, but then again you either let them be invoked or you assign them to a variable or an object property, then just invoke them with () at the end.
What I'm interested if it's anyhow possible to add a new named function in a scope which does not have to be assigned to a variable and accessed with $functionName?
Some solution what I'm looking for is:
create_named_function('fullname', function($firstname, $lastname) {
return $firstname . ' ' . $lastname;
});
Then I'd have it accessible like fullname(params...).
Here example with eval:
<?php
$functionName = 'foo';
$f = '
function ' . $functionName . '($a) {
var_dump($a);
}
';
// Finger crossed!)))
eval($f);
// Now you have function "foo" in your global scope!)
$functionName('bar');
// It will print
// string(3) "bar"
But you have to have clear vision what are you really doing here... because it's really tricky place...
Not sure if it should be encouraged to do this - it stops all sort of useful things being able to check code and code completion in IDE's.
BUT...
<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
$body = <<< 'FN'
<?php
function fullname($firstname, $lastname) {
return $firstname . ' ' . $lastname;
}
FN;
file_put_contents("func.php", $body);
require "func.php";
echo fullname("Joe", "Bloggs");
The first part creates an include file with the required code (note the use of Nowdoc string, which allows the inclusion of variables without them being substituted). This could be any form of code generation.
I'm currently doing a beginner course in coding, mainly focusing on PHP and in one exercise we're changing our code from including a template through normal namespacing to instead including it via a function so that we can use output buffering. To make it work we are using extract() and although I understand how extract works, I struggle to see why we need to use it to make include work. Before running it via the function, we didn't need to send in or extract new variables. Is someone able to explain the reasons behind this?
Here's what the function looks like:
const TEMPLATE_EXTENSION = '.phtml';
const TEMPLATE_FOLDER = 'templates/';
const TEMPLATE_PREFIX = 'cart_view_';
function display($template, $variables, $extension = TEMPLATE_EXTENSION) {
extract($variables);
ob_start();
include TEMPLATE_FOLDER . TEMPLATE_PREFIX . $template . $extension;
return ob_get_clean();
}
Here's how we call it:
<?php echo display('user', ['users' => $users, 'cart' => $cart]); ?>
<?php echo display('item', ['new_item' => $new_item]); ?>
<?php echo display('items', ['cart' => $cart]); ?>
And here's what's in the templates we're including:
<h2>New Item</h2>
<p><?php printf($new_item['name']);?> is $<?php printf($new_item['price']);?></p>
<h2>User: <?php printf($cart['user']); ?></h2>
<p>ID: <?php printf($users[$cart['user']]['id']); ?></p>
<p>Email: <?php printf($users[$cart['user']]['email']); ?></p>
<h2>Cart</h2>
<?php foreach ($cart['items'] as $item) {
printf("<p>%s is $%d</p>\n", $item['name'], $item['price']);
} ?>
The variables are definied in another file which is already included in the index.
Previously before using the function to buffer, all we needed was this:
<?php include 'templates/cart_view_user.phtml'; ?>
<?php include 'templates/cart_view_item.phtml'; ?>
<?php include 'templates/cart_view_items.phtml'; ?>
Functions do have their own variable scope. So when you created the display() function, it doesn't see what variables are available outside of it. See more on Variable Scopes in PHP. You are using extract() in order to convert an array into variables in the scope where you are calling it from eg: in the function.
Your first solution was probably something like this (I'm making up the variables):
$users = [];
$cart = [];
// you are including the template in the same scope as the variables are defined, aka it will "see"/have access to those variables
include 'templates/cart_view_user.phtml';
Now you have refactored your code and moved the including logic in a function. This function has its own local scope.
$users = [];
$cart = [];
function display($template, $variables, $extension = TEMPLATE_EXTENSION) {
// you don't have access to $users and $cart here as those are defined in the global scope
extract($variables); // <-- after this call you will have new variables created in the local function scope based on your $variables array
ob_start();
include TEMPLATE_FOLDER . TEMPLATE_PREFIX . $template . $extension;
return ob_get_clean();
}
So now you would have two options if you know what variables you want to make available inside the function you could use the global keyword, but I would discourage using it, it could lead to weird bugs when you don't understand why your variables being changed (ps later you will move onto using classes and you won't have the headache of global variables).
// you can drop $variables from the function signature
function display($template, $extension = TEMPLATE_EXTENSION) {
global $users, $cart, $new_item;
// no extract needed, but please try not using global, it can lead to weird bugs
ob_start();
include TEMPLATE_FOLDER . TEMPLATE_PREFIX . $template . $extension;
return ob_get_clean();
}
Or you can use the extract to create variables in the function's scope so when you include the files they will have access to those variables. On thing to note here that extract will use the array keys as the variable names it is creating. That's why you are passing in display('user', ['users' => $users, 'cart' => $cart]); after this call, extract will create a $users and a $cart variable inside the function call. If you would call it with different array keys, like: display('user', ['u' => $users, 'c' => $cart]); the included file would complain that it can't find the variables $users and $cart.
I hope this helped, feel free to ask more if I wasn't clear anywhere.
I am well aware that globals are evil and this is an issue I will deal with later. It's not my codebase, but I've been assigned some cleaning up tasks.
Trying to smarten up a codebase, I decided to implement simple routing by using a package known as AltoRouter - I've worked with it before and it has worked fine for my purposes.
Now, the codebase is using a large amount of variables declared in the global scope. Usually, these variables are then fetched by using the globalkeyword. But for some reason, this doesn't work when I'm working inside a closure.
Consider this simple routing example:
<?php
require 'vendor/autoload.php';
$router = new AltoRouter();
$router->map('GET', '/shops/[i:id]', function($id) {
$_GET['shop_id'] = $id;
require 'go_to_shop.php';
});
$match = $router->match();
if( $match && is_callable( $match['target'] ) ) {
call_user_func_array( $match['target'], $match['params'] );
}
This calls my closure that sets a variable and requires a file.
This produces an error:
Fatal error: Call to a member function get() on null in
/vagrant/Core/CampaignHandler.php on line 71
Now, the code being called doing this is the following (line 70-71):
// Inside a method
global $serviceContainer;
$dispatcher = $serviceContainer->get("dispatcher");
The $serviceContainer is being declared by including a file early on:
$serviceContainer = new ServiceContainer();
$serviceContainer->set("dispatcher", new EventDispatcher());
Basically, if I move the contents of the closure outside of the closure, everything works perfectly - but as soon as I'm doing it from inside the closure, all variables accessed via the global scope is empty - and I have no idea as to why.
I've tried using use on the closure, this didn't work either.
I'm mostly looking for an explanation rather than a solution.
Globals are evil for a reason. You get the error because the global is not initialized at the time when function is being called. The mess of globals and requires is the exact issue and you are already trying to deal with it.
There is no problem to use globals in closure per se. This example works perfectly fine:
global.php:
<?php
class Foo {
public function bar() { return 'bar';}
}
$foo = new Foo;
test.php:
<?php
require 'global.php';
$test = function($param) {
global $foo;
echo $param, $foo->bar();
}
call_user_func_array($test, ['baz']);
so php test.php outputs bazbar;
I'm pretty sure that the $serviceContainer variable does not exist in the global scope, but the question leaves that part out.
Can't you pass the container to the anonymous function using a use( $serviceContainer ) statement? That'd be a far cleaner solution then having to rely on globals.
function($id) use( $serviceContainer ) {
$_GET['shop_id'] = $id;
require 'go_to_shop.php';
}
Off-topic: not sure what you're doing with that id variable later on and why you're putting it back into the $_GET variable like that, but please be careful.
Please check the manual for anonymus functions–also known as closures, which in real are objects.
http://php.net/manual/en/functions.anonymous.php
Theses callables have specific functions for extending their scopes.
See: Example #3 Inheriting variables from the parent scope.
$message = 'hello';
// No "use"
$example = function () {
var_dump($message);
};
$example();
// Inherit $message
$example = function () use ($message) {
var_dump($message);
};
$example();
Sure you want to assign a value to the $_GET global var?
$_GET['shop_id'] = $id;
The shop ID in your route you can extract from altorouter parameters. (See documentation.)
$router->map( 'GET', '/', function() { .. }, 'home' );
// assuming current request url = '/'
$match = $router->match();
/*
array(3) {
["target"] => object(Closure)#2 (0) { }
["params"] => array(0) { }
["name"] => 'home'
}
*/
Or if you want to store an ID for a session use $_COOKIES or $_SESSION global variables.
Is it possible in PHP to require an arbitrary file without leaking any variables from the current scope into the required file's variable namespace or polluting the global variable scope?
I'm wanting to do lightweight templating with PHP files and was wondering for purity sake if it was possible to load a template file without any variables in it's scope but the intended ones.
I have setup a test that I would like a solution to pass. It should beable to require RequiredFile.php and have it return Success, no leaking variables..
RequiredFile.php:
<?php
print array() === get_defined_vars()
? "Success, no leaking variables."
: "Failed, leaked variables: ".implode(", ",array_keys(get_defined_vars()));
?>
The closest I've gotten was using a closure, but it still returns Failed, leaked variables: _file.
$scope = function( $_file, array $scope_variables ) {
extract( $scope_variables ); unset( $scope_variables );
//No way to prevent $_file from leaking since it's used in the require call
require( $_file );
};
$scope( "RequiredFile.php", array() );
Any ideas?
Look at this:
$scope = function() {
// It's very simple :)
extract(func_get_arg(1));
require func_get_arg(0);
};
$scope("RequiredFile.php", []);
I've been able to come up with a solution using eval to inline the variable as a constant, thus preventing it from leaking.
While using eval is definitely not a perfect solution, it does create a "perfectly clean" scope for the required file, something that PHP doesn't seem to be able to do natively.
$scope = function( $file, array $scope_array ) {
extract( $scope_array ); unset( $scope_array );
eval( "unset( \$file ); require( '".str_replace( "'", "\\'", $file )."' );" );
};
$scope( "test.php", array() );
EDIT:
This technically isn't even a perfect solution as it creates a "shadow" over the file and scope_array variables, preventing them from being passed into the scope naturally.
EDIT2:
I could resist trying to write a shadow free solution. The executed code should have no access to $this, global or local variables from previous scopes, unless directly passed in.
$scope = function( $file, array $scope_array ) {
$clear_globals = function( Closure $closure ) {
$old_globals = $GLOBALS;
$GLOBALS = array();
$closure();
$GLOBALS = $old_globals;
};
$clear_globals( function() use ( $file, $scope_array ) {
//remove the only variable that will leak from the scope
$eval_code = "unset( \$eval_code );";
//we must sort the var name array so that assignments happens in order
//that forces $var = $_var before $_var = $__var;
$scope_key_array = array_keys( $scope_array );
rsort( $scope_key_array );
//build variable scope reassignment
foreach( $scope_key_array as $var_name ) {
$var_name = str_replace( "'", "\\'", $var_name );
$eval_code .= "\${'$var_name'} = \${'_{$var_name}'};";
$eval_code .= "unset( \${'_{$var_name}'} );";
}
unset( $var_name );
//extract scope into _* variable namespace
extract( $scope_array, EXTR_PREFIX_ALL, "" ); unset( $scope_array );
//add file require with inlined filename
$eval_code .= "require( '".str_replace( "'", "\\'", $file )."' );";
unset( $file );
eval( $eval_code );
} );
};
$scope( "test.php", array() );
After some research, here is what I came up with. The only (clean) solution is to use member functions and instance/class variables.
You need to:
Reference everything using $this and not function arguments.
Unset all globals, superglobals and restore them afterwards.
Use a possible race condition of some sorts. i.e.: In my example below, render() will set instance variables that _render() will use afterwards. In a multi-threaded system, this creates a race condition: thread A may call render() at the same time as thread B and the data will be inexact for one of them. Fortunately, for now, PHP isn't multi-threaded.
Use a temporary file to include, containing a closure, to avoid the use of eval.
The template class I came up with:
class template {
// Store the template data
protected $_data = array();
// Store the template filename
protected $_file, $_tmpfile;
// Store the backed up $GLOBALS and superglobals
protected $_backup;
// Render a template $file with some $data
public function render($file, $data) {
$this->_file = $file;
$this->_data = $data;
$this->_render();
}
// Restore the unset superglobals
protected function _restore() {
// Unset all variables to make sure the template don't inject anything
foreach ($GLOBALS as $var => $value) {
// Unset $GLOBALS and you're screwed
if ($var === 'GLOBALS') continue;
unset($GLOBALS[$var]);
}
// Restore all variables
foreach ($this->_backup as $var => $value) {
// Set back all global variables
$GLOBALS[$var] = $value;
}
}
// Backup the global variables and superglobals
protected function _backup() {
foreach ($GLOBALS as $var => $value) {
// Unset $GLOBALS and you're screwed
if ($var === 'GLOBALS') continue;
$this->_backup[$var] = $value;
unset($GLOBALS[$var]);
}
}
// Render the template
protected function _render() {
$this->_backup();
$this->_tmpfile = tempnam(sys_get_temp_dir(), __CLASS__);
$code = '<?php $render = function() {'.
'extract('.var_export($this->_data, true).');'.
'require "'.$this->_file.'";'.
'}; $render();'
file_put_contents($this->_tmpfile, $code);
include $this->_tmpfile;
$this->_restore();
}
}
And here's the test case:
// Setting some global/superglobals
$_GET['get'] = 'get is still set';
$hello = 'hello is still set';
$t = new template;
$t->render('template.php', array('foo'=>'bar', 'this'=>'hello world'));
// Checking if those globals/superglobals are still set
var_dump($_GET['get'], $hello);
// Those shouldn't be set anymore
var_dump($_SERVER['bar'], $GLOBALS['stack']); // undefined indices
And the template file:
<?php
var_dump($GLOBALS); // prints an empty list
$_SERVER['bar'] = 'baz'; // will be unset later
$GLOBALS['stack'] = 'overflow'; // will be unset later
var_dump(get_defined_vars()); // foo, this
?>
In short, this solution:
Hides all globals and superglobals. The variables themselves ($_GET, $_POST, etc.) can still be modified, but they will revert back to what they were previously.
Does not shadow variables. (Almost) everything can be used, including $this. (Except for $GLOBALS, see below).
Does not bring anything into scope that wasn't passed.
Does not lose any data nor trigger destructors, because the refcount never reaches zero for any variable.
Does not use eval or anything like that.
Here's the result I have for the above:
array(1) {
["GLOBALS"]=>
*RECURSION*
}
array(2) {
["this"]=>
string(11) "hello world"
["foo"]=>
string(3) "bar"
}
string(10) "get is still set"
string(12) "hello is still set"
Notice: Undefined index: bar in /var/www/temp/test.php on line 75
Call Stack:
0.0003 658056 1. {main}() /var/www/temp/test.php:0
Notice: Undefined index: stack in /var/www/temp/test.php on line 75
Call Stack:
0.0003 658056 1. {main}() /var/www/temp/test.php:0
NULL
NULL
If you dump $GLOBALS after the fact it should be just like it was before the call.
The only possible issue is that someone still can execute something like:
unset($GLOBALS);
... and you're screwed. And there is no way around that.
If you need a very simple templating engine, your approach with a function is good enough.
Tell me, what are the real disadvantages of exposing that $_file variable?
If you need to do real work, grab Twig and stop worrying.
Any proper templating engine compiles your templates into pure PHP anyway, so you don't lose
speed. You also gain significant advantages - simpler syntax, enforced htmlspecialchars and other.
You could always hide your $_file in a superglobal:
$_SERVER['MY_COMPLEX_NAME'] = $_file;
unset($_file);
include($_SERVER['MY_COMPLEX_NAME']);
unset($_SERVER['MY_COMPLEX_NAME']);
Is it possible to define private variables in a PHP script so these variables are only visible in this single PHP script and nowhere else? I want to have an include file which does something without polluting the global namespace. It must work with PHP 5.2 so PHP namespaces are not an option. And no OOP is used here so I'm not searching for private class members. I'm searching for "somewhat-global" variables which are global in the current script but nowhere else.
In C I could do it with the static keyword but is there something similar in PHP?
Here is a short example of a "common.php" script:
$dir = dirname(__FILE__);
set_include_path($dir . PATH_SEPARATOR . get_include_path());
// Do more stuff with the $dir variable
When I include this file in some script then the $dir variable is visible in all other scripts as well and I don't want that. So how can I prevent this?
There are a few things you could do to keep $dir out of subsequent files
Example 1
set_include_path(dirname(__FILE__) . PATH_SEPARATOR . get_include_path());
This is the most obvious.
Example 2
$dir = dirname(__FILE__);
set_include_path($dir . PATH_SEPARATOR . get_include_path());
// work with $dir
unset($dir);
Just unset the variable after defining it and using it. Note this will unset any variable named $dir used prior to including this script.
Example 3
define('DIR_THIS', dirname(__FILE__));
set_include_path(DIR_THIS . PATH_SEPARATOR . get_include_path());
It is less likely I suppose to redefine a global constant like this.
Example 4
function my_set_include_path {
$dir = dirname(__FILE__);
set_include_path($dir . PATH_SEPARATOR . get_include_path());
// Do more stuff with the $dir variable
$my_other_var = 'is trapped within this function';
}
my_set_include_path();
You can define as many variables within that function and not affect the global namespace.
Conclusion
The first method is the easiest way to solve this problem, however because you want to use $dir again, it may not be ideal. The last example will at least keep that $dir (and any others defined in that function) out of the global namespace.
The only way you're going to accomplish anything close to what you want is to wrap everything in that included file in a function, and call it. If the file needs to execute itself you could still do
<?php
run_myfile()
function run_myfile() {
...
}
?>
There is no generic way to make a variable scoped to only a file outside of namespaces, classes, or functions.
Well, I'm probably getting flailed for this, but you if you are totally desperate you could use a Registry for that. I've whipped up a small one that does without classes (since I assume from And no OOP is used here so I'm not searching for private class members. means you don't want to do it with OOP at all)
function ®istry_get_instance()
{
static $data = array();
return $data;
}
The static $data variable inside is persisted inside the function scope, so you can call the function wherever you like and always get the same contents. The crucial point is returning by reference, e.g.
$registry = ®istry_get_instance(); // get $data array by reference
$registry['foo'] = 'bar'; // set something to $data
unset($registry); // delete global reference to $data
print_r(®istry_get_instance()); // show $data
Obviously you'd still have $registry as a variable in the global scope when calling this method from the global scope. So, you could add some more functions to make the Registry more convenient to use, e.g. for setting data to the Registry:
function registry_set($key, $value)
{
$registry = ®istry_get_instance();
$registry[$key] = $value;
}
and for getting it out again:
function registry_get($key)
{
$registry = ®istry_get_instance();
if(array_key_exists($key, $registry)) {
return $registry[$key];
} else {
trigger_error(sprintf(
'Undefined Index: %s', htmlentities($key)
), E_USER_NOTICE);
}
}
and for checking if a key exists:
function registry_isset($key)
{
$registry = ®istry_get_instance();
return array_key_exists($key, $registry);
}
which you could then use like:
registry_set('foo', 'bar'); // setting something to the registry
var_dump( registry_isset('foo') ); // check foo is in the registry now
echo registry_get('foo'); // prints 'bar'
echo registry_get('punt'); // raises Notice
You could populate the Registry from an include file with an additional method like this:
function registry_load_file($file)
{
if(!is_readable(realpath($file))) {
return trigger_error(sprintf(
'File is not readable: %s', htmlentities($file)
), E_USER_WARNING);
}
$config = include $file;
if(!is_array($config)) {
return trigger_error(sprintf(
'Expected file %s to return an array', htmlentities($file))
, E_USER_WARNING);
}
$registry = ®istry_get_instance();
$registry += $config;
}
with the include file having to return an array:
// config.php
return array(
'setting1' => 'something'
);
and then you can do
registry_load_from_file('config.php'); // add the contents of config to registry
print_r(registry_get_instance()); // show content of registry
Of course, this is now six functions in the global scope just for not having a global variable. Don't know if it's worth it, especially since I consider static in functions and all that reference stuff doubtful practice.
Take it as a proof of concept :)
Why not just put everything in a static class? Then you only have a single "variable" that could possibly conflict with the global namespace.
class MyClass {
public static $myvar = 1;
public static $myvar2 = "xyz";
public static function myfunction() {
self::$myvar++;
self::$myvar2 = "abc";
}
}
// References to class items, if needed
MyClass::myfunction();
MyClass::$myvar += 3;
If the problem you are trying to is just:
$dir = dirname(__FILE__);
set_include_path($dir . PATH_SEPARATOR . get_include_path());
// Do more stuff with the $dir variable
Then the solution would be to change the include path relative to '.' in your ini settings. E.g. change:
include_path=includes:/usr/local/php
to
include_path=./includes:/usr/local/php
Note that a script does not come into scope except where you explicitly include/require it (both the _once check applies globally) however I would recommend strongly against calling include/require from within a function - its much more transparent having the includes/requires at the top of the script.
I think that the problem you are trying to solve is based on a false premise and you should look for another way of fixing it. If you want the code in an include file to behave differently depending on what includes it, then really you should seperate it out into 2 seperate files - or maybe even 3 - 2 for the different behaviours and 1 for the common.
C.