Таким образом, 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, который делает то, что вы делаете).