变量范围:require_once 不会加载我的变量,但需要加载


Variable scope: require_once doesn't load my variable, but require does

我知道这很愚蠢,但我无法弄清楚。我在MVC框架的上下文中发现了一些类似的问题。这也是我的情况,因为我正在使用CodeIgniter。

我有一个文件questions.php(包含在视图中(:

require_once '../site_init.php';
var_dump($siteVars);
// shows null and a Notice: Undefined variable: siteVars
// but the ABSPATH constant is showing as defined!
var_dump(ABSPATH);
// shows string 'c:'wamp'www'sitename'
require '../site_init.php';
var_dump($siteVars);
// correctly dumps the content of siteVars array

以及一个文件site_init.php,它应该包含在任何地方,因为它包含我的站点范围的配置值:

if ( !defined('ABSPATH') )
        define('ABSPATH', dirname(__FILE__) . '/');
/** Site-wide sitevars */
$siteVars = array();
// set to true in develop environment
$siteVars['debug'] == false;

我知道The require_once statement is identical to require except PHP will check if the file has already been included, and if so, not include (require) it again但是,当我使用 require_once 时,我会收到一条通知,说Undefined variable: siteVars,在使用require时,一切都按预期工作。但是,正如您在上面的代码中看到的,常量显示为已定义,尽管它们都是在同一个文件中定义的。PHP手册:Like superglobals, the scope of a constant is global. You can access constants anywhere in your script without regard to scope.

print_r(get_included_files());显示site_init.php在require_once之前就包含在内,所以我不必再次要求(_once(它。

它一定与变量作用域有关。如果我使用 global $siteVars ,它可以工作,而无需再次require文件,但有人可以解释为什么会发生这种情况吗?我是CodeIgniter的新手。我可以看到只有一个入口点(主索引.php文件(,那就是基本文件($_SERVER['PHP_SELF'](。

理想情况下,我还想知道如何在不使用globalrequire的情况下解决此问题。

更新:文件结构似乎如下(这是我只在做的一个项目,我不是原始开发人员(:

  • 控制器welcome.php加载 (include_once( 在 CodeIgniter 应用程序文件夹结构之外的文件 X(CI 应用程序是较大站点的管理部分(。

  • 文件
  • X include_once site_init.php文件

  • 控制器welcome.php加载视图$this->load->view('template', $data);

  • 差不多就是这样。希望这是解决方案的关键。

在 CodeIgniter 中,视图中唯一可访问的变量从控制器传递给它。永远不应该有理由在 COdeIgniter 中包含以这种方式包含任何内容

控制器:

$d['title'] = 'title';    
$this->load->view('main',$d);

视图:

<?php print $title;?>

有关自定义配置值,请参阅 Config 类 http://www.codeigniter.com/user_guide/libraries/config.html 然后可以在控制器中访问这些值并将其传递到视图

这是一个逻辑问题,范围只是帮助你看到它。这是它的关键:

print_r(get_included_files());显示site_init.php在require_once之前就包含在内,所以我不必再次要求(_once(它。

这表示您之前已经包含过该文件,因此当您再次尝试时require_once()不会执行任何操作。这并不是说require_once()"不加载你的变量",它只是做了它应该做的事情 - 避免包含你已经加载的文件。
显然,require()不关心这种情况,它会重新包含脚本,从而将所述变量导入当前范围。

无论如何,一次又一次地包含脚本是将数据纳入当前范围的可怕方法。您应该学习如何使用函数参数传递数据。