I'm setting a $baseurl in a settings.php file.
In my index.php, I've got 3 require() in a row for the settings.php/header.php/masthead.php.
When I come to echo out the $baseurl it's undefined. If I define the $baseurl within the header.php then it works within the header.php file.
How can I get the $baseurl to be defined within the settings.php file and usable within each require() ?
Order of inclusion
The file that sets $baseurl must be require_once() first for the subsequent files to have access to the variable.
Function Scope
If you are defining $baseurl in a function or the files are require_once() from within a function then $baseurl will be trapped in that functions scope. This would the case if settings.php looked something like:
<?php
function setup_config() {
$baseurl = 'http://www.example.org';
}
Or requiring from within a function
<?php
function include_a_file($file) {
require_once 'my/base/path/' . $file;
}
This is documented in the Variable Scope portion of the PHP Manual.
One way to work around this is to add $baseurl as an element in $GLOBALS array instead of as a standalone variable:
$GLOBALS['config']['baseurl'] = 'my/base/url/';
Note I have added the ['config'] element to namespace your config away from anything else you may be tempted to place in $GLOBALS.
variable unset()
Another possibility is that you might be calling unset($baseurl) somewhere else in the code, which would be marking the variable as undefined.
If you define it in settings.php, it should be available in the global scope of all the included scripts. When you enter a function, the scope changes so the variable won't be available unless you 'import' it by declaring global $baseurl; at the start of the function (not advised, though).
If settings.php is included first, and $baseurl is defined as a global variable in settings.php, it will be available in all subsequently included files. If the variable is defined inside a function in settings.php, it will need to be defined as a global there:
$GLOBALS['baseurl'] = 'theurl';
If it is accessed within a function in any of the subsequently included files, it will need to be accessed via $GLOBALS[] there too:
echo $GLOBALS['baseurl'];
If you are expecting to access a global variable from multiple files, it is highly recommended to always use the $GLOBALS[] array since it remains clear in any scope that the variable is being set and accessed globally.
If you require() the files in a function, the variables are defined in the scope of the function: They are not global.
Use $GLOBALS['baseurl'] = '...'; in settings.php
Related
I have PHP files a bit like this
public_html/environment.php
public_html/task.php
phpbin/actions.php
phpbin/library.php
environment.php is included by public_html/* before any other php files are included, phpbin/* assumes everything in environment.php is already available.
It defines these two globals
$g_foo = "...";
$g_bar = "...";
task.php includes this logic
function do_stuff ()
{
require_once determine_required_file ();
...
}
In this case, determine_required_file() returns "/path/to/phpbin/actions.php"
actions.php in turn contains
require_once "/path/to/phpbin/library.php"
Finally, library.php contains
$x = $g_foo;
$y = $g_bar;
I get this error:
Undefined variable: $g_bar;
Now, $g_foo and $g_bar are strictly read-only except in environment.php, I have exhaustively grepped and verified that there are no other places which create or modify variables with these names.
I am aware that PHP globals are weird, and doing things like including files from within functions can mess up your scope. I know that I should probably use define() or some other method, yeah yeah.
My question is this (yes, I'm asking you to speculate in the absence of full code, sorry):
Why might $g_bar generate an error but not $g_foo?
I assume the in-function-inclusion is probably responsible, but assuming these globals really are read-only, what should I be looking for as the culprit for why one ends up in global scope in library.php but not the other?
You need to use include_once instead of required_once for your fields that needed your global variables, or define a global $g_bar, $g_foo.
http://php.net/manual/en/language.variables.scope.php
I am working in wordpress, and have a function in functions.php. This is meant to set a number of variables based on the context the variable is used in. But there's a problem.
I am using the function in an included template file, and the function is intended to work with variables on the page that template file is included into. I declare all the variables as global inside my function, but the function doesn't recognize the values of the variables. I don't understand why this is happening, because I am certain that the variable scope is being used properly.
To clear up confusion, I have included a simplified code example below, showing the three files involved in this issue. If anybody has any idea why this is happening, I would be delighted to hear it. I am interested in understanding the reasons why it is happening, more than looking for a fix.
functions.php
function set_variables() {
global $data;
print_r($data);
}
included_file.php
set_variables();
(Code that sets other variables and works with HTML)
template_file.php
$data = "Test";
include "included_file.php";
The result of the code above is nothing--I can't get the function in functions.php to recognize the variable defined in template_file.php. However, if I define the $data variable in functions.php, it works.
Like I said, this baffles me since it seems to contradict how declaring global variables within a function is supposed to work. How am I getting it wrong?
It looks like you misspelled the calling function:
set_variable() is not the same as set_variables()
Please note the following from PHP about including files:
When a file is included, the code it contains inherits the variable scope of the line on which the include occurs. Any variables available at that line in the calling file will be available within the called file, from that point forward. However, all functions and classes defined in the included file have the global scope.
See: http://php.net/manual/en/function.include.php
#zerkms - Thanks very much for answering my question. Turns out all I had to do was declare the variable as global in the file where it was defined.
So, in the example given above, the solution is as follows:
functions.php
function set_variables() {
global $data;
print_r($data);
}
included_file.php
set_variables();
(Code that sets other variables and works with HTML)
template_file.php
global $data = "Test";
include "included_file.php";
I just assumed that the variable declared in the template_file.php was in the global scope, but I suppose it wasn't. Still a bit fuzzy on the whys, but I know the code worked, and I'm really happy about that.
I have 2 files, class.inc.php and index.php.
class.inc.php contains Myclass and few functions, index.php file spits out functions from class.inc.php.
Now I need to create a function which will include/require a file and that function should actually require that file in index.php not in class.inc.php.
Yes I know I can place my file in a function and call it that way but we have to keep it in files because of some future MVC overrides. I do not want to include a file in index.php directly either if all possible. So is there a way to do this?
In my index.php I should be able to do this:
Myclass::include(PARAMS);
and that should include a file name params.php located somewhere else.
I tried this in class.inc.php
abstract class Myclass {
static function load($filename){
require_once $filename;
}
}
and this in
index.php
Myclass::include(PARAMS);
but none of my variables from params.php are visible in index.php because they seem to be in class.inc.php.
include, require and friends basically act as though you had copied-and-pasted the contents of the file to that location. So if you run them in a function, any "bare" variables, which would be global if you ran the file on its own, are instead local to that function.
Generally speaking, the answer in modern PHP code is simply not to use any global variables - a file should contain only functions, or better still, only namespaces and classes, with all the variables wrapped up in those.
If you really need to have global variables, however, you can use the global keyword either in your include function or at the top of the included file.
So for instance if your included file defines a variable $config which needs to be accessed elsewhere, at the top of the file you can write global $config; to push it out of any scope you're in when you include/require it.
In one PHP file, I have this code:
require_once $_SERVER['DOCUMENT_ROOT'] . '/custom/functions.php';
global $testVar;
var_dump($testVar);
In the functions.php file, I have this at the beginning, followed by a few other functions:
function pr($s) {
echo '<pre>', htmlspecialchars(print_r($s,true)), '</pre>';
}
$testVar = 'hello world';
When running the first file, the variable comes back as NULL. I added the global bit but it shouldn't be necessary. This is part of a Joomla module but I've never had problems including files before, it should just work like regular PHP. Why might this be happening?
First, try to use Joomla's path constants such as JPATH_BASE instead of $_SERVER['DOCUMENT_ROOT']. Joomla has a lot of useful constants, check it's documentation.
I've read your answer, and reading php documentation I tried to find a reason to why you need to use global keyword twice.
First, Variable scope.
The scope of a variable is the context within which it is defined. For the most
part all PHP variables only have a single scope.
(...)
However, within user-defined functions a local function scope is introduced.
Any variable used inside a function is by default limited to the local
function scope.
The variable isn't in a function scope, so that's why we thought the NULL was a strange behavior.
But then I read include and found something interesting:
(...)
Any variables available at that line in the calling file will be available
within the called file, from that point forward. However, all **functions**
and **classes** defined in the included file have the global scope.
I can't see any mention about the variables being global in this paragraph. So,it seens that, being cumbersome or not, your solution is the right thing to do when you want to use global variables like that.
In your situation, if doing this is cumbersome, I would create a simple class. If you have just helper functions in your file, create a class Util{} with a lot of methods and $testVar as an attribute.
I have found a solution that seems to work: using the global keyword both when setting the variable initially, and just before I need to use it.
(However this is quite cumbersome, and I'm still not sure why it happens, so if anyone has a better solution, feel free to post.)
I have a seperate PHP file I include that has a several important functions on it. I also have a file called variables.php which I include into each function so I can call some important variables too. Is there a way to just call variables.php at the top of the page, instead of inside each function manually? I just thought it would be easier if there was a way to do like a 'global' include or something.
You can set auto_prepend_file in the INI or .htaccess file to automatically include a file.
Well, if they are constant variables (AKA they don't change) you can define a constant instead
define("CONSTANT_NAME", "constant_value");
Or as of PHP5.3
const COSTANT_NAME="constant_value";
Then you can access them in every function
function test(){
echo CONSTANT_NAME;
}