0.8 $langs = array_combine($lang_parse[1], $lang_parse[4]); // set default to 1 for any without q factor foreach ($langs as $lang => $val) { if ($val === '') { $langs[$lang] = 1; } } // sort list based on value arsort($langs, SORT_NUMERIC); $langs = array_map('strtolower', array_keys($langs)); } } return $langs; } /** * HTTP Cache * * Sends HTTP cache headers (304) according to a list of files and an optionnal. * list of timestamps. * * @param array $files Files on which check mtime * @param array $mod_ts List of timestamps */ public static function cache($files, $mod_ts = []) { if (empty($files) || !is_array($files)) { return; } array_walk($files, function (&$v) { $v = filemtime($v); }); $array_ts = array_merge($mod_ts, $files); rsort($array_ts); $now = time(); $ts = min($array_ts[0], $now); $since = null; if (!empty($_SERVER['HTTP_IF_MODIFIED_SINCE'])) { $since = $_SERVER['HTTP_IF_MODIFIED_SINCE']; $since = preg_replace('/^(.*)(Mon|Tue|Wed|Thu|Fri|Sat|Sun)(.*)(GMT)(.*)/', '$2$3 GMT', $since); $since = strtotime($since); $since = ($since <= $now) ? $since : null; } # Common headers list $headers[] = 'Last-Modified: ' . gmdate('D, d M Y H:i:s', $ts) . ' GMT'; $headers[] = 'Cache-Control: must-revalidate, max-age=' . abs((integer) self::$cache_max_age); $headers[] = 'Pragma:'; if ($since >= $ts) { self::head(304, 'Not Modified'); foreach ($headers as $v) { header($v); } exit; } else { header('Date: ' . gmdate('D, d M Y H:i:s', $now) . ' GMT'); foreach ($headers as $v) { header($v); } } } /** * HTTP Etag * * Sends HTTP cache headers (304) according to a list of etags in client request. */ public static function etag() { # We create an etag from all arguments $args = func_get_args(); if (empty($args)) { return; } $etag = '"' . md5(implode('', $args)) . '"'; unset($args); header('ETag: ' . $etag); # Do we have a previously sent content? if (!empty($_SERVER['HTTP_IF_NONE_MATCH'])) { foreach (explode(',', $_SERVER['HTTP_IF_NONE_MATCH']) as $i) { if (stripslashes(trim($i)) == $etag) { self::head(304, 'Not Modified'); exit; } } } } /** * HTTP Header * * Sends an HTTP code and message to client. * * @param string $code HTTP code * @param string $msg Message */ public static function head($code, $msg = null) { $status_mode = preg_match('/cgi/', PHP_SAPI); if (!$msg) { $msg_codes = [ 100 => 'Continue', 101 => 'Switching Protocols', 200 => 'OK', 201 => 'Created', 202 => 'Accepted', 203 => 'Non-Authoritative Information', 204 => 'No Content', 205 => 'Reset Content', 206 => 'Partial Content', 300 => 'Multiple Choices', 301 => 'Moved Permanently', 302 => 'Found', 303 => 'See Other', 304 => 'Not Modified', 305 => 'Use Proxy', 307 => 'Temporary Redirect', 400 => 'Bad Request', 401 => 'Unauthorized', 402 => 'Payment Required', 403 => 'Forbidden', 404 => 'Not Found', 405 => 'Method Not Allowed', 406 => 'Not Acceptable', 407 => 'Proxy Authentication Required', 408 => 'Request Timeout', 409 => 'Conflict', 410 => 'Gone', 411 => 'Length Required', 412 => 'Precondition Failed', 413 => 'Request Entity Too Large', 414 => 'Request-URI Too Long', 415 => 'Unsupported Media Type', 416 => 'Requested Range Not Satisfiable', 417 => 'Expectation Failed', 500 => 'Internal Server Error', 501 => 'Not Implemented', 502 => 'Bad Gateway', 503 => 'Service Unavailable', 504 => 'Gateway Timeout', 505 => 'HTTP Version Not Supported' ]; $msg = isset($msg_codes[$code]) ? $msg_codes[$code] : '-'; } if ($status_mode) { header('Status: ' . $code . ' ' . $msg); } else { header($msg, true, $code); } } /** * Trim request * * Trims every value in GET, POST, REQUEST and COOKIE vars. * Removes magic quotes if magic_quote_gpc is on. */ public static function trimRequest() { if (!empty($_GET)) { array_walk($_GET, ['self', 'trimRequestInVar']); } if (!empty($_POST)) { array_walk($_POST, ['self', 'trimRequestInVar']); } if (!empty($_REQUEST)) { array_walk($_REQUEST, ['self', 'trimRequestInVar']); } if (!empty($_COOKIE)) { array_walk($_COOKIE, ['self', 'trimRequestInVar']); } } private static function trimRequestInVar(&$value, $key) { if (is_array($value)) { foreach ($value as $k => &$v) { if (is_array($v)) { self::trimRequestInVar($v, $k); } else { $v = trim($v); } } } else { $value = trim($value); } } /** * Unset global variables * * If register_globals is on, removes every GET, POST, COOKIE, REQUEST, SERVER, * ENV, FILES vars from GLOBALS. */ public static function unsetGlobals() { if (!ini_get('register_globals')) { return; } if (isset($_REQUEST['GLOBALS'])) { throw new Exception('GLOBALS overwrite attempt detected'); } # Variables that shouldn't be unset $no_unset = ['GLOBALS', '_GET', '_POST', '_COOKIE', '_REQUEST', '_SERVER', '_ENV', '_FILES']; $input = array_merge( $_GET, $_POST, $_COOKIE, $_SERVER, $_ENV, $_FILES, (isset($_SESSION) && is_array($_SESSION) ? $_SESSION : []) ); foreach ($input as $k => $v) { if (!in_array($k, $no_unset) && isset($GLOBALS[$k])) { $GLOBALS[$k] = null; unset($GLOBALS[$k]); } } } }