$val) { static::set($key, true, static::NAMESPACE_FLASH_REMOVE); } Controller::queueToRunAfterResponse([__CLASS__, 'cleanupFlashes']); } public static function cleanupFlashes() { foreach (array_keys(static::getNamespace(static::NAMESPACE_FLASH_REMOVE)) as $flashName) { static::unsetKey($flashName, static::NAMESPACE_FLASH); static::unsetKey($flashName, static::NAMESPACE_FLASH_REMOVE); } } public static function getFlash($name, $default = null) { return static::get($name, $default, static::NAMESPACE_FLASH); } public static function setFlash($name, $value) { static::set($name, $value, static::NAMESPACE_FLASH); static::unsetKey($name, static::NAMESPACE_FLASH_REMOVE); } public function persistFlashes() { static::unsetNamespace(static::NAMESPACE_FLASH_REMOVE); } public static function getClientIP() { // Nothing to do without any reliable information if (!isset($_SERVER['REMOTE_ADDR'])) { return null; } // Header that is used by the trusted proxy to refer to // the original IP $proxyHeader = "HTTP_X_FORWARDED_FOR"; // List of all the proxies that are known to handle 'proxy_header' // in known, safe manner $trustedProxies = array("127.0.0.1"); if (in_array($_SERVER['REMOTE_ADDR'], $trustedProxies)) { // Get IP of the client behind trusted proxy if (array_key_exists($proxyHeader, $_SERVER)) { // Header can contain multiple IP-s of proxies that are passed through. // Only the IP added by the last proxy (last IP in the list) can be trusted. $clientIP = trim(end(explode(",", $_SERVER[$proxyHeader]))); // Validate just in case if (filter_var($clientIP, FILTER_VALIDATE_IP)) { return $clientIP; } else { // Validation failed - beat the guy who configured the proxy or // the guy who created the trusted proxy list? // TODO: some error handling to notify about the need of punishment } } } // In all other cases, REMOTE_ADDR is the ONLY IP we can trust. return $_SERVER['REMOTE_ADDR']; } }