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

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions