PHP global or $GLOBALS - php

Is there a best practice / recommendation when I want to use a variable declared outside of a function when it comes to using:
global $myVar
$GLOBALS['myVar']
Thank you.

Well, you should only use globals in limited circumstances, but to answer your question:
global is potentially marginally faster (it will rarely make a difference).
$GLOBALS (not $GLOBAL) is more readable, because every time you see it, you know you are accessing/changing a global variable. This can be crucial in avoiding nasty bugs.
Inside the function, if you want to unset a global variable, you must use unset($GLOBALS['varname']), not global $varname; unset($varname);.
As to points 1 and 2, I'll quote Sara Golemon here:
What does that mean for your use of the $GLOBALS array? That's right, the global keyword is technically faster. Now, I want to be really clear about one thing here. The minor speed affordance given by using your globals as localized [compiled variables] needs to be seriously weighed against the maintainability of looking at your code in five years and knowing that $foo came from the global scope. something_using($GLOBALS['foo']); will ALWAYS be clearer to you down the line than global $foo; /* buncha code */ something_using($foo); Don't be penny-wise and pound foolish..

What you should really do is pass the variable to the function instead of using a global at all.
An example how to change a variable outside of the function via passing it as reference parameter:
function myFunc(&$myVar)
{
$myVar = 10;
}
$foo = 0;
myFunc($foo);
var_dump($foo); // yields 10

Use global at the top of your function. That way, you can easily see what globals are used.

global $var; is equivalent to $var =& $GLOBALS['var'].
Some people suggested that it is faster than using $GLOBALS, however it's not necessarily the case. If you use the variable only once, $GLOBALS will be faster, because you won't waste time for assignment.
However, if you do use the variable multiple times, using global (or the equivalent assignment) is faster, because search the array for the var key only once.
That's it about speed. However, the speed difference is really small, and readability is more important. However, different people have different preferences about readability -- I prefer global, some other people answering here prefer $GLOBALS, so it's up to you to decide what looks better.

Related

Variable variable string constructed for "$GLOBALS" works within global scope, but not function scope

An important note: $GLOBALS are dirty and evil. Don't use them. Ever. Never ever ever.
Please focus on the fact that it doesn't work and not why you would be doing this in the first place, it is purely a theoretical question about a technical exercise.
This is a rather weird one. I'm attempting to construct a variable variable using a string named $GLOBALS.
From the global scope
Let's see what we get when var_dump()ing this in the global scope.
$g = sprintf('%s%s%s%s%s%s%s', chr(71), chr(76), chr(79), chr(66), chr(65), chr(76), chr(83));
var_dump($$g);
The result is an array of global variables, which you can see here. Great! So, let's try this in a function.
From a function scope
First, let's just make sure that we can actually run an $GLOBALS check within a function.
function globalAllTheThings()
{
var_dump($GLOBALS);
}
globalAllTheThings();
The result is: it works!! You can see this here.
Now, let's try the first test that we used in the global scope, within the function, and see what happens.
function globalAllTheThings()
{
$g = sprintf('%s%s%s%s%s%s%s', chr(71), chr(76), chr(79), chr(66), chr(65), chr(76), chr(83));
var_dump($$g);
}
globalAllTheThings();
For simplicity's sake
You can also try this without the weird obfuscation (don't ask).
function globalAllTheThings()
{
$g = 'GLOBALS';
var_dump($$g);
}
globalAllTheThings();
It returns NULL. What's that about?? Why does it return NULL, and what can I do to get this working. Why, you ask? For educational purposes of course, and for science!
Because the manual says so:
Warning
Please note that variable variables cannot be used with PHP's Superglobal arrays within functions or class methods. The variable $this is also a special variable that cannot be referenced dynamically.
http://php.net/manual/en/language.variables.variable.php
It's simply "special". PHP is "special". Superglobals don't play by the same rules as regular variables to begin with. Someone forgot to or decided against making them compatible with variable variables in functions. Period.

Passing globals thru function arguments

1I know it may sound silly from the get go...
and let me tell you right off the batt, this ain't the same question as The advantage / disadvantage between global variables and function parameters in PHP. asked right here on stackoverflow. There, asker wonders local vars vs global vars. Here, globals vs globals. My question is all about the PHP's internal way of handling the global variable access and speed.
Here is the question, in the below examples, is the function_1 supposed to run faster than the function_2?
function function_1 ( &$global_variable_x) {
//do something with $global_variable_x
}
function function_2 () {
global $global_variable_x;
//do something with $global_variable_x
}
Let me highlight what's the difference...
In case 1, you pass the global in the function arguments and not only that, you pass it as by ref so the memory location is handed to PHP directly. Because of this trick, there is no need for the use of the global keyword within the function, and because of this very fact, there is no time spent by PHP looking up the global in the global name space. Then the question is why not do it? It's got to be faster, ain't it?
Of course, it is easy to misinterpret this question and get into the usual chores of talking about
Globals are bad
Globals do not need to be passed thru function args because globals well... are globals, so they can be accessed anywhere anyway.
and finally, it does not make sense to pass a global thru a function argument from a semantical point of view, it confuses the hell out of people.
none of which addresses the question being asked.
It's all about speed.
if its global it makes no sense to use it as an argument to a function which can see that global. It either 1) won't be faster or 2) it will run barely slower 3) it will run faster by very little and the reason for this will defy formal logic.

Which is the better way to reference a variable outside the function scope?

I can change $var in my function in one of two ways: either pass it by reference or using the global keyword.
$var1 = 10;
function test1() {
global $var1;
$var1++;
}
function test2(&$var) {
$var++;
}
Both approaches have the same result, but is there any difference between them? Which one is preferred and which one is faster?
1. None of them is preferred.
Unless you have a special reason to do otherwise, the preferred would be
$var1 = 10;
$var1 = test3($var1);
function test3($var)
{
return $var + 1;
}
Introducing coupling between different parts of your program (if using a global) is something you should always reasonably try to avoid.
In addition, if there is no concrete reason to make your function accept its argument by reference you should also avoid doing that. Only a very miniscule fraction of all functions behave this way, so if nothing else you are risking confusion among the developers who use this code for no real benefit.
2. You do not need to think about which one is faster.
Unless you have profiled your application under real world scenarios and have found that this function is a bottleneck (which of course it will never be in this simple form), then optimizing for performance at the expense of writing clear and maintainable code is not only pointless, but also detrimental.
As a bonus, I should mention that using a reference might actually make the function slower.
Since global variables pollute the namespace (i.e. can be used inadvertently and/or by another function with the same idea), references are preferable.
However, in many cases (where the data structures are more complex), you should be using objects instead, like this:
class Counter {
private $val = 10;
public function increment() {
$this->val++;
}
}
The speed of any of these solutions does not matter and will be dwarfed by any actual computation.
Preferred way is avoiding globals. The reason is that if you put a variable in global scope, you lose control over it - since projects grow, you might forget what the name of your global variable is and you can overwrite it accidentally somewhere causing an incredible headache for yourself.
From performance point of view - reference is faster and it's also much safer to use because you define in method's signature whether a reference is being used or not, making the actual function call easy as you don't have to pass the variable by reference explicitly.

php global variables with variable names

I am trying to have a function that among other things declares global variables based on a variable that i give it.
the part that fails is making the variables global
function setGlobalVariable($name) {
global $name, $arrayname_{$name};
}
any idea?
thanks :)
Really, stop messing with global variables that way.
Anywaym here's your solution if you really want to do that:
function setGlobalVariable($name) {
$GLOBALS['arrayname_' . $name] = 'yourvalue';
}
You should not do that. Global variables are in general a sign of poor design. What is it that you are trying to achieve? I am sure that there is a better solution. Besides that, global does not work like that. global makes other variables outside your function locally available. Use $_GLOBAL to create globals.
Take a look at the Registry Pattern (http://martinfowler.com/eaaCatalog/registry.html).
A well-known object that other objects
can use to find common objects and
services.
There are various PHP implementations, for example Zend_Registry: http://framework.zend.com/manual/en/zend.registry.html
You're almost right, but not quite; a variable variable takes the form of ${"name"}, so what you're looking for is something like global ${"arrayname_$name"};.
http://www.reddit.com/r/programming/comments/dst56/today_i_learned_about_php_variable_variables/c12np38 is fascinating reading on the topic, if you feel so inclined.
It's likely a terrible idea, though, and if you're resorting to that sort of thing, it's a good indication that your code may be poorly designed. Consider refactoring it (for example, to keep a single known array that your other arrays are kept in, and may be referenced by key.)

The advantage / disadvantage between global variables and function parameters in PHP?

sorry i'm a beginner and i can't determine how good a question this is, maybe it sounds utterly obvious to some of you.
if our use of these two below is the same which is better?
function doSomething ($var1,$var2,..){
...
}
OR
function doSomething (){
global $var1,$var2,..;
...
}
by our use I mean that I know that in the second scenario we can also alter the global variables' value. but what if we don't need to do that, which is the better way of writing this function? does passing variables take less memory than announcing global's in a function?
The memory usage is a paltry concern. It's much more important that the code be easy to follow and not have... unpredicted... results. Adding global variables is a VERY BAD IDEA from this standpoint, IMO.
If you're concerned about memory usage, the thing to do is
function doSomething (&$var1, &$var2,..) {
...
}
This will pass the variables by reference and not create new copies of them in memory. If you modify them during the execution of the function, those modifications will be reflected when execution returns to the caller.
However, please note that it's very unusual for even this to be necessary for memory reasons. The usual reason to use by-reference is for the reason I listed above (modifying them for the caller). The way to go is almost always the simple
function doSomething ($var1, $var2) {
...
}
Avoid using global variables, use the passing variables in parameters approach instead. Depending on the size of your program, the performance may be negligible.
But if you are concerned with performance here are some key things to note about global variable performance with regards to local variables (variables defined within functions.)
Incrementing a global variable is 2 times slow than a local var.
Just declaring a global variable without using it in a function also slows things down (by about the same amount as incrementing a local var). PHP probably does a check to see if the global exists.
Also, global variables increase the risk of using wrong values, if they were altered elsewhere inside your code.
Write it to take parameters. Maintainability is far more important than micro-optimization. When you take parameters, the variables can not be modified in unexpected places.
Although it is not good practice as long as you guarantee that the global is never written, but only read you will have the flexibility of paramaters.
As as alternative, you can pass one parameter (or two if it really goes with the function, like exp) and the rest in an array of option (a bit like jquery does).
This way you are not using globals, have some parameter flexibility and have clearly defined the defaults for each parameter.
function get_things($thing_name,$opt= array() {
if(!isset($opt["order"])) $opt["order"]= 'ASC';
}
Pass in parameters, avoid globals. Keeping only the scope you need for a given situation is a measure of good code design. You may want to look at PHP variable scope...
http://php.net/manual/en/language.variables.scope.php
An excellent resource, with some pointers on what is best practices and memory management.
As of PHP 4 using global with big variables affects performance significantly.
Having in $data a 3Mb string with binary map data and running 10k tests if the bit is 0 or 1 for different global usage gives the following time results:
function getBit($pos) {
global $data;
$posByte = floor($pos/8);
...
}
t5 bit open: 0.05495s, seek: 5.04544s, all: 5.10039s
function getBit($data) {
global $_bin_point;
$pos = $_bin_point;
$posByte = floor($pos/8);
}
t5 bit open: 0.03947s, seek: 0.12345s, all: 0.16292s
function getBit($data, $pos) {
$posByte = floor($pos/8);
...
}
t5 bit open: 0.05179s, seek: 0.08856s, all: 0.14035s
So, passing parameters is way faster than using global on variables >= 3Mb. Haven't tested with passing a $&data reference and haven't tested with PHP5.

Categories