Есть ли способ установить область require_once() явно глобально?
Я ищу способ задать область require_once()
для глобальной области, когда require_once()
используется внутри функции. Что-то вроде следующего кода должно работать:
файл `foo.php ':
<?php
$foo = 42;
действительный код:
<?php
function includeFooFile() {
require_once("foo.php"); // scope of "foo.php" will be the function scope
}
$foo = 23;
includeFooFile();
echo($foo."\n"); // will print 23, but I want it to print 42.
Есть ли способ явно установить область require_once()
? Хорошее обходное решение?
Ответы
Ответ 1
Вы можете использовать эту хакерскую функцию, которую я написал:
/**
* Extracts all global variables as references and includes the file.
* Useful for including legacy plugins.
*
* @param string $__filename__ File to include
* @param array $__vars__ Extra variables to extract into local scope
* @throws Exception
* @return void
*/
function GlobalInclude($__filename__, &$__vars__ = null) {
if(!is_file($__filename__)) throw new Exception('File ' . $__filename__ . ' does not exist');
extract($GLOBALS, EXTR_REFS | EXTR_SKIP);
if($__vars__ !== null) extract($__vars__, EXTR_REFS);
unset($__vars__);
include $__filename__;
unset($__filename__);
foreach(array_diff_key(get_defined_vars(), $GLOBALS) as $key => $val) {
$GLOBALS[$key] = $val;
}
}
Он перемещает все вновь определенные vars обратно в глобальное пространство, когда возвращается файл include. Там предостережение, что если включенный файл содержит другой файл, он не сможет получить доступ к любым переменным, определенным в родительском файле, через $GLOBALS
, потому что они еще не были глобализованы.
Ответ 2
Помимо "глобализации" вашей переменной, нет никакого способа сделать это:
global $foo;
$foo = 42;
ИЛИ
$GLOBALS['foo'] = 42;
Тогда при печати вы должны указать 42.
UPDATE
Что касается включения классов или функций, обратите внимание, что все функции и классы всегда считаются глобальными, если мы не говорим о методе класса. В этот момент метод в классе доступен только из самого определения класса, а не как глобальная функция.
Ответ 3
Это определенно не "хорошая" работа, но она будет работать:
function includeFooFile() {
require_once("foo.php");
foreach (get_defined_vars() as $key => $value) {
// Ignore superglobals
if (!in_array($key, array('GLOBALS','_SERVER','_GET','_POST','_FILES','_COOKIE','_SESSION','_REQUEST','_ENV'))) {
$GLOBALS[$key] = $value;
}
}
}
Однако ваш включенный файл не может определять какие-либо функции или классы (и, возможно, некоторые другие вещи, о которых я не могу сейчас думать), потому что это приведет к ошибке синтаксического анализа, поскольку вы не можете вставлять классы или функции.
EDIT, видимо, вы можете включить функции в свой файл. Я всегда думал, что ты не можешь, но после тестирования кажется, что ты можешь.
Ответ 4
Вам нужно объявить глобальное значение в foo.php
:
<?php
global $foo;
$foo = 42;
?>
В противном случае это возможно не возможно.
Вы можете попробовать поиграть с extract()
, get_defined_vars()
, global
и $GLOBALS
в различных комбинациях, возможно... как итерация по всем определенным переменным и вызов глобальных на них, прежде чем требуется файл...
$vars = get_defined_vars();
foreach($vars as $varname => $value)
{
global $$varname; //$$ is no mistake here
}
require...
Но я не совсем уверен, если вы доберетесь туда, куда захотите...
Ответ 5
Поскольку область видимости явно определена, где вы используете require
и тому подобное, вам нужно указать, что делать с переменными внутри области действия функции:
function includeFooFile() {
require_once("foo.php"); // scope of "foo.php" will be the function scope
foreach (get_defined_vars() as $k => $v)
{
$GLOBALS[$k] = &$v;
}
}
В этом примере рассматриваются как переменные, так и ссылки, которые могут быть тем, что вы ищете. Демо. Обратите внимание, что require_once
будет работать только один раз и будет только определять переменные один раз.
Ответ 6
В ожидании ваших конкретных требований вы можете использовать constants. Требовать свой файл в глобальной области, но внутри он устанавливает константу.
IE file.php:
define('MY_CONSTANT', 42);
Тогда в любом месте вашего script просто используйте MY_CONSTANT
, чтобы ссылаться на это значение, вы не сможете редактировать его после его установки. Помимо этого, вы можете глобализовать переменную, как говорит другой ответ, но она не на 100% не позволяет понять, чего вы пытаетесь достичь, а не просто извлекать значение из включенного файла? В этом случае константы должны быть точными.
Update:
Теперь вы объяснили, что хотите, чтобы свойства объектов были доступны повсюду, я предлагаю вам изучить статический класс который после создания экземпляра в вашем глобальную область можно использовать в любом месте приложения. Прочтите связанную страницу руководства, она имеет пример с голубыми костями.
Ответ 7
Я не пробовал (поскольку использование глобальных vars - плохая идея tbh), но это потенциально может работать:
require_once '...';
$GLOBALS = array_merge($GLOBALS, get_defined_vars());
В качестве альтернативы вы можете просто сделать это вручную:
foreach (get_defined_vars() as $k => $v) {
$GLOBALS[$k] = $v;
}