Dynamic variables do not exist in Apex Code, because it is a "strongly typed" language. Languages such as PHP are "loosely typed" languages, which means that they are partly compiled, and then interpreted as a scripting language.
However, if you truly wanted to emulate dynamic variables, you could use the following class:
global class Vars {
static map<object, map<object, object>> values = new map<object, map<object, object>>();
global static object get(object scope, object key) {
if(!values.containskey(scope)) {
return null;
}
return values.get(scope).get(key);
}
global static void set(object scope, object key, object value) {
if(!values.containskey(scope)) {
values.put(scope, new map<object, object>());
}
values.get(scope).put(key, value);
}
global static boolean isset(object scope, object key) {
return values.containskey(scope) && values.get(scope).containsKey(key);
}
global static void remove(object scope, object key) {
if(isset(scope, key)) {
values.get(scope).remove(key);
}
if(values.get(scope) != null && values.get(scope).isEmpty()) {
values.remove(scope);
}
}
global static void remove(object scope) {
values.remove(scope);
}
global static boolean isempty(object scope, object key) {
return !isset(scope, key) || values.get(scope).get(key) == null || String.valueOf(values.get(scope).get(key)) == '';
}
global static boolean isequal(object scope, object key, object value) {
return !isempty(scope, key) && get(scope, key).equals(value);
}
}
Usage
// Set a global variable
vars.set(null, "myvar", 12345);
// Set a local variable
vars.set(this, "myvar", 12345);
// Get a global variable; must cast to get to a primitive type
integer a12345 = (integer)vars.get(null, "myvar");
// Get a local variable; must cast to get to a primitive type
integer a12345 = (integer)vars.get(this, "myvar");
// See if a value is as expected
if(vars.isequal(this, "myvar", 12345)) { ... }
// See if a value has been set
if(vars.isset(this, "myvar")) { ... }
// See if a value is blank or not
if(vars.isempty(this, "myvar")) { ... }
// Store a complex object
vars.set(null, "myvar", new map<string, account>());
// Access a complex object; cast is required
((map<string, account>)vars.get(null, "myvar")).put("some account", new Account());
// remove a variable from a scope
vars.remove(null, "myvar");
// remove all variables in a scope
vars.remove(this);
As you can see, there are some subtleties involved to make this work, such as requiring casts to concrete types, but this system is fuctionally similiar to dynamic variables. Note that casting is required for most operations, such as accessing a specific method or using any comparison operator other than ==, !=, ===, or !== (such as <, >, etc). Also, you can't store references to functions, because the language doesn't allow that, and you can't access a function without casting. For example, the following code won't work: vars.get(null, "myvar").put("some account", new account());
.
Feel free to experiment with this code and see what you can do. In the end, it may be more trouble than it's worth (I think so), but this should give you some idea of the potential capabilities of the language. Even though dynamic variables aren't directly supported, you can achieve some degree of freedom. Also note that, unlike a regular dynamic variable situation, you can use any value as a key, including dates, numbers, complex objects, etc.