public function fnmatch($pattern, $url)
    {
        $quoted = preg_quote($pattern, '~');

        $step1 = strtr($quoted, ['\?' => '[^/]', '\*' => '[^/]*', '/\*\*' => '(?:/.*)?', '#' => '\d+', '\[' => '[',
            '\]' => ']', '\-' => '-', '\{' => '{', '\}' => '}']);

        $step2 = preg_replace_callback('~{[^}]+}~', function ($part) {
            return '(?:' . substr(strtr($part[0], ',', '|'), 1, -1) . ')';
        }, $step1);

        $regex = rawurldecode($step2);
        return (boolean)preg_match("~^{$regex}$~i", $url);
    }