public static function camelCaseToUnderscore($string)
    {
        static $cache = array();

        if (array_key_exists($string, $cache) === true) {
            return $cache[$string];
        }

        $replacer = function(array $matches) {
            return '_' . strtolower($matches[0]);
        };

        return $cache[$string] = preg_replace_callback('/[A-Z]/', $replacer, $string);
    }