public function getRealIP($allowPrivateRange = false, array $prependHeaders = null)
    {
        $headers = [
            'HTTP_CF_CONNECTING_IP', // CloudFlare sent IP
            'CLIENT_IP',
            'FORWARDED',
            'FORWARDED_FOR',
            'FORWARDED_FOR_IP',
            'HTTP_CLIENT_IP',
            'HTTP_FORWARDED',
            'HTTP_FORWARDED_FOR',
            'HTTP_FORWARDED_FOR_IP',
            'HTTP_PC_REMOTE_ADDR',
            'HTTP_PROXY_CONNECTION',
            'HTTP_VIA',
            'HTTP_X_FORWARDED',
            'HTTP_X_FORWARDED_FOR',
            'HTTP_X_FORWARDED_FOR_IP',
            'HTTP_X_IMFORWARDS',
            'HTTP_X_PROXY_CONNECTION',
            'VIA',
            'X_FORWARDED',
            'X_FORWARDED_FOR',
            'REMOTE_ADDR',      // REMOTE_ADDR is always set, use it as last resort
        ];

        if($prependHeaders !== null && !empty($prependHeaders)) {
            $headers = array_merge($prependHeaders, $headers);
        }

        foreach($headers as $row) {
            if(!array_key_exists($row, $_SERVER)) {
                continue;
            }

            foreach(explode(',', $_SERVER[$row]) as $ip) {
                $tmpIp = trim ($ip);
                $portPos = stripos ($tmpIp, ':');

                if(!filter_var($tmpIp, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) && false !== $portPos) {
                    $tmpIp = substr ($tmpIp, 0, $portPos);
                }

                $flag = $allowPrivateRange
                    ? FILTER_FLAG_NO_RES_RANGE
                    : FILTER_FLAG_NO_RES_RANGE | FILTER_FLAG_NO_PRIV_RANGE;

                if(false === filter_var($tmpIp, FILTER_VALIDATE_IP, $flag)) {
                    continue;
                }

                return $realIp = $tmpIp;
            }
        }

        return $realIp = false;
    }