A Question of Scope |
Page 2 of 2
SolutionIf you live and breathe PHP you will probably be wondering what sort of idiot the programmer who committed this stupid error was - but believe me the code as presented is more-or-less how the majority of programmer not so familiar with PHP would expect PHP to work. It is also a good excuse to look at how PHP actually implements scope and to consider whether or not it is actually better. A variable defined "at the top level" i.e. outside of any function would generally have global scope and so it does in PHP but... Any variables that you declare within a function have local scope and so $MyOtherVariable can only be used by instructions within BigComputation. However any variables not defined within a function, and this includes any variable that are apparently "Global" are exactly that - undefined. This is not the way most programming languages do things. So what this means is that, despite its name, $MyGlobal, isn't really anything of the sort. Within BigComputation $MyGlobal is undefined - something you will see if the PHP errorlevel is set for debugging but not usually in a running system. So what is the solution? Most programming languages at this point would introduce an attribute that could be used to signal that the attempted global variable really was GLOBAL. For example, and this doesn't work in PHP, you might expect this solution to be something like: global $MyGlobal="This is a global variable"; function BigComputation(){ As already hinted at, this doesn't work either. PHP has a global keyword but it isn't used to indicate a global variable at top level but to indicate that a global variable is to be used in function local scope.... what? OK put simply the solution is: $MyGlobal="This is a global variable"; That is declaring a variable as global within the function extends the scope of the global variable of the same name into the function. So the solution is - you can declare as many variables as you like at the top level but they aren't accessible within a function unless you declare them again with the global keyword within the function. There is an alternative approach. The $GLOBALS associative array has true global - a superglobal in PHP jargon - and it contains all of the global variables as name value pairs. Notice that since PHP 4.1 most predefined variables are superglobal and so do not need to be declared using the global keyword - another source of confusion for the beginner. PatternThe pattern to avoid this type of problem is simply to know that there is a problem and declare any global variables within each function that makes use of them. PHP's approach is more like including global variables as default parameters of the function and the big disadvantage is, of course, that you have to list them. Some might argue that this is a better way to control access to variables and the discipline of listing variables is good for you. There are others who would rightly point out that limiting the number of global or superglobal in PHP's sense is a very good idea. Passing everything as a parameter also has its problems however and here we are entering the area of what constitutes good program design and this is well beyond the scope (pun intended) of this puzzle. More Puzzles
<ASIN:0470395095> <ASIN:1932394753> <ASIN:0596006810> <ASIN:0672329166> |