function array_key_search(&$search, $key, $replace = NULL)
{
    if (isset($search[$key]) || array_key_exists($key, $search)) {
        if ($replace === NULL) {
            return $search[$key];
        } else {
            $search[$key] = $replace;
            return true;
        }
    }
    foreach ($search as $k => $v) {
        if (is_array($v) && count($v) > 0) {
            return array_key_search($search[$k], $key, $replace);
        }
    }
    return false;
}
/**
 * Iterates over an array containing PHP and handles calls to enabled functions and executes them.
 * @param {phpObj} array A JSON decoded array of representational PHP.
 * @return {*} Will return the results of the last function call passed in through phpObj.
 */
function parse_php_object($arr, $config)
{
    // We define a pointer array that contains reference names to parameter placeholders
    // that will be replaced by real data.
    $pointers = array();
    // We store a list of all PHP defined constants. We use this array to match against arguments
    // sent from JavaScript that will naturally be in string form but are intended to represent
    // constants.
    $constants = get_defined_constants(true);
    foreach ($arr as $k => $v) {
        // Create variable definition with our first level array keys
        ${$k} = $v;
        // Populate our pointers index
        $pointers[$k] = $k;
        // When a value is an object we attempt to call functions defined within
        if (is_object(${$k})) {
            // Convert our function object to an array
            $funcArr = (array) ${$k};
            // Use the first key of the function array as our function name to call
            $func_name = array_keys($funcArr);
            $func_name = $func_name[0];
            // Get the array of arguments to parse to our arguments array
            $func_args = $funcArr[$func_name];
            // Create an array to store the arguments to pass to our function call
            $args_arr = array();
            // Now we iterate over our function arguments looking for reference strings
            foreach ($func_args as $arg) {
                // We compare against the keys in our pointers index which was created above
                if (array_key_exists($arg, $pointers)) {
                    // This is now a reference to ${$k}, the originally defined definition, the returned
                    // result of the last sucessful function call
                    $p = ${$arg};
                    // We push our arguments onto the args_array which will be passed to our function call
                    array_push($args_arr, $p);
                } else {
                    // We push our arguments onto the args_array which will be passed to our function call
                    array_push($args_arr, $arg);
                }
            }
            // Create our final cleaned array
            $args_clean_arr = array();
            // Iterate over function parameters
            foreach ($args_arr as $arg) {
                // Test if any function arguments are function calls themselves
                print $arg;
                if (function_exists($arg)) {
                }
                // At this point we test if a function argument is a literal. If it is we replace the
                // literal string with its value.
                if (is_string($arg)) {
                    $constant = array_key_search($arg, $constants);
                    if (isset($constant)) {
                        $arg = $constant;
                    }
                }
                array_push($args_clean_arr, $arg);
            }
            // Based on the security mode selected, use either our blacklist or whitelist.
            switch ($config['SEC_MODE']) {
                case 'blacklist':
                    if (function_exists($func_name) && !in_array($func_name, $config['LISTS']['blacklist'])) {
                        $function_allowed = true;
                    } else {
                        $function_allowed = false;
                    }
                    break;
                case 'whitelist':
                    if (function_exists($func_name) && in_array($func_name, $config['LISTS']['whitelist'])) {
                        $function_allowed = true;
                    } else {
                        $function_allowed = false;
                    }
                    break;
            }
            // Call the requested function if permitted
            if ($function_allowed === true) {
                // Reassign our variable the returned value of a function call so that further function calls can
                // search for the existence of pointers and then use the updated variable definitions. This logic
                // takes advantage of the procedural nature of PHP and the order of the sub-blocks in the php object.
                ${$k} = call_user_func_array($func_name, $args_clean_arr);
            } else {
                return "Function you requested {$func_name} has been disabled by backend configuration.";
            }
        } else {
            // Handle any recursive objects in arrays, cast them to arrays
            if (is_array(${$k})) {
                array_walk_recursive(${$k}, 'object_to_array');
            }
            // Handle any type casting of arrays and objects
            if (json_decode(${$k}) !== NULL) {
                ${$k} = json_decode(${$k});
                if (is_object(${$k})) {
                    ${$k} = (array) ${$k};
                }
            }
        }
    }
    // Return the returned result from our final function call
    return ${$k};
}
function array_key_search($needle, $haystack)
{
    if (isset($haystack[$needle])) {
        return $haystack[$needle];
    } else {
        foreach ($haystack as $key => $value) {
            if (is_array($value) && ($return = array_key_search($needle, $haystack))) {
                return $return;
            }
        }
    }
    return null;
}