Пришлось подробно изучить вопрос откуда в Битриксе «неожиданно» возникают глобальные переменные. В некоторых случаях между $CODE и $_REQUEST["CODE"] нет разницы.
Рассмотрим страницу /index.php?CODE=Artemy
Странно? Почему $CODE содержит значение? Первая мысль: «настройка включена». Но на виртуальной машине и на хостинге она выключена. Тем более известно, что эта опция потенциально опасна при неправильном использовании и даже удалена в версии php 5.4.0.
После длительного исследования была найдена функция, которая вызывается при подключении заголовка /bitrix/header.php:
Что она делает? Сначала чуть-чуть теории PHP.
На странице /index.php любая используемая переменная будет глобальной. $GLOBALS или global писать не надо.
Внутри функций своё изолированное пространство имен, и к глобальной переменной можно обращаться через массив $GLOBALS или ключевое слово global.
Фрагмент функции FormDecode() делает из переменной $_GET["CODE"] глобальную переменную $CODE. Поэтому /index.php?CODE=Artemy всегда создает переменную $CODE=Artemy:
Аналогично из $_SERVER["DOCUMENT_ROOT"] получается глобальная переменная $DOCUMENT_ROOT.
Выводы:
Несмотря на то, что сейчас везде PHP 5.3 и PHP 5.4, в Битриксе эмулируется register_globals=on. Это означает, что переменные перед использованием на странице надо объявлять. Иначе они могут быть неожиданно получены из URL.
Компонент вызывается функцией $APPLICATION->IncludeComponent(), значит в нем пространство имен изолировано.
Включаемый файл вызывается функцией $APPLICATION->IncludeFile(). В нем тоже пространство имен изолировано.
Настоятельно не рекомендуется писать код на странице. Пишите код внутри компонентов, или во включаемых файлах, или в функциях.
На странице можно писать короче $CODE вместо $_REQUEST["CODE"]. Но лучше $_REQUEST["CODE"], потому что такой код при копировании в другое место не вызовет странных ошибок.
Рассмотрим страницу /index.php?CODE=Artemy
<?require($_SERVER["DOCUMENT_ROOT"]."/bitrix/header.php");?> <? echo $CODE; // вернет Artemy ?> <?require($_SERVER["DOCUMENT_ROOT"]."/bitrix/footer.php");?> |
После длительного исследования была найдена функция, которая вызывается при подключении заголовка /bitrix/header.php:
function FormDecode()
{
global $HTTP_ENV_VARS, $HTTP_GET_VARS, $HTTP_POST_VARS, $HTTP_POST_FILES, $HTTP_COOKIE_VARS, $HTTP_SERVER_VARS;
$superglobals = Array('_GET'=>1, '_SESSION'=>1, '_POST'=>1, '_COOKIE'=>1, '_REQUEST'=>1, '_FILES'=>1, '_SERVER'=>1, 'GLOBALS'=>1, '_ENV'=>1, 'DBSQLServerType'=>1);
foreach($superglobals as $gl=>$t)
{
unset($_REQUEST[$gl]);
unset($_GET[$gl]);
unset($_POST[$gl]);
unset($_COOKIE[$gl]);
}
$register_globals = ini_get_bool("register_globals");
if (!$register_globals)
{
$HTTP_ENV_VARS = $_ENV;
foreach($_ENV as $key => $val)
if(!isset($superglobals[$key]))
$GLOBALS[$key] = $val;
$HTTP_GET_VARS = $_GET;
foreach($_GET as $key => $val)
if(!isset($superglobals[$key]))
$GLOBALS[$key] = $val;
$HTTP_POST_VARS = $_POST;
foreach($_POST as $key => $val)
if(!isset($superglobals[$key]))
$GLOBALS[$key] = $val;
$HTTP_POST_FILES = $_FILES;
foreach($_FILES as $key => $val)
if(!isset($superglobals[$key]))
$GLOBALS[$key] = $val;
$HTTP_COOKIE_VARS = $_COOKIE;
foreach($_COOKIE as $key => $val)
if(!isset($superglobals[$key]))
$GLOBALS[$key] = $val;
$HTTP_SERVER_VARS = $_SERVER;
foreach($_SERVER as $key => $val)
if(!isset($superglobals[$key]))
$GLOBALS[$key] = $val;
}
} |
Что она делает? Сначала чуть-чуть теории PHP.
На странице /index.php любая используемая переменная будет глобальной. $GLOBALS или global писать не надо.
Внутри функций своё изолированное пространство имен, и к глобальной переменной можно обращаться через массив $GLOBALS или ключевое слово global.
<?// index.php
// Пример 1. Установка глобальной переменной до функции
function ShowGlobalValue()
{
echo $GLOBALS["value"];
}
$value = 1;
ShowGlobalValue(); // покажет 1
?> |
<?// index.php
// Пример 2. Установка глобальной переменной внутри функции
function SetGlobalValue()
{
$GLOBALS["value"] = "1";
}
SetGlobalValue();
echo $value; // покажет 1
?> |
Фрагмент функции FormDecode() делает из переменной $_GET["CODE"] глобальную переменную $CODE. Поэтому /index.php?CODE=Artemy всегда создает переменную $CODE=Artemy:
foreach($_GET as $key => $val) if(!isset($superglobals[$key])) $GLOBALS[$key] = $val; |
Аналогично из $_SERVER["DOCUMENT_ROOT"] получается глобальная переменная $DOCUMENT_ROOT.
Выводы:
Несмотря на то, что сейчас везде PHP 5.3 и PHP 5.4, в Битриксе эмулируется register_globals=on. Это означает, что переменные перед использованием на странице надо объявлять. Иначе они могут быть неожиданно получены из URL.
Компонент вызывается функцией $APPLICATION->IncludeComponent(), значит в нем пространство имен изолировано.
Включаемый файл вызывается функцией $APPLICATION->IncludeFile(). В нем тоже пространство имен изолировано.
Настоятельно не рекомендуется писать код на странице. Пишите код внутри компонентов, или во включаемых файлах, или в функциях.
На странице можно писать короче $CODE вместо $_REQUEST["CODE"]. Но лучше $_REQUEST["CODE"], потому что такой код при копировании в другое место не вызовет странных ошибок.
