запустить функциональный блок в контексте глобального пространства имен в PHP

Таким образом, senario заключается в том, что я хочу иметь пользовательскую функцию для запросов библиотек. Что-то вроде:

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; // !!! } 

Проблема в том, что require и require_once будут загружать файлы в пространство имен функции, что не помогает библиотекам функций, классов и т. Д. Так есть способ сделать это?

(Что-то избегая require и require_once вообще нормально, если оно не использует eval поскольку оно запрещено на таком количестве хостов).

Благодаря!

Технически include() должен действовать так, как если бы вы вставляли текст включенного скрипта в этот момент вашего PHP. Таким образом:

 includeMe.php: <?php $test = "Hello, World!"; ?> includeIt.php: <?php include('includeMe.php'); echo $test; ?> в includeMe.php: <?php $test = "Hello, World!"; ?> includeIt.php: <?php include('includeMe.php'); echo $test; ?> 

Должно быть то же самое, что:

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

Понимая это, идея создания функции для динамического включения файлов имеет примерно такой же смысл (и примерно такой же простой), что и общий динамический код. Это возможно, но это будет связано с большим количеством мета-переменных.

Я бы посмотрел Variable Variables в PHP, а также функцию get_defined_vars для переноса переменных в глобальную область. Это можно сделать с помощью чего-то вроде:

 <?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]; } } ?> 

Возможно, более удобно просто использовать require() и require_once() вместо e_load()

Обратите внимание, что функции и константы всегда должны находиться в глобальной области, поэтому независимо от того, где они определены, они должны быть доступны из любого места в вашем коде.

Единственное исключение – функции, определенные внутри класса. Они могут быть вызваны только в пространстве имен класса.

РЕДАКТИРОВАТЬ:

Я просто испытал это сам. Функции объявляются в глобальной области. Я выполнил следующий код:

 <?php function test(){ function test2(){ echo "Test2 was called!"; } } //test2(); <-- failed test(); test2(); // <-- succeeded this time ?> 

Таким образом, функция была определена только после запуска test() , но после этого функция была вызвана вне test() . Поэтому единственное, что вам нужно, чтобы втянуть в глобальную область действия, – это ваши переменные, используя ранее предоставленный мной сценарий.

 require_once E_ROOT.$libName.'.php'; 

ПОЦЕЛУЙ

Вместо этого …

 $test = "Hello, World!"; 

… вы могли бы подумать об этом …

 $GLOBALS[ 'test' ] = "Hello, World!"; 

Это безопасно и согласовано как в контексте локальных функций, так и в глобальном контексте. Наверное, не вредно визуально напоминать читателю, что вы ожидаете, что $ test станет глобальным. Если у вас есть большое количество глобалов, которые перетаскиваются вашими библиотеками, возможно, есть оправдание для их переноса в класс (тогда у вас есть преимущество spl_autoload_register, который делает то, что вы делаете).