darrenc

variable/object/function scoping issue? namespace related?

Recommended Posts


<?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?

Share this post


Link to post
Share on other sites

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

  • Like 1

Share this post


Link to post
Share on other sites

@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. 

Share this post


Link to post
Share on other sites
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.

  • Like 4

Share this post


Link to post
Share on other sites

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 account

Sign in

Already have an account? Sign in here.

Sign In Now


  • Recently Browsing   0 members

    No registered users viewing this page.