PHP从函数内部访问未知的外部变量

时间:2014-05-12 08:02:59

标签: php arrays function variables

我有这个函数来获取动态db数据,并且应该将常量和变量从db结果字符串转换为它们的匹配值。如果我只是将代码作为"直接"运行,那么该函数可以正常工作。代码而不是使它成为一个函数,但我想让它更具通用性,所以我尝试将它作为一个函数,当它是一个函数时 - 它只将常量转换为它的函数。值,但不是变量。这是直接的代码,工作正常。

$text = 'The sky is $color and<br> the grass is GRASS_COLOR'; // Example value taken from the database

$color = 'blue';
define('GRASS_COLOR', 'green');

// collect all defined variables and filter them to get only variables of string and numeric type
$values = array_filter( get_defined_vars(), function( $item ) {
    return is_string($item) || is_numeric($item);
});

// append the dollar sign to keys
$keys = array_map( function( $item ) { 
    return '$'.$item;
}, array_keys( $values ) );

// create the final array by comining the arrays $keys and $values
$vars = array_combine( $keys, array_values( $values ) );

// relpace names of the variables with values
$text = str_replace( array_keys( $vars ), array_values( $vars ), $text );

// collect all constants and replace user defined constants with values
$constants = get_defined_constants( true );
$text = str_replace( array_keys( $constants['user'] ), array_values( $constants['user'] ), $text );

// we are done
echo $text;

如何将其转换为通用函数,该函数将访问未知变量并输出正确的结果,如下例所示:

The sky is blue and
the grass is green

修改 这是功能:

$foo = 'The sky is $color and</br> the grass is GRASS_COLOR'; // place here value from database

$color = 'blue';
define('GRASS_COLOR', 'green');

function db_fetch_vars_constants($text) {

// collect all defined variables and filter them to get only variables of string and numeric type
$values = array_filter( get_defined_vars(), function( $item ) {
    return is_string($item) || is_numeric($item);
});

// append the dollar sign to keys
$keys = array_map( function( $item ) { 
    return '$'.$item;
}, array_keys( $values ) );

// create the final array by comining the arrays $keys and $values
$vars = array_combine( $keys, array_values( $values ) );

// relpace names of the variables with values
$text = str_replace( array_keys( $vars ), array_values( $vars ), $text );

// collect all constants and replace user defined constants with values
$constants = get_defined_constants( true );
$text = str_replace( array_keys( $constants['user'] ), array_values( $constants['user'] ), $text );

// we are done
echo $text;
}

db_fetch_vars_constants($foo);

编辑#2 正如@deceze建议的那样,我已将功能更改为以下内容并且可以正常工作。

$color = 'blue';
define('GRASS_COLOR', 'green');
$foo = 'The sky is $color and</br> the grass is GRASS_COLOR'; // place here value from database

function db_fetch_vars_constants($text) {

// collect all defined variables and filter them to get only variables of string and numeric type
//$values = array_filter( get_defined_vars(), function( $item ) {
$values = array_filter( $GLOBALS, function( $item ) {
    return is_string($item) || is_numeric($item);
});

// append the dollar sign to keys
$keys = array_map( function( $item ) { 
    return '$'.$item;
}, array_keys( $values ) );

// create the final array by comining the arrays $keys and $values
$vars = array_combine( $keys, array_values( $values ) );

// relpace names of the variables with values
$text = str_replace( array_keys( $vars ), array_values( $vars ), $text );

// collect all constants and replace user defined constants with values
$constants = get_defined_constants( true );
$text = str_replace( array_keys( $constants['user'] ), array_values( $constants['user'] ), $text );

// we are done
echo $text;
}

db_fetch_vars_constants($foo);

1 个答案:

答案 0 :(得分:1)

这听起来像是一种糟糕的做法。存在可变范围以将应用程序的各个部分彼此分离和隔离,以防止它自身踩踏。您基本上要求一个平面变量命名空间,并且应用程序中任何位置的任何变量都可以插入到模板文本中。你不应该这样做。

相反,创建一个包含目标用于最终用户表示的所有可能值的数组,并将它们作为数组传递给文本插值函数。不要让函数获取所有可能的变量,但是明确地将它应该使用的值传递给它。这是一个更加健全的应用程序结构。

想象一下,您拥有一个变量$password来保存您的秘密数据库连接凭据或其他敏感信息,以及一个字符串'Your password is $password'。您现在无意中输出了您的秘密供任何人查看。糟糕。