#php #variables #scope #defined
#php #переменные #область видимости #определено
Вопрос:
Я пытаюсь создать функцию для получения всех пользовательских переменных для выборочного их сброса до фактического завершения скрипта. Чтобы получить все используемые переменные, вы должны использовать get_defined_vars()
функцию, которую предоставляет вам PHP, но у нее есть предостережение (по крайней мере, для меня …): она работает только в той области, в которой она фактически вызвана.
Я хотел бы, в идеале, инкапсулировать его в функцию внутри моего основного пространства имен framework, HelpersCore
таким образом, функция будет HelpersCoregetVariables()
.
На самом деле, мой код выглядит так:
foreach (array_diff(array_keys(get_defined_vars()), ["_COOKIE", "_ENV", "_FILES", "_GET", "_POST", "_REQUEST", "_SERVER", "_SESSION", "argc", "argv", "GLOBALS", "HTTP_RAW_POST_DATA", "http_response_header", "ignore", "php_errormsg"], ["page"]) as $variable) {
unset($variable);
}
По сути, он пытается автоматизировать выбор переменных с помощью:
- получение всех имен переменных с помощью
array_keys(get_defined_vars())
- определение набора зарезервированных или общесистемных переменных, таких как
$_GET
,$_POST
,$_SERVER
и так далее - при условии, какие из ваших используемых переменных сохранены (в этом примере,
$page
)
Проблема в том, что я не хотел бы размещать этот код везде, где я хочу избавиться от некоторых переменных. В идеале я хотел бы иметь возможность определить это как функцию и автоматизировать ее использование, но … есть ли способ выполнить это, но в текущем скрипте, из которого вы вызываете функцию?
Комментарии:
1. Используйте
$GLOBAL
для получения переменных в глобальной области видимости и передачи результатаget_defined_vars
в качестве аргумента вашей функции.2. может быть, вы можете сохранить в сеансе или файле cookie?
3. Это то, что я имел в виду … функция для вставки некоторых имен переменных
$_SESSION
, поэтому вместо третьего члена["page"]
(как в примере выше) его можно автоматизировать, указав что-то подобноеHelpersCoregetVariables()
или подобное. Я хотел избежать выполнения большего количества шагов, чем на самом деле необходимо, но, возможно, это единственный «гарантированный» способ его работы…
Ответ №1:
Вы можете использовать $GLOBALS
вместо get_defined_vars()
для доступа к глобальной области видимости и для отмены установки глобальных переменных:
$non_user_vars = ["_COOKIE", "_ENV", "_FILES", "_GET", "_POST", "_REQUEST",
"_SERVER", "_SESSION", "argc", "argv", "GLOBALS",
"HTTP_RAW_POST_DATA", "http_response_header",
"ignore", "php_errormsg"];
$safe_user_vars = ["page"];
$all_vars = array_keys($GLOBALS);
$user_vars = array_diff($all_vars, $non_user_vars, $safe_user_vars);
foreach($user_vars as $variable) {
unset($GLOBALS[$variable]);
}
Быстрые предостережения к этому подходу:
- чтобы сделать его более чистым, я сначала определил массивы. Это может привести к их попаданию в ваш
$user_vars
массив (думал, что этого не должно быть, если они не являются глобальными), поэтому защищайтесь от этого, чтобы избежать возникновения ошибки или других последствий. - Ваш массив непользовательских переменных не является исчерпывающим, так как, когда я тестировал выше, я все равно получил:
Array ( [2] => HTTP_ENV_VARS [6] => HTTP_POST_VARS [8] => HTTP_GET_VARS [10] => HTTP_COOKIE_VARS [12] => HTTP_SERVER_VARS [14] => HTTP_POST_FILES [16] => test [17] => non_user_vars )
Если вы не хотите угадывать, что предопределено или видно во время выполнения, возможно, может быть начальный вызов HelpersCoregetVariables()
, который получает список переменных и сохраняет их статически, поэтому вам array_diff
просто нужно сравнить начальный список со списком в конце, чтобы узнать, что определено пользователем.
Комментарии:
1. Хорошо, теперь это другая история. У меня не было цели для $GLOBALS, пока я не запустил ваш пример. Извините за путаницу и большое вам спасибо за подсказку. Теперь метод работает отлично! Я должен тебе пиво 🙂