Page 1 of 1
Requiring code within a function designed to be global
Posted: Sun Oct 01, 2006 3:12 pm
by Ollie Saunders
Code: Select all
// GlobalCode.php
$globalVar = 10;
function globalFunction()
{
global $globalVar;
return $globalVar * 2;
}
Code: Select all
// CallGlobalCode.php
function something()
{
require_once 'GlobalCode.php'; // GlobalCode is only needed if this function is used
return globalFunction();
}
Code: Select all
// TestOfCallGobalCode.php
require_once 'CallGlobalCode.php';
$this->assertEqual(something(), 20);
// fails with undefined $globalVar
This is because GlobalCode.php was required inside something() function making the variable definition local to the function rather than global as intended. The call to globalFunction() inside something() works because function definitions are always global.
Constraints:
- You are not allowed to modify GlobalCode.php
- In CallGlobalCode.php, GlobalCode.php must only be required when it is needed i.e. when something is called so just sticking require_once 'GlobalCode.php' outside of something() is not acceptable.
So the question is how can I fool PHP into thinking GlobalCode.php is in global scope even when it is being called from inside a function without modifying GlobalCode.php itself?
Posted: Sun Oct 01, 2006 4:14 pm
by onion2k
Yuck. Horrible code. Globals suck.
If you really must use a global like this, write it directly to the $GLOBALS array. EG
Code: Select all
// GlobalCode.php
$GLOBALS['globalVar'] = 10;
function globalFunction()
{
return $GLOBALS['globalVar'] * 2;
}
Thats the only way to do it.
Well, I suppose you could do file_get_contents("GlobalCode.php"), modify it, then eval the resulting string. I wouldn't though.
Posted: Sun Oct 01, 2006 4:34 pm
by Ollie Saunders
The globals are defined in
phputf8 written by Harry Fuecks. I certainly wouldn't write a library in this way (and I'm not) but considering my library depends on phputf8 I don't want to have to modify phputf8 in order for it to work with mine hence constrant
I wrote:You are not allowed to modify GlobalCode.php
If you really must use a global like this, write it directly to the $GLOBALS array. EG
Breaks the first constrant and is obviously what I would do were it not there.
Well, I suppose you could do file_get_contents("GlobalCode.php"), modify it, then eval the resulting string. I wouldn't though.
Yes I did consider that but I happen to agree with you, its pretty manky.
Posted: Sun Oct 01, 2006 4:43 pm
by volka
Code: Select all
function something()
{
global $globalVar;
require_once 'GlobalCode.php'; // GlobalCode is only needed if this function is used
return globalFunction();
}
nevertheless bad solution.
Posted: Sun Oct 01, 2006 5:03 pm
by Ollie Saunders
Volka; awesome!
Can't believe I didn't think of it myself.
nevertheless bad solution.
Its a dirty hack yes but its a hell of a lot better than the alternatives. Thanks you.
Posted: Wed Oct 04, 2006 5:52 am
by harry_f
Re
this bug report - understood and considering fixes - not decided yet. Hadn't foreseen that scenario.
The globals are defined in phputf8 written by Harry Fuecks. I certainly wouldn't write a library in this way (and I'm not) but considering my library depends on phputf8 I don't want to have to modify phputf8 in order for it to work with mine hence constrant
The reason for placing the lookup table globally is for performance - ideally it should only be created once per request. For similar reasons phputf8 prefers functions over classes - anything that save a few milliseconds. Normally abstractions are worth it but when it comes to replacing something as fundamental as PHP's string functions, which tend to get used all over, with userland functions, performance is worth considering.
Also be careful with $GLOBALS -
http://www.hardened-php.net/advisory_202005.79.html
Posted: Wed Oct 04, 2006 8:27 am
by Ollie Saunders
Re this bug report - understood and considering fixes - not decided yet. Hadn't foreseen that scenario.
That be mi bug report yarr
Interesting. How about setting the global inside a function:
Code: Select all
function setLookUps() {
global $UTF8_UPPER_ACCENTS, $UTF8_LOWER_ACCENTS;
$UTF8_UPPER_ACCENTS = array(/* lookup */);
$UTF8_LOWER_ACCENTS = array(/* lookup */);
}
which avoids using $GLOBALS.
For similar reasons phputf8 prefers functions over classes - anything that save a few milliseconds.
Well OK but won't those most concerned with performance be running opcode caches that will all but obliterate that problem?