PHP在调用函数时保留范围

时间:2008-10-03 02:33:58

标签: php

我有一个函数,它包含一个基于传递给它的字符串的文件,即来自查询字符串的操作变量。我将其用于过滤目的等,因此人们不能包含他们不应该的文件,如果文件不存在,则加载默认文件。 问题是当函数运行并包含文件范围时,由于include在函数内部运行而丢失。这成为一个问题,因为我使用全局配置文件,然后我为站点上的每个模块使用特定的配置文件。 我现在这样做的方法是定义我希望能够用作全局的变量,然后将它们添加到过滤函数的顶部。

有没有更简单的方法来做到这一点,即在进行函数调用时保留范围还是有PHP宏这样的东西?

编辑:使用extract($ _ GLOBALS)会更好吗?在我的函数调用内部?

编辑2: 对于任何关心的人。我意识到我完全在想这个问题,而不是使用一个函数我应该只使用一个包,呃!这样我就可以保持我的范围,也可以拿我的蛋糕。

6 个答案:

答案 0 :(得分:5)

编辑:好的,我已经重新阅读了您的问题,我想我现在正在谈论您的问题:
你想要这样的东西工作:

// myInclude.php
$x = "abc";

// -----------------------
// myRegularFile.php

function doInclude() {
    include 'myInclude.php';
}
$x = "A default value";
doInclude();
echo $x;    // should be "abc", but actually prints "A default value"

如果您只是更改了几个变量,并且事先知道要在include中定义哪些变量,请在global函数中将它们声明为doInclude()

或者,如果您的每个包含都可以定义任意数量的变量,您可以将它们全部放入一个数组中:

// myInclude.php
$includedVars['x'] = "abc";
$includedVars['y'] = "def";

// ------------------
// myRegularFile.php
function doInclude() {
    global $includedVars;
    include 'myInclude.php';
    // perhaps filter out any "unexpected" variables here if you want
}

doInclude();
extract($includedVars);
echo $x;        // "abc"
echo $y;        // "def"

原始答案:

这种事情被称为“闭包”,并在PHP 5.3中引入

http://steike.com/code/php-closures/

  

使用extract($ _ GLOBALS)会更好吗?在我的函数调用内部?

亲爱的领主,没有。如果要从函数内部访问全局变量,只需使用global关键字。例如:

$x = "foo";
function wrong() {
    echo $x;
}
function right() {
    global $x;
    echo $x;
}

wrong();        // undefined variable $x
right();        // "foo"

答案 1 :(得分:0)

当谈到配置选项(特别是文件路径等)时,我通常只使用define()用绝对路径定义它们。类似的东西:

define('MY_CONFIG_PATH', '/home/jschmoe/myfiles/config.inc.php');

这样,无论范围如何变化,它们始终都是全局可访问的,除非我迁移到不同的文件结构,否则它始终能够找到所有内容。

答案 2 :(得分:0)

如果我理解正确,你的代码就是:

function do_include($foo) {
  if (is_valid($foo))
    include $foo;
}

do_include(@$_GET['foo']);

一个解决方案(可能是也可能不简单,取决于代码库)是将include移出全局范围:

if (is_valid(@$_GET['foo']))
  include $_GET['foo'];

存在其他变通方法(如您提到的:声明全局变量,直接使用$ _GLOBALS数组等),但此解决方案的优点是您不必在所有包含的文件中记住此类约定。

答案 3 :(得分:0)

为什么不从include中返回一个值,然后将include调用的值设置为变量:

的config.php

return array(
    'foo'=>'bar',
    'x'=>23,
    'y'=>12
);

的script.php

$config = require('config.php');
var_dump($config);

无需使用全局变量搞乱这个地方

答案 4 :(得分:0)

  

有没有更简单的方法来做到这一点,即在进行函数调用时保留范围

您可以使用:

function doInclude($file, $args = array()) {
  extract($args);
  include($file);
}

如果您不想显式传递变量,可以使用get_defined_vars作为参数调用doInclude,例如:

doInclude('test.template.php', get_defined_vars());

我个人更喜欢传递一个显式数组,而不是使用它,但它会起作用。

答案 5 :(得分:0)

您可以将包含文件中的变量声明为全局变量,确保它们具有全局范围:

//inc.php
global $cfg;
$cfg['foo'] = bar;

//index.php
function get_cfg($cfgFile) {
    if (valid_cfg_file($cfgFile)) {
        include_once($cfgFile);
    }
}
...
get_cfg('inc.php');
echo "cfg[foo]: $cfg[foo]\n";