Monday, April 30, 2018
CMSMS, global vairables and $GLOBALS - beware!
CMSMS User-Defined tags are chunks of php. If you use them, be careful about global variables.
My web host sold out and I was moved to a new (namesco) server, and suddenly my CMSMS content was seriously broken.
Aside from configuration switches, the big problem turned out to come from global variables.
I use "User Defined Tags" to load blocks of php into my page banner. And in that php, I was setting variables that I wanted to access from functions, which I achieved by declaring the variables as global in the function, eg:
myFunctions.php
function doSummat(){
global $thisVar;
//Do something with $thisVar
}
USER-DEFINED TAG
include (myFunctions.php);
$thisVar=123;
doSummat();
This approach, which had worked with my previous web host's (php5.4) server setup, would not work on the new (php5.6) one. The function didn't find the expected value in $thisVar.
Why?
Something has changed (either between server setups, or between php5.4 and php5.6) in the way that global variables are handled. Variables defined in a cmsms user-defined tag used to be working at top level, and so were available to functions if specified there as global.
But in the new setup, the php for a user-defined-tag appears to be handled within a php function: variables created within have only local scope. So when, in my example above, the function doSummat tries to access the global variable $thisVar, it doesn't find the variable $thisVar that I set in the tag - because the scope is limited to the php function in which the php for the tag is accessed.
(I presume that the user-defined tag was always handled this way, and that the two servers had different switch settings - which I have either missed, or have no access to - that have changed the behaviour)
Solution - if I declare "global $thisVar;" at the top of the User-defined Tag, then everything works as before: the User-defined Tag is finding the top-level variable $thisVar (by specifying it as global) and the function then finds it in the $GLOBALS array as expected.
Alternative - explicitly set and read $GLOBALS['thisVar']. A bit more typing but less error-prone, I suspect.
My web host sold out and I was moved to a new (namesco) server, and suddenly my CMSMS content was seriously broken.
Aside from configuration switches, the big problem turned out to come from global variables.
I use "User Defined Tags" to load blocks of php into my page banner. And in that php, I was setting variables that I wanted to access from functions, which I achieved by declaring the variables as global in the function, eg:
myFunctions.php
function doSummat(){
global $thisVar;
//Do something with $thisVar
}
USER-DEFINED TAG
include (myFunctions.php);
$thisVar=123;
doSummat();
This approach, which had worked with my previous web host's (php5.4) server setup, would not work on the new (php5.6) one. The function didn't find the expected value in $thisVar.
Why?
Something has changed (either between server setups, or between php5.4 and php5.6) in the way that global variables are handled. Variables defined in a cmsms user-defined tag used to be working at top level, and so were available to functions if specified there as global.
But in the new setup, the php for a user-defined-tag appears to be handled within a php function: variables created within have only local scope. So when, in my example above, the function doSummat tries to access the global variable $thisVar, it doesn't find the variable $thisVar that I set in the tag - because the scope is limited to the php function in which the php for the tag is accessed.
(I presume that the user-defined tag was always handled this way, and that the two servers had different switch settings - which I have either missed, or have no access to - that have changed the behaviour)
Solution - if I declare "global $thisVar;" at the top of the User-defined Tag, then everything works as before: the User-defined Tag is finding the top-level variable $thisVar (by specifying it as global) and the function then finds it in the $GLOBALS array as expected.
Alternative - explicitly set and read $GLOBALS['thisVar']. A bit more typing but less error-prone, I suspect.