darrenc Posted September 23, 2017 Share Posted September 23, 2017 <?php namespace ProcessWire; class Foo {}; $foo = new Foo; $foo->message = "hello world"; function print_foo() { global $foo; print_r($foo); } print_r($foo); // success print_foo(); // nothing ?> In any template file, or init, the above code doesn't pull $foo into the function's local scope. It seems to not exist even though I'd fully expect it to be there. Does anyone have insight into why this happens or how I should be approaching it? Link to comment Share on other sites More sharing options...
abdus Posted September 23, 2017 Share Posted September 23, 2017 Why not use closures? function print_foo() use($foo) { // to be able to change $foo use get it by reference &$foo instead print_r($foo); } One distinction is that with closures $foo will have the value at the moment of function creation, whereas global $foo will have the value of $foo at the time of execution. Often this doesn't matter, but you should be aware. Also with closures you can reference variables from parent scope. To access even higher scopes, you'll have to use globals. https://stackoverflow.com/questions/16959576/reference-what-is-variable-scope-which-variables-are-accessible-from-where-and 1 Link to comment Share on other sites More sharing options...
fbg13 Posted September 23, 2017 Share Posted September 23, 2017 I think it's because of this https://github.com/processwire/processwire/blob/57b297fd1d828961b20ef29782012f75957d6886/wire/core/WireInput.php#L628 1 Link to comment Share on other sites More sharing options...
darrenc Posted September 23, 2017 Author Share Posted September 23, 2017 @abdus that's an approach i'm not at all familiar with, thanks very much i'll experiment with it. @fbg13 interesting, I wonder why that is done. Link to comment Share on other sites More sharing options...
BitPoet Posted September 24, 2017 Share Posted September 24, 2017 15 hours ago, darrenc said: I wonder why that is done. That's a remnant from times with PHP < 5.4, where the register_globals setting in php.ini was still often set to true. This meant that every GET or POST parameter was added as a global variable of the same name. If programmers were just a tiny bit sloppy and forgot to initialize their global variables with reasonable default values, this lead to security issues since malicious visitors could set their desired values. A simple example would be a PHP script with an authorization check. Let's suppose our hacker calls it with the URL http://my.broken.site/page.php?auth=1 <?php // Authorization check if(is_user_authorized()) { // we only set $auth to a truthy value when the check was successful $auth = true; } if($auth) { show_sensitive_content(); } In that example, $auth isn't set to anything if is_user_authorized fails, so our hacker created a global variable $auth from the GET parameter with a truthy value (1) and that never gets overwritten. He can see our sensitive content. Ouch. To prevent these kinds of problems, it was good practice to remove all globals before populating your own. 4 Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now