I know this is something silly, but I can't figure it out. I found a few similar questions all in the context of an MVC framework. That's my case as well, as I am using CodeIgniter.
I have a file questions.php
(that's included in a view):
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
and a file site_init.php
that should be included everywhere as it holds my site-wide configuration values:
if ( !defined('ABSPATH') )
define('ABSPATH', dirname(__FILE__) . '/');
/** Site-wide sitevars */
$siteVars = array();
// set to true in develop environment
$siteVars['debug'] == false;
I know that 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
however, when I am using require_once
, I get a notice saying Undefined variable: siteVars
, while using require
, all works as expected. However, as you can see in the code above, the constant shows as defined, although they are both defined in the same file. PHP manual: 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());
shows site_init.php was included before the require_once, so I shouldn't have to require(_once) it again.
It must have something to do with variable scope. If I use global $siteVars
, it works, without the need to require
the file again, but can someone explain exactly why this happens? I am new to CodeIgniter. I can see there is only one entry point (the main index.php file) and that's the base file ($_SERVER['PHP_SELF']
).
Ideally, I would also like to know how I can fix this without using global
or require
.
UPDATE: File structure seems to be the following (this is a project I am only working on, I am not the original developer):
controller welcome.php
loads (include_once) a file X outside the CodeIgniter app folder structure (the CI app is the admin part of a larger site).
file X include_once site_init.php
file
controller welcome.php
loads the view $this->load->view('template', $data);
this is pretty much it. Hope this holds the key to a solution.
In CodeIgniter the only variables accessible in a view are passed to it from the controller. There should never be a reason to include anything in this way in COdeIgniter
Controller:
$d['title'] = 'title';
$this->load->view('main',$d);
View:
<?php print $title;?>
see Config Class http://www.codeigniter.com/user_guide/libraries/config.html for custom config values which could then be accessed in the controller and passed on to the view
This is a logical problem, the scope just helps you see it. Here's the key to it:
print_r(get_included_files());
shows site_init.php was included before the require_once, so I shouldn't have to require(_once) it again.
This says that you've already included that file before, so require_once()
doesn't do anything when you try it again. It's not that require_once()
"doesn't load your variable", it just does what it should - avoid including a file that you've already loaded.
Obviously, require()
doesn't care for that condition and it re-includes the script and hence imports the said variable in your current scope.
Anyway, including scripts again and again is a horrible method for getting data into your current scope. You should learn how to pass data around using function parameters.