我知道这很愚蠢,但我无法弄清楚。我在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']
(。
理想情况下,我还想知道如何在不使用global
或require
的情况下解决此问题。
更新:文件结构似乎如下(这是我只在做的一个项目,我不是原始开发人员(:
控制器
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()
不关心这种情况,它会重新包含脚本,从而将所述变量导入当前范围。
无论如何,一次又一次地包含脚本是将数据纳入当前范围的可怕方法。您应该学习如何使用函数参数传递数据。