Not much of a PHP programmer, so I have a quick question in order to improve the performance of a WP site.
For many pages, the header and the body are handled by a set of completely separate functions.
The body functions do a lot of the same work as the header functions have already done, so is it possible to save the results of the header functions in a set of page level variables? (to avoid doing the same work twice).
Page level variables = variables with a page level scope that separate functions on the same page all have read/write access to.
Thanks!
You're probably looking for global, which is described on this page: http://php.net/manual/en/language.variables.scope.php
Short example:
function do1()
{
global $foo;
$foo = do work ...
}
functio do2()
{
global $foo;
$bar = do work with ($foo); ...
}
do1();
do2();
And one word of adivce; be very careful not to accidentally reuse names for global variables.
Related
I have heard using global variables is not good, however I am just trying to understand how the PHP language works. I am a beginner in the coding world.
Why can global variables be created within functions? Whether it is through the use of the global keyword or through a superglobal variable. I thought these two actions were used to access global variables in a function. I thought the only way you can create a global variable is to create it outside a function; in the global scope. I have looked at many different websites including w3schools.com and php.net
This is just some simple code I created to try and understand the way global variables work with functions:
<?php
function sample1() {
global $a;
echo $a = "this ";
}
sample1();
function sample2() {
echo $GLOBALS['$b'] = "is ";
}
sample2();
function sample3() {
global $c;
$c = "an ";
}
sample3();
echo $c;
function sample4() {
$GLOBALS['$d'] = "example ";
}
sample4();
echo $GLOBALS['$d'];
?>
This is the result of the code:
this is an example
All of the code works, but I don't understand how I created a global variable on any of these blocks of code? The global variables were not created outside of the functions. How can they be created inside of a function? What am I missing? Any response is appreciated - If possible, please keep the answer simple - I would like to discuss this further in the comment section, because I'm sure I will have follow up questions - Thank you
Variables can be created in the global scope in the two ways you just did - there's nothing saying that a function can't create (or change) a variable in the global scope - WHEN you explicitly ask for it through $GLOBALS or the global keyword.
The issue is that your belief "I thought the only way you can create a global variable is to create it outside a function; in the global scope." is not an exact statement. When you're using $GLOBALS and global, you're referring to the global scope. You're introducing a reference to the global scope inside your function.
With global you're in effect linking the local reference to the global reference, while with $GLOBALS you're explicitly referencing the global scope (which internally inside PHP can be introduced to the local scope in the same way).
In that case you're explicitly saying "I want this variable to be available in the global scope, make it so!" and PHP does what you're asking it to. This behaviour differ between languages, but as you've discovered for PHP, it's allowed.
It's not something I would recommend using in any way - it makes your code very hard to follow and argue around, so consider it an esoteric detail.
I have not been able to find a good example for this particular case. Most people who ask this question have a more complex use case and so the answer usually involves a complex solution. I simply have a few variables at the beginning of the script that need to be available throughout all the code including several functions. Otherwise I would have to set it in each function, and considering this is a user set value, changing it all throughout the code is just not possible.
<?php
//**** Example User Config Area ****
$name = "blah";
$tag = "blah";
//**********************************
function taco() {
echo $name; //this function needs to use these user set variables
echo $tag;
}
?>
Everyone says NOT to use global variables. Is this a case where global variables actually DOES make sense? If not, what should I do here to make this work?
It should be noted that those values do not change in the program. They only change if the user edits them. Like a DB location or a username etc.
Just pass these variables:
function taco($name, $tag) {
echo $name;
echo $tag;
}
// and
taco($name, $tag);
There are two main ways you can do configuration in PHP.
The first is to create a configuration object that you can pass around to each function. Some people consider this a little clunky, but it does get around using global variables.
That being said, if you're just trying to store configuration details, a global variable is not a bad option and has been discussed on this site before.
You need to think about your use case. If you're dealing with something that could create a race condition, then global variables are of course a bad idea. If you just want to store some static information to reference throughout your code... it's not the end of the world.
I am creating some widget for Word Press, but maybe this is standard PHP question, because it is related to some MVC pattern. I have some HTML that i need to output on page but that HTML is for now i inside function, i would like to transfer it to partial, because in the future there can be lots of more HTML, and if I make it like this it will be lots of spaghetti code.Here is what i have for now
class motractrucks extends WP_Widget{
function widget($args, $instance, $defaults){
echo '<p>'.$value1.'<p>';
echo '<p>'.$value2.'<p>';
echo '<p>'.$value3.'<p>';
echo '<p>'.$value4.'<p>';
echo '<p>'.$value5.'<p>';
echo '<p>'.$value6.'<p>';
}
}
This is just simple example, I have modified function easy that you can understand what i need, i was thinking to do something like, but how to pass values form inside function in that view?
class motractrucks extends WP_Widget{
function widget($args, $instance, $defaults){
include 'partials/userValues.php';
}
}
And pass all values to that partial, any good idea and best code practice will be nice.
The part of this question that specifically pertains to PHP is the variable scope. PHP functions have a local scope. So variables used inside those functions are considered to be local variables by default. Unless you explicitly import a variable from the global scope into the function's local scope via the global keyword, it's local. In your examples those variables are all undefined.
Also, using echo inside a function is never considered good practice, but I can't speak specifically to the WordPress aspect of your code as I'm not that familiar with WordPress.
Functions should take inputs as arguments and should return values as output. That's typically what you would consider good practice.
function foo($var1, $var2, $var3) {
return <<<HTML
<p>$var1</p>
<p>$var2</p>
<p>$var3</p>
HTML;
}
As far as including files for use in templates, that's usually fine in PHP. When you're doing those includes inside of a function it becomes easier to contain their scope, because include takes scope into account.
Let's say your partials/userValues.php file looks something like this...
<p><?=$var1?></p>
<p><?=$var2?></p>
<p><?=$var3?></p>
If you want to include it from your function you can. You can also use output buffering with functions like ob_start() and ob_get_clean() to write the output into a buffer and return that from the function instead of just printing directly to standard out.
function foo($var1, $var2, $var3) {
ob_start(); // start the output buffer first
include 'partials/userValues.php'; // include inherits the variable scope
$output = ob_get_clean(); // close the buffer and store it in $output
return $output; // return it to the caller
}
How to make variables visible when including some file. For example:
code.php:
<?php
global $var; $var = "green";
?>
index.php:
<?php
include("code.php");
Function index(){
echo "The apple is $var";
}
?>
Please note that in code.php there are a lot of global variables (~150 variables) and all variables are used in many different functions inside the index.php.
This is an issue to do with variable scope, plus you do not need to be defining $var as a global.
When you include a file, you can imagine in your head that it is just copy-pasting the contents of the other file into the current file.
E.g.
code.php
$includedName = 'Tom';
index.php
include 'code.php';
function sayHello($name)
{
echo 'Hello ' . $name;
}
sayHello($includedName); // Hello Tom
You've mentioned you are working with legacy code, so it may be worthwhile to preserve the use of globals for the sake of consistency - though using globals is generally considered to be very bad practice, I'd generally consider inconsistently using globals to be worse.
To break function scope and pull in variables from the global scope you must invoke the global keyword from within the function:
<?php
$var = "green";
Function index(){
global $var;
echo "The apple is $var";
}
?>
This answer sums up why global variables are considered to be bad practice:
There's no indication that this function has any side effects, yet it
does. This very easily becomes a tangled mess as some functions keep
modifying and requiring some global state. You want functions to be
stateless, acting only on their inputs and returning defined output,
however many times you call them.
However, in this specific example, you are not modifying $var's state - only reading it. So the issues are minimal.
The problems with global state can be read about in more depth on Programmers.SE.
Here's my scenario:
$foo = bar;
one()
{
two()
{
three()
{
// need access to $foo here
}
}
}
I know I could pass $foo down all three functions, but that isn't really ideal, because you may or may not require it, besides, there are other parameters already and I don't want to add to that list if I can prevent it. It's only when you get to three() do you need $foo. I know I could also specify global $foo; in three(), but I read that this wasn't a good practice.
Is there another way $foo can be made available to three() without doing either of those?
To provide a little more info, $foo in this case is info on how to connect to the database e.g. server, user, pass, but only in three() does it actually need that info. Of course I could connect to the database right as the document loads, but that feels unecessary if the document might not need it.
Any ideas?
UPDATE: I'm sorry, I didn't mean to have "function" at the beginning of each function implying that I was created them in a nested way.
Yes, you can use global, or pass it through as a parameter. Both are fair ways. However, I'd do the latter. Or, you can also use closures and the use keyword:
$foo = 'bar';
$one = function() use($foo) {
$two = function() use($foo) {
$three = function () use($foo) {
// access to $foo here
};
};
};
Can also be use(&$foo) if you need to modify the top $foo's value inside of $three()
Using global is not a bad practice if used properly. This case you would use global and it will be totally fine.
Since global makes functions get access to global variables, there are data corruption risks.
Just make sure to use with caution and you know what you're doing (i.e. not accidentally change the data that you don't want it to change. This sometimes causes some nasty bugs that's hard to track.)
Summarize: global in this case is perfectly fine.
What's really bad is nested functions, at least in PHP.
Don't listen anybody, who are speaking about global.
Read books about OOP (e.g. this one), read about Dependency Injection, Factory-patterns.
Dependency Injection is the best way to create flexible and easy-to-maintain code, and by DI philosophy you will pass $foo from first to third function in arguments, or will pass Context object with all necessary variables (if you want to minimize count of arguments).
More about DI you can read here: http://components.symfony-project.org/dependency-injection/trunk/book/00-Introduction