views:

39

answers:

2

So the senario is that I want to have a custom function for requiring libraries. Something like:

define('E_ROOT', str_replace('//','/',dirname(__FILE__)));
/* ... */
function e_load($fn, $allowReloading = FALSE) {
    $inc = E_ROOT.'/path/here/'.$fn.'.php';
    if($allowReloading)
        require $inc; // !!!
    else
        require_once $inc; // !!!
}

The problem being that require and require_once will load the files into the namespace of the function, which doesn't help for libraries of functions, classes, et cetera. So is there a way to do this?

(Something avoiding require and require_once altogether is fine, as long as it doesn't use eval since it's banned on so many hosts.)

Thanks!

A: 
require_once E_ROOT.$libName.'.php';

KISS

Col. Shrapnel
I only hope that libName is not coming from the user input
Col. Shrapnel
I mean $libName to be from the function. And, yes—this works. But for say 10 different files, it's a lot of repetition to not be in a file.
aharon
Contrast that with `e_load('libName')`.
aharon
@aharon you have aleady typed 10 times more by typing your question. Sometimes we complicate things in pursue of ease them
Col. Shrapnel
I legitimately don't understand the need for an e_load function unless you wanted users to be able to specify files to include, in which case you'd want to parse their input to be sure they weren't including any dangerous files. Although it is possible. You just have to pull variables into the global scope.
steven_desu
+1  A: 

Technically include() is meant to act as though you're inserting the text of included script at that point in your PHP. Thus:

includeMe.php:
<?php
    $test = "Hello, World!";
?>

includeIt.php:
<?php
    include('includeMe.php');
    echo $test;
?>

Should be the exact same as:

<?php
    /* INSERTED FROM includeMe.php */
    $test = "Hello, World!";
    /* END INSERTED PORTION */
    echo $test;
?>

Realizing this, the idea of making a function for dynamically including files makes about as much sense (and is about as easy to do) as having dynamic code all-together. It's possible, but it will involve a lot of meta-variables.

I'd look into Variable Variables in PHP as well as the get_defined_vars function for bringing variables into the global scope. This could be done with something like:

<?php
define('E_ROOT', str_replace('//','/',dirname(__FILE__)));
/* ... */
function e_load($fn, $allowReloading = FALSE) {

    $prev_defined_vars = get_defined_vars();

    $inc = E_ROOT.'/path/here/'.$fn.'.php';
    if($allowReloading)
        require $inc; // !!!
    else
        require_once $inc; // !!!

    $now_defined_vars = get_defined_vars();

    $new_vars = array_diff($now_defined_vars, $prev_defined_vars);

    for($i = 0; $i < count($new_vars); $i++){
        // Pull new variables into the global scope
        global $$newvars[$i];
    }
}
?>

It may be more convenient to just use require() and require_once() in place of e_load()

Note that functions and constants should always be in the global scope, so no matter where they are defined they should be callable from anywhere in your code.

The one exception to this is functions defined within a class. These are only callable within the namespace of the class.

EDIT:

I just tested this myself. Functions are declared in the global scope. I ran the following code:

<?php
function test(){
    function test2(){
        echo "Test2 was called!";
    }
}

//test2(); <-- failed
test();
test2(); // <-- succeeded this time
?>

So the function was only defined after test() had been run, but the function was then callable from outside of test(). Therefore the only thing you should need to pull into the global scope are your variables, via the script I provided earlier.

steven_desu