get_defined_vars

(PHP 4 >= 4.0.4, PHP 5, PHP 7, PHP 8)

get_defined_vars 返回所有已定义变量的数组

描述

get_defined_vars(): array

此函数返回一个多维数组,包含在调用 get_defined_vars() 的作用域中定义的所有变量的列表,无论是环境变量、服务器变量还是用户定义的变量。

参数

此函数没有参数。

返回值

包含所有变量的多维数组。

示例

示例 #1 get_defined_vars() 示例

<?php
$b
= array(1, 1, 2, 3, 5, 8);

$arr = get_defined_vars();

// 打印 $b
print_r($arr["b"]);

/* 打印到 PHP 解释器的路径(如果用作 CGI)
* 例如 /usr/local/bin/php */
echo $arr["_"];

// 打印所有命令行参数(如果有)
print_r($arr["argv"]);

// 打印所有服务器变量
print_r($arr["_SERVER"]);

// 打印变量数组的所有可用键
print_r(array_keys(get_defined_vars()));
?>

参见

添加注释

用户贡献的注释 20 个注释

cmswares dot com at gmail dot com
2 年前
注意 get_defined_vars() 函数在不同上下文中的返回值

- 在全局作用域中,所有已定义变量的列表,无论是超级全局变量、命令行参数还是用户定义的变量
- 在函数作用域中,只有用户定义的变量列表(包括参数和函数体内的定义)
- 在类/对象方法作用域中,不返回类/对象属性;

此外,从 PHP 5.4 开始,即使可用,也不返回 $_ENV。

有关更多详细信息和作用域测试/结果,请参见 https://github.com/php/doc-en/issues/1317
antonfedonyuk at gmail dot com
3 年前
注意:当您使用 eval() 调用代码时,PHP 会将自身变量附加到结果中,它们具有 "__" 前缀(在 PHP 7.3 中为 "__source_code" 和 "__bootstrap_file")。

修复
<?php
function filter_eval_vars(array $vars): array
{
foreach (
$vars as $key => $value) {
if (
$key[0] === '_' && $key[1] === '_') {
unset(
$vars[$key]);
}
}
return
$vars;
}

?>
Qiibow
2 年前
get_defined_vars() 非常适合一次导入多个值
到另一个作用域(例如用户定义的函数)。

以下是一个示例,用于在表格中显示一些值及其变量名。
(在调试中很有用)

您可以在脚本中的多个位置放置此用户定义的函数
以显示一些值(要在循环中更改的值)
以检查它们是否与预期的一致。

<?php
// 将 "get_defined_vars()" 设置为第二个参数。
function get_value_table($name_array, $gdv) {
$name_value_table = [];
foreach (
$name_array as $name) :
if (!
array_key_exists($name, $gdv)) :
$value = 'undefined';
elseif (
is_bool($gdv[$name])) :
$value = $gdv[$name]? 'true' : 'false';
elseif (
is_numeric($gdv[$name]) || is_string($gdv[$name])) :
$value = $gdv[$name];
elseif (
is_array($gdv[$name])) :
$value = '<pre>'.print_r($gdv[$name],true).'</pre>';
else :
$value = (PHP_VERSION_ID >= 80000)? get_debug_type($gdv[$name]) : get_type($gdv[$name]);
endif;
$name_value_table[] = '<tr><td>$'.$name.'<td>'.$value;
endforeach;
return
'<table border=1>'.implode("\n", $name_value_table).'</table>';
}
// (f) get_value_table()

$_1 = 'a';
$_2 = 'b';
$_3 = [1,2];
$_4 = false;
$_5 = null;

$name_array = ['_1','_2','_3','_4','_5','_6'];
$show_id = 1;

if (
$show_id === 1) :
echo
get_value_table($name_array, get_defined_vars());
endif;
/*
如果 $show_id === 1,只会显示以下内容。

$_1 a
$_2 b
$_3 Array
(
[0] => 1
[1] => 2
)
$_4 false
$_5 null
$_6 undefined
*/

$_2 = 'c';
if (
$show_id === 2) :
echo
get_value_table($name_array, get_defined_vars()); // $_2 c
endif;
# 如果 $show_id === 2,$_2 变为 "c"。

?>
zabmilenko at hotmail dot com
17 年前
一个小陷阱要注意

如果你关闭了 RegisterGlobals 和相关设置,然后使用 get_defined_vars(),你可能会看到如下内容

<?php
Array
(
[
GLOBALS] => Array
(
[
GLOBALS] => Array
*
RECURSION*
[
_POST] => Array()
[
_GET] => Array()
[
_COOKIE] => Array()
[
_FILES] => Array()
)

[
_POST] => Array()
[
_GET] => Array()
[
_COOKIE] => Array()
[
_FILES] => Array()

)
?>

注意 $_SERVER 不存在。 似乎只有在某个地方使用它时,php 才会加载超级全局变量 $_SERVER。你可以这样做

<?php
print '<pre>' . htmlspecialchars(print_r(get_defined_vars(), true)) . '</pre>';
print
'<pre>' . htmlspecialchars(print_r($_SERVER, true)) . '</pre>';
?>

然后 $_SERVER 会出现在两个列表中。 我想这并不算是一个陷阱,因为无论哪种方式都不会发生什么不好的事情,但这仍然是一个有趣的发现。
ryanlwh at yahoo dot com
11 年前
由于 get_defined_vars() 只获取你在调用函数时定义的变量,所以有一种简单的方法可以获取当前作用域中定义的变量。

<?php
// PHP 脚本的最顶端
$vars = get_defined_vars();

// 现在执行你的操作
$foo = 'foo';
$bar = 'bar';

// 获取当前作用域中定义的所有变量
$vars = array_diff(get_defined_vars(),$vars);

echo
'<pre>';
print_r($vars);
echo
'</pre>';
?>
nix dot code at 4assistance dot com dot nix
3 年前
在感兴趣的位置插入这段代码;将不需要的第一个维度变量的键添加到 array_diff_key 的第二个参数中
<?php
echo '<pre>defined_except '; var_dump (array_diff_key (get_defined_vars(), ['GLOBALS'=>0,'_SERVER'=>0])); echo ' '.basename(__FILE__).':'.__LINE__.'</pre>'; #die;
?>
sergeyzuzic at mail dot ru
8 年前
脏代码示例

print_r(compact(array_keys(get_defined_vars())));
mail at mkharitonov dot net
10 年前
引用变量是通过引用返回的(在 PHP 5.5.11 上测试)
<?php
$a
= null;
$b = &$a;
get_defined_vars()['b'] = 4;
var_dump($b); // int(4)
?>
Joey
6 年前
我偶尔会用它作为一种 hack 将参数转换为数组,在需要简洁的情况下(处理遗留代码等)。

但是,在对象上下文中,它也会拉入 $this。

确保将其 unset。 如果你将它映射到属性或数组,那么设置键 this 不会出错。

我建议使用一个包装函数,它将 this 从结果中剥离。
npelov at croler dot net
3 年前
get_defined_vars() 返回所有变量 - 局部定义的变量和全局变量(实际上只是超级全局变量)。如果你只需要局部变量 - 例如你需要从一个文件获取变量 - 比如 config.php,并且你不想让一个缺失的值被一个在其他地方定义的全局变量替换。

<?php

/**
* 过滤掉 get_defined_vars() 中的全局变量,以获取仅局部变量
* @param array $localVars 将 get_defined_vars() 传递到这里
*
* @return array 仅局部变量
*/
function removeGlobals(array $localVars) {
return
array_diff_key($localVars, $GLOBALS);
}

define('CONFIG_FILE_PATH', '/path/to/config.php');
function
readConfig() {
require
CONFIG_FILE_PATH;
$config = removeGlobals(get_defined_vars());
return
$config;
}

?>
Joey
6 年前
这里的一些评论指出,这个函数不会返回引用。 但是它确实返回名称,而名称是“引用”。

我不建议这里将它转换为引用的建议。

相反...

public function x($a, $b, $c) {
foreach(array_keys(get_defined_vars()) as $key)
if($key !== 'this')
$this->y(${$key});
}

public function y(&$input) {
$input++;
}

除了 ${} 之外,你也可以使用 $$。

我在我的时代做过一些怪异的事情来编写非常通用的代码,但我从未做过像上面那样的操作。 它甚至可能不起作用(但应该起作用,因为它与 $a[$key] 没有区别)。

你也可以使用 `$$key++`,但我从未见过这种代码,除了那些糟糕透顶的代码(在没有益处的情况下使用动态变量)。

如果你要这样做,那么要仔细检查一下。
lbowerh at adelphia dot net
20 年前
这是一个生成用于显示或电子邮件的调试报告的函数
使用 `get_defined_vars`。非常适合在没有
依赖用户输入的情况下获取详细快照。

<?php
function generateDebugReport($method,$defined_vars,$email="undefined"){
// 用于创建用于显示或电子邮件的调试报告的函数。
// 使用方法:generateDebugReport(方法,get_defined_vars(),电子邮件[可选]);
// 其中方法为 "浏览器" 或 "电子邮件"。

// 为 'get_defined_vars' 返回的键创建忽略列表。
// 例如,HTTP_POST_VARS、HTTP_GET_VARS 和其他变量是
// 多余的(与 _POST、_GET 相同)
// 还包括你出于安全原因想要忽略的变量 - 例如 PHPSESSID。
$ignorelist=array("HTTP_POST_VARS","HTTP_GET_VARS",
"HTTP_COOKIE_VARS","HTTP_SERVER_VARS",
"HTTP_ENV_VARS","HTTP_SESSION_VARS",
"_ENV","PHPSESSID","SESS_DBUSER",
"SESS_DBPASS","HTTP_COOKIE");

$timestamp=date("m/d/y h:m:s");
$message="Debug report created $timestamp\n";

// 获取最新的 SQL 错误,其中 $link 是 mysql_connect 的资源标识符
// 用于 mysql_connect。根据你的数据库或抽象设置进行注释或修改。
global $link;
$sql_error=mysql_error($link);
if(
$sql_error){
$message.="\nMysql Messages:\n".mysql_error($link);
}
// 结束 MySQL

// 可以在这里使用递归函数。你明白了 ;-)
foreach($defined_vars as $key=>$val){
if(
is_array($val) && !in_array($key,$ignorelist) && count($val) > 0){
$message.="\n$key array (key=value):\n";
foreach(
$val as $subkey=>$subval){
if(!
in_array($subkey,$ignorelist) && !is_array($subval)){
$message.=$subkey." = ".$subval."\n";
}
elseif(!
in_array($subkey,$ignorelist) && is_array($subval)){
foreach(
$subval as $subsubkey=>$subsubval){
if(!
in_array($subsubkey,$ignorelist)){
$message.=$subsubkey." = ".$subsubval."\n";
}
}
}
}
}
elseif(!
is_array($val) && !in_array($key,$ignorelist) && $val){
$message.="\nVariable ".$key." = ".$val."\n";
}
}

if(
$method=="browser"){
echo
nl2br($message);
}
elseif(
$method=="email"){
if(
$email=="undefined"){
$email=$_SERVER["SERVER_ADMIN"];
}

$mresult=mail($email,"Debug Report for ".$_ENV["HOSTNAME"]."",$message);
if(
$mresult==1){
echo
"Debug Report sent successfully.\n";
}
else{
echo
"Failed to send Debug Report.\n";
}
}
}
?>
istiaquealamjoy at gmail dot com
7 年前
对于所有不知道如何使用此函数的人,请将此代码复制到你的计算机并运行。

注意:你需要了解什么是超级全局变量......

<?php


$A
= 5 ;
$B = 10 ;
$C = 15 ;
$D = 20 ;

$F = get_defined_vars($A);

var_dump($F); // 不要使用 echo。它会显示错误

?>

结果:将显示所有超级全局变量的状态以及你定义的
变量及其值
jgettys at gnuvox dot com
22 年前
将 `get_defined_vars` 对象转换为 XML 的简单例程。

<?php
function obj2xml($v, $indent='') {
while (list(
$key, $val) = each($v)) {
if (
$key == '__attr') continue;
// 检查 __attr
if (is_object($val->__attr)) {
while (list(
$key2, $val2) = each($val->__attr)) {
$attr .= " $key2=\"$val2\"";
}
}
else
$attr = '';
if (
is_array($val) || is_object($val)) {
print(
"$indent<$key$attr>\n");
obj2xml($val, $indent.' ');
print(
"$indent</$key>\n");
}
else print(
"$indent<$key$attr>$val</$key>\n");
}
}

// 例如对象
$x->name->first = "John";
$x->name->last = "Smith";
$x->arr['Fruit'] = 'Bannana';
$x->arr['Veg'] = 'Carrot';
$y->customer = $x;
$y->customer->__attr->id='176C4';

$z = get_defined_vars();
obj2xml($z['y']);
?>

将输出
<customer id="176C4">
<name>
<first>John</first>
<last>Smith</last>
</name>
<arr>
<Fruit>Bannana</Fruit>
<Veg>Carrot</Veg>
</arr>
</customer>
SyCo
15 年前
这是一个非常简单的调试函数。它远非完美,但我发现它非常方便。它在一行新行上输出变量值和变量名称。问题是如果变量值相同,它会回显所有变量及其名称。在调试时这没什么大不了的,并且节省了在回显变量时编写 HTML 和变量名称的麻烦。(ev=回显变量)。在函数内使用 `get_defined_vars()` 会将变量名称重命名为函数变量,因此对于调试不太有用。当然,你需要访问 `$GLOBALS` 数组。
<?
function ev($variable){
foreach($GLOBALS as $key => $value){
if($variable===$value){
echo '<p>'.$key.' - '.$value.'</p>';
}
}
}

$a=0;
ev($a);
$b=0;
ev($b);
$c=0;
ev($c);
?>
将输出
a - 0

a - 0
b - 0

a - 0
b - 0
c - 0
donovan at example dot com
15 年前
需要注意的是,`get_defined_vars()` 不会返回一组变量引用(正如我所希望的)。例如

<?php

// 定义一个变量
$my_var = "foo";

// 获取定义的变量列表
$defined_vars = get_defined_vars();

// 现在尝试通过返回的数组更改值
$defined_vars["my_var"] = "bar";

echo
$my_var, "\n";

?>

将输出 "foo"(原始值)。如果 `get_defined_vars()` 有一个可选参数可以将它们作为引用,那就太好了,但我认为这是一个相当专业的要求。你可以自己用类似下面的代码来实现(不太方便)

<?php

$defined_vars
= array();
$var_names = array_keys(get_defined_vars());

foreach (
$var_names as $var_name)
{
$defined_vars[$var_name] =& $$var_name;
}

?>
Joey
6 年前
我之前在这里发帖讨论过 `this` 在 `get_defined_vars` 中的问题。

事实证明,它并不总是存在,但在某些情况下它会莫名其妙地出现。

php -r '
class Test {
public function a() {var_dump(array_keys(get_defined_vars()));$a = 123;}
public function b() {var_dump(array_keys(get_defined_vars()));$this;}
}
$t = new Test();
$t->a();
$t->b();
'

array()
array('this')

这种情况在 PHP 7.2 中不会发生,但在 PHP 5.6 中会发生。
Anonymous
13 年前
`get_defined_vars()` 返回所有变量(在当前作用域中),如果只想获取所有你的变量,而不是 PHP 的超级全局变量,该怎么办呢?

<?php
var_export
(array_diff(get_defined_vars(), array(array())));
?>

例如...

<?php
$TOP_LEVEL_VAR
=1;
var_export(array_diff(get_defined_vars(), array(array())));
?>

输出(register_globals 关闭)应该是...

array (
'TOP_LEVEL_VAR' => 1,
)

...它完美地消除了所有超级全局变量,而无需我指定它们!(注意,如果 register_globals 打开,输出将包括这些全局变量,然后是 TOP_LEVEL_VAR)。

这是一个函数...(这是我所能做的最好的 {我不能在 `get_user_defined_vars()` 中调用 `get_defined_vars()`,因为作用域问题})。

<?php
header
('Content-type: text/plain');

$TOP_LEVEL_VAR=1;

echo
'register_globals(';
echo
ini_get('register_globals');
echo
') '.phpversion()."\n";

var_export(get_user_defined_vars(get_defined_vars()));

function
get_user_defined_vars($vars) {
return
array_diff($vars, array(array()));
}
?>

注意,最初我有一个包含我想从 `get_defined_vars()` 数组中删除的超级全局变量的数组,然后我注意到即使是一个空的双数组,`array(array())`,也能让我得到正确的结果。奇怪。

这在 PHP 5.2.9 上测试过。
Johan de Vries
14 年前
注意,这只会返回你使用过的内容。参见 http://bugs.php.net/bug.php?id=52110 。因此,不要期望它包含 `$this` 条目,除非你将 `$this` 赋值为返回 `$this`。
meint at meint dot net
13 年前
请注意,`function_get_vars` 只返回在调用 `function_get_vars` 函数之前的点定义的变量,它不会为你扫描整个函数,只扫描调用它之前的行。
To Top