Global variable isn't accessible inside my Wordpress function. Why not? - 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.

Related

how to include a php file inside a public function in Joomla?

I want to include/require_once a PHP file inside a template with the help of a class. It's not including the file as it should be. Only showing the top html part of the file.
In place of JPATH_BASE, I have tried other options also.
class xyz {
public function loadfile($block) {
require_once JPATH_BASE.'/templates/'.$block.'.php';
}
}
$app = new xyz();
$app->loadfile(top);
A help will be very much appreciable.
When you include a file inside a function, remember that it will be executed in its context, which is very likely to break some things for some code. (for example all globals will be undefined without calling global statement before)
For example, consider you add this to your class xyz:
private function test() {
echo 'test';
}
Now, in the included file you can put:
<?php
$this->test();
Now if you load this file using this class, test will be outputted.
The question is why do you want to load files with a help of the class and a function and if it's really neccessary.
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.
(https://php.net/manual/en/function.include.php)
(also, about only top part of the page being shown, check the file that is being included, what it really contains; also check for errors in your server log, they will let you more easily spot the issue)

About variables

So if I have a variable in a php file I just made , if I put it in the same folder as other php files and include it into one of them , I can use any variable from that file right?
Sorry if it's a bit of noobish
Basically yea. Running the include is equivalent to pasting the code.
Specifically, from the PHP manual:
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.
In general the PHP manuals are pretty much self explained. You will find there most answers for basic questions as this one.
In short, yes.
From the documentation
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. This single
scope spans included and required files as well. For example:
<?php
$a = 1;
include 'b.inc';
?>
Here the $a variable will be available within the included b.inc script.
Note that this also works in the other direction:
<?php
/* a.inc */
$a = 1;
?>
<?php
/* b.php */
include 'a.inc';
echo $a;
?>

PHP Global Variables Issue

I've got a scope problem here. and no idea why its not working, ive got a setup as follows:
functions.php
global $id;
$id = $_GET['id'];
index.php
require_once('functions.php');
echo $id;
now inside functions.php i can echo out $id. however my echo $id; inside index.php is bringing up blank. absolutely nothing.
what am i doing wrong?
In PHP, the global keyword allows you to reference variables in the global scope from inside a local scope - eg to access a global variable inside a function. You don't need global in your example, because you are in the global scope anyway.
I suspect you are showing us a simplified version of what you have, where the issue is in code you haven't shown us.
Why you shouldn't use globals
Confusion like this is part of why using globals is a bad idea and should be avoided.
The alternative is to pass variables around explicitly, so for example if you call a function or instantiate a class from another file, you pass the variable in as a parameter to that function or constructor. Doing this, instead of using global variables, makes it easier to follow what function is accessing what variable because you can follow the trail easier.
You don't need globals between files, only for functions.
Functions.php
<?php
$foobar = "Hello";
?>
Index.php
<?php
include('Functions.php');
echo $foobar;
?>
You shouldn't use globals, but you have it backwards. You declare the variable global after you include its definition:
file1.php:
$name = 'Josh';
file2.php:
require_once('file1.php');
global $name;
echo $name;
#thomasrutter is correct (+1) Global variables areA Bad Thing. Always seek alternatives.
Perhaps you can use $_SESSION (which sort of amounts to the same thing, I know), or declare a class which has a static variable and use a getter() and setter() ? (the latter uis definitely cleaner, but $_SESSION might tie in better with your design, I can't say)
Btw, I hope that functions.php was just an example name, or that you have an extermely simple project.
Otherwise fucntions.php is going to get extermaly large and hard to oversee. If you are going OO then user one file per class, otherwse try to group your functions into separate files (file_management.php, databse.php, forms.php and the like).
If you are just starting out, I would advise you to use Netbeans and document your code with PhpDoc comments which will allow you to generate good documentation which you can view in your browser (including the structure of your coed, what gets declared where, used where, descruptions of function parameters and return values, etc)
Btw, I notice that you use include() I prefer require_once. The _once helps spee dperformnce a little and hte require makes sure that you are aware of missing files more quickly.
Oh, and learn to use Xdebug, which plays well with NetBeans.

Retrieving variables from included files

I have a php file that includes another one using include()
I defined a variable $something in the included file and that will change depending on a function that runs in the included file.
Now, I want to print that variable in the original file, when I use echo $something it is printing absolutely nothing, help?
Let's just leave aside that this is a poor design choice for a moment :)
You're probably running into a issue where you haven't declared the variable as global inside the function which modifies it.
function foo()
{
global $something;
$something='bar';
}
You will find the PHP manual page on variable scope most educational in this regard!
So why is this a poor design choice? First of all, check out "Are global variables bad?" which answers the question for C++. The answer is really no different for PHP - it can lead to unmaintainable and unreadable code.
There's another (increasingly historical) wrinkle with PHP though - if the 'register_globals' setting is on, a user can set global variables via the URL query string. This can lead to all manner of security problems, which is why this is now turned off by default (never write new code which requires it to be on).
As a wise man once said, "globals are the path to the dark side. globals lead to anger. anger leads to hate. hate leads to suffering" :)
It is possible you have declared your variable in global scope and are trying to use it in functional scope. To get around this use the global command.
$myglobal = 3;
function printMyGlobal() {
global $myglobal; // will not work without this line
echo $myglobal;
}
Use get_defined_vars to debug defined variables

PHP variable from other file comes back as NULL

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.)

Categories