Skip to content

get_defined_vars() scope clarification #1317

@CmsWares

Description

@CmsWares

The manual for get_defined_vars() reads:

This function returns a multidimensional array containing a list of all defined variables, be them environment, server or user-defined variables, within the scope that get_defined_vars() is called.

However, I notice that superglobals like $_GET, $_POST, $_SERVER etc. are within a function's scope (right?), however they are only returned when called outside any scoping context. Calling get_defined_vars() inside a function only returns user-defined variables, if any. Investigating further, a scoping test shows that:

- function no_vars: array(0) { }
- function has_vars: array(1) { ["var"]=> int(1) }
- function has_args: array(1) { ["arg"]=> int(1) }
- anon function: array(0) { }
- anon function with var: array(1) { ["var"]=> int(1) }
- anon function with use(): array(1) { ["used"]=> int(1) }
- blank class: array(0) { }
- class with properties: array(0) { }
- static class with properties: array(0) { }
- no context: array(10) {
	 ["_GET"]=> array(0) { }
	 ["_POST"]=> array(0) { }
	 ["_COOKIE"]=> ...
	 ["_FILES"]=> array(0) { }
	 ["func"]=> object(Closure)#1 (0) { }
	 ["funcVar"]=> object(Closure)#2 (0) { }
	 ["used"]=> int(1)
	 ["funcUses"]=> object(Closure)#3 (1) { ["static"]=> array(1) { ["used"]=> int(1) } }
	 ["cBlank"]=> object(classBlank)#4 (0) { }
	 ["cProps"]=> object(classProps)#5 (3) { ["foo"]=> int(1) ["bar":protected]=> int(2) ["meh":"classProps":private]=> int(3) }
}

In keeping with the "returns variables explicitly available in a given scope" (and excluding superglobals) behavior, the results are mostly as expected. However, I find the following a bit anomalous:

  • when called inside a class constructor, properties are not returned -- even though they are within scope
  • when called in global scope, the properties of an object instance are however returned
  • in global scope, superglobals $_SERVER and $_ENV (PHP 5.4+) are not returned

I think these behaviors should be mentioned explicitly in the manual, along the lines of:

  • In global scope, a list of all defined variables, whether superglobals, command line arguments or user-defined variables
  • In function scope, only a list of user-defined variables (both arguments and in-body definitions)
  • In class/object method scope, does not return class/object properties;

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions