Подтвердить что ты не робот

Есть ли способ установить область 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()? Хорошее обходное решение?

4b9b3361

Ответ 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;
}