params = self::params();
return self::$instance;
}
/**
* 获取ip地址
*
* @return string ip地址:如 59.151.9.90
*/
public function ip() {
if (isset($_SERVER)) {
if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
$realip = $_SERVER['HTTP_X_FORWARDED_FOR'];
} elseif (isset($_SERVER['HTTP_CLIENT_IP'])) {
$realip = $_SERVER['HTTP_CLIENT_IP'];
} else {
$realip = $_SERVER['REMOTE_ADDR'];
}
} else {
if (getenv("HTTP_X_FORWARDED_FOR")) {
$realip = getenv("HTTP_X_FORWARDED_FOR");
} elseif (getenv("HTTP_CLIENT_IP")) {
$realip = getenv("HTTP_CLIENT_IP");
} else {
$realip = getenv("REMOTE_ADDR");
}
}
$realip = preg_replace('#,.*$#', '', $realip);
$realip = preg_replace('#[^\d\.]+#', '', $realip);// 从支付平台发现,有时会获取到这种ip,%20%2058.255.8.39,说明前面有有空格,处理一下
return $realip;
}
/**
* 从 REQUEST_URI 字段获取请求路径
* 如:/article/index.php?id=857&action=show 会被处理成:article/index.php
*
* @param string | null $request_uri
* @return string
*/
public function path($request_uri = null) {
if (is_null($request_uri)) {
$request_uri = $_SERVER['REQUEST_URI'];
}
if (($iPos = strpos($request_uri, '?')) !== false) {
$request_uri = substr($request_uri, 0, $iPos);
}
$request_uri = str_replace(' ', '/', trim(str_replace('/', ' ', $request_uri)));
$request_uri = urldecode($request_uri);
return $request_uri;
}
/**
*
* 获取当前请求的url
* @return String 完整的url,如:http://www.kimiss.com/test.php?c=Default
*/
public function url() {
$port = $_SERVER['SERVER_PORT'] == '80' ? '' : ":{$_SERVER['SERVER_PORT']}";
$url = "http://{$_SERVER['HTTP_HOST']}{$_SERVER['REQUEST_URI']}";
return $url;
}
/**
*
* 获取分类url的模版
* @param string $pageKey 请求里表示分页的参数
* @return string
*/
public function pageUrlTpl($pageKey = 'page') {
$routeParams = Route::getInstance()->getsRouteParams();
if ($routeParams) {
$routeParams[$pageKey] = '{page}';
$path = Route::getInstance()->reverse($routeParams);
$url = "http://{$_SERVER['HTTP_HOST']}/" . $path;
return String::jointUrl($url, array_diff_key($_GET, $routeParams));
} else {
$request_params = $_GET;
$request_params[$pageKey] = '{page}';
$url = "http://{$_SERVER['HTTP_HOST']}/" . $this->path();
return String::jointUrl($url, $request_params);
}
}
/**
*
* 获取带请求协议的域名url,如:https://kimiss.com
* @return string
*/
static public function schemeDomain() {
$protocol_str = $_SERVER['SERVER_PROTOCOL'];
if (!$protocol_str) {
return '';
}
list($protocol,) = explode('/', $protocol_str);
return strtolower($protocol) . "://{$_SERVER['HTTP_HOST']}";
}
/**
*
* 获取当前请求的顶级域名
* @param string $host
* @return string
*/
public function rootDomain($host = null) {
if (is_null($host))
$host = $_SERVER['HTTP_HOST'];
if (empty($host)) {
return '';
}
$host = strtolower($host);
# 是个ip直访的url
if (filter_var($host, FILTER_VALIDATE_IP)) {
return '';
}
# 不带.,可能是绑host的域名
if (strpos($host, '.') === FALSE) {
return $host;
}
$domain_suffs = array(
'.com', '.cn', '.net', '.com.cn', '.net.cn',
'.org', '.me', '.biz', '.name', '.org.cn', '.gov.cn',
'.info', '.so', '.tel', '.mobi', '.asia', '.cc', '.tv', '.co',
);
foreach ($domain_suffs as $suff) {
$tmp_stuff_pos = strrpos($host, $suff);
if ($tmp_stuff_pos === false) {
continue;
}
$tmp_rootdomain_pos = strrpos($host, '.', 0-strlen(substr($host, $tmp_stuff_pos))-1);
if ($tmp_rootdomain_pos === false) {
return $host;
}
return substr($host, $tmp_rootdomain_pos+1);
}
}
/**
* 获取请求url中的查询字符串
*
* @return string
*/
static public function queryString() {
return $_SERVER['QUERY_STRING'];
}
/**
*
* 获取请求的referer
* @return string
*/
static public function referer() {
return $_SERVER['HTTP_REFERER'];
}
/**
* 是否POST请求
*
* @return boolean
*/
static public function isPost() {
return strtoupper($_SERVER['REQUEST_METHOD']) == 'POST';
}
/**
* 是否GET请求
*
* @return boolean
*/
static public function isGet() {
return strtoupper($_SERVER['REQUEST_METHOD']) == 'GET';
}
/**
* 该请求是否由 蜘蛛 发出
*
* @return boolean
*/
public function isSpider() {
if (self::isCLI()) {
return false;
}
if (!isset($_SERVER['HTTP_USER_AGENT'])) {
return false;
}
$bots = array(
'Googebot', 'Baiduspider', 'Yahoo! Slurp', 'Sosospider', 'Sogou', 'Sogou-Test-Spider',
'Sogou head spider', 'YoudaoBot', 'qihoobot', 'iaskspider', 'LeapTag', 'MSIECrawler'
);
foreach ($bots as $bot) {
if (strpos($_SERVER['HTTP_USER_AGENT'], $bot) !== false) {
return true;
}
}
if (stristr($_SERVER['HTTP_USER_AGENT'], 'Windows') !== false) {
return false;
}
$bots = array(
'spider', 'bit', 'crawler', 'slurp', 'subscriber', 'http',
'rssreader', 'blogline', 'greatnews', 'feed', 'alexa', 'php'
);
foreach ($bots as $bot) {
if (stristr($_SERVER['HTTP_USER_AGENT'], $bot) !== false) {
return true;
}
}
return false;
}
/**
* 该请求是否从相同的主机过来,即来源页是否与当前页处于相同域下
*
* @return boolean
*/
public function isFromSameHost() {
if (!isset($_SERVER['HTTP_REFERER'])) {
return true;
}
$url_parts = parse_url($_SERVER['HTTP_REFERER']);
$host = $url_parts['host'];
if ($_SERVER['HTTP_HOST'] == $host) {
return true;
}
return false;
}
/**
* 从请求的 $_GET 变量里获取 变量的整数值,如果不存在该变量或不为整数,则返回 $default 值
* @param string $varName 变量名
* @param int $default 默认值
* @return int
*/
public function varGetInt($varName, $default = 0) {
if (!isset($_GET[$varName])) {
return $default;
}
if (!Verify::unsignedInt($_GET[$varName])) {
return $default;
}
return $_GET[$varName];
}
/**
* 从请求的 $_POST 变量里获取 变量的整数值,如果不存在该变量或不为整数,则返回 $default 值
* @param string $varName 变量名
* @param int $default 默认值
* @return int
*/
public function varPostInt($varName, $default = 0) {
if (!isset($_POST[$varName])) {
return $default;
}
if (!Verify::unsignedInt($_POST[$varName])) {
return $default;
}
return $_POST[$varName];
}
/**
* 从请求的 $_POST 变量里获取 变量的整数值,如果不存在该变量或不为整数,则返回 $default 值
* @param string $varName 变量名
* @param int $default 默认值
* @return int
*/
public function varRequestInt($varName, $default = 0) {
if (!isset($_REQUEST[$varName])) {
return $default;
}
if (!Verify::unsignedInt($_REQUEST[$varName])) {
return $default;
}
return $_REQUEST[$varName];
}
/**
* 获取请求的参数集。
* 支持http访问的参数 以及 命令行下访问的参数
* demo1:php test.php -p3 -t=abc --opt=valopt --opt2 valopt2
* demo2 http://test.kimiss.com/index.php?c=xxx&a=ddd
* @return array
*/
public function params() {
if (self::isCLI()) {
return self::cliParams();
} else {
return $_REQUEST;
}
}
/**
*
* 获取命令行下传递进来的参数
* 只支持以 - 或 -- 开头的参数
* demo:php test.php -p3 -t=abc --opt=valopt --opt2 valopt2
* @return array
*/
private function cliParams() {
$result = array();
$params = $GLOBALS['argv'];
array_shift($params);
reset($params);
do {
$tmpEachResult = each($params);
if (!$tmpEachResult) {
break;
}
list($tmp, $p) = $tmpEachResult;
if ($p{0} == '-') {
$pname = substr($p, 1);
$value = false;
if ($pname{0} == '-') {// 长选项 (--)
$pname = substr($pname, 1);
if (strpos($p, '=') !== false) {
// value specified inline (--=)
list($pname, $value) = explode('=', substr($p, 2), 2);
}
} else {// 短选项
if (strpos($p, '=') !== false) {
// value specified inline (-=)
list($pname, $value) = explode('=', substr($p, 1), 2);
} else if (strlen($p) > 1) {
$pname = substr($p, 1, 1);
$value = substr($p, 2);
}
}
# 如果上面没有取到值,并且下一个不是以-开头的,则下一个值为当前参数的值
$nextparm = current($params);
if ($value === false
&& $nextparm !== false
&& $nextparm{0} != '-'
) {
list($tmp, $value) = each($params);
}
$result[$pname] = (string) $value;// 将 false转为空串,以便与http访问时对参数的处理一致
} else {
# 不是以-指定开始的参数,一律丢弃
//$result[] = $p;
}
} while (true);
return $result;
}
/**
*
* 获取 $_GET 里指定key $name 的值,同时可以指定 $filters 过滤方法处理值
*
* 用法:
* 1、对值不做任何处理:Request::getInstance()->get('content', null);
* 2、对值做html转义处理:Request::getInstance()->get('name');
*
* @param string $name
* @param mixed $filters 默认使用html转义过滤。当值为null里,对值不做任何过滤。
* $filters支持以下格式:
* 1) 标量类型,如:
* Filter::HTMLSPECIALCHARS;
* 2) 多个filter,如:
* array(
* Filter::HTMLSPECIALCHARS,
* Filter::STRIP_TAGS,
* );
* 3) 多个filter,并且某些filter另外指定参数,如:
* array(
* array(
* Filter::HTMLSPECIALCHARS => ENT_QUOTES,
* ),
* array(
* Filter::STRIP_TAGS => "",
* ),
* Filter::STRIP_SELECTED_TAGS,
* );
*
* @throws ParamsException "无效的过滤方法filter"
* @return string
*/
public function get($name, $filters = array(Filter::HTMLSPECIALCHARS, Filter::TRIM)) {
if (!isset($_GET[$name])) {
return false;
}
$val = $_GET[$name];
if (is_null($filters)) {
return $val;
}
if (!is_array($filters)) {
$filters = array($filters);
}
return self::filter($val, $filters);
}
/**
*
* get的别名方法
* @param string $name
* @param mixed $filters 默认使用html转义过滤。当值为null里,对值不做任何过滤。
* @throws ParamsException "无效的过滤方法filter"
* @return string
*/
public function g($name, $filters = array(Filter::HTMLSPECIALCHARS, Filter::TRIM)) {
return self::get($name, $filters);
}
/**
*
* 获取 $_POST 里指定key $name 的值,同时可以指定 $filters 过滤方法处理值
*
* 用法:
* 1、对值不做任何处理:Request::getInstance()->post('content', null);
* 2、对值做html转义处理:Request::getInstance()->post('name');
*
* @param string $name
* @param mixed $filters 默认使用html转义过滤。当值为null里,对值不做任何过滤。
* @throws ParamsException "无效的过滤方法filter"
* @return string
*/
public function post($name, $filters = array(Filter::HTMLSPECIALCHARS, Filter::TRIM)) {
if (!isset($_POST[$name])) {
return false;
}
$val = $_POST[$name];
if (is_null($filters)) {
return $val;
}
if (!is_array($filters)) {
$filters = array($filters);
}
return self::filter($val, $filters);
}
/**
*
* post的别名方法
* @param string $name
* @param mixed $filters 默认使用html转义过滤。当值为null里,对值不做任何过滤。
* @throws ParamsException "无效的过滤方法filter"
* @return string
*/
public function p($name, $filters = array(Filter::HTMLSPECIALCHARS, Filter::TRIM)) {
return self::post($name, $filters);
}
/**
*
* 获取 $_REQUEST 里指定key $name 的值,同时可以指定 $filters 过滤方法处理值
* !! 因为与类同名的方法会被认为是构造函数,所以这个方法名加个小字符 !!
*
* 用法:
* 1、对值不做任何处理:Request::getInstance()->requestV('content', null);
* 2、对值做html转义处理:Request::getInstance()->requestV('name');
*
* @param string $name
* @param mixed $filters 默认使用html转义过滤。当值为null里,对值不做任何过滤。
* @throws ParamsException "无效的过滤方法filter"
* @return string
*/
public function requestV($name, $filters = array(Filter::HTMLSPECIALCHARS, Filter::TRIM)) {
if (!isset($_REQUEST[$name])) {
return false;
}
$val = $_REQUEST[$name];
if (is_null($filters)) {
return $val;
}
if (!is_array($filters)) {
$filters = array($filters);
}
return self::filter($val, $filters);
}
/**
*
* requestV的别名方法
* @param string $name
* @param mixed $filters 默认使用html转义过滤。当值为null里,对值不做任何过滤。
* @throws ParamsException "无效的过滤方法filter"
* @return string
*/
public function r($name, $filters = array(Filter::HTMLSPECIALCHARS, Filter::TRIM)) {
return self::requestV($name, $filters);
}
/**
*
* 获取 $_COOKIE 里指定key $name 的值,同时可以指定 $filters 过滤方法处理值
*
* 用法:
* 1、对值不做任何处理:Request::getInstance()->cookie('content', null);
* 2、对值做html转义处理:Request::getInstance()->cookie('name');
*
* @param string $name
* @param mixed $filters 默认使用html转义过滤。当值为null里,对值不做任何过滤。
* @throws ParamsException "无效的过滤方法filter"
* @return string | false
*/
public function cookie($name, $filters = array(Filter::HTMLSPECIALCHARS, Filter::TRIM)) {
if (!isset($_COOKIE[$name])) {
return false;
}
$val = $_COOKIE[$name];
if (is_null($filters)) {
return $val;
}
if (!is_array($filters)) {
$filters = array($filters);
}
return self::filter($val, $filters);
}
/**
*
* cookie的别名方法
* @param string $name
* @param mixed $filters 默认使用html转义过滤。当值为null里,对值不做任何过滤。
* @throws ParamsException "无效的过滤方法filter"
* @return string | false
*/
public function c($name, $filters = array(Filter::HTMLSPECIALCHARS, Filter::TRIM)) {
return self::cookie($name, $filters);
}
/**
*
* 获取当前请求参数里指定key $name 的值,同时可以指定 $filters 过滤方法处理值
*
* 用法:
* 1、对值不做任何处理:Request::getInstance()->param('content', null);
* 2、对值做html转义处理:Request::getInstance()->param('name');
*
* @param string $name
* @param mixed $filters 默认使用html转义过滤。当值为null里,对值不做任何过滤。
* @throws ParamsException "无效的过滤方法filter"
* @return string | false
*/
public function param($name, $filters = array(Filter::HTMLSPECIALCHARS, Filter::TRIM)) {
if (!isset($this->params[$name])) {
return false;
}
$val = $this->params[$name];
if (is_null($filters)) {
return $val;
}
if (!is_array($filters)) {
$filters = array($filters);
}
return self::filter($val, $filters);
}
/**
*
* 使用用户指定的 过滤方法,过滤值 $val
* @param string $val
* @param array $filters 过滤方法相关信息
* @throws ParamsException "无效的过滤方法filter"
* @return string
*/
private function filter($val, array $filters) {
foreach ($filters as $filter) {
$params = array($val);
if (is_array($filter)) {
list($filter_name, $filter_options) = each($filter);
} else {
$filter_name = $filter;
$filter_options = null;
}
if (!Filter::isValid($filter_name)) {
throw new ParamsException("无效的过滤方法filter");
}
$val = call_user_func(array('KIF\String\Filter', $filter_name), $val, $filter_options);
}
return $val;
}
/**
* 是否处于命令行下
* @return Boolean
*/
static public function isCLI() {
if (php_sapi_name() == "cli"//PHP 4 >= 4.0.1, PHP 5 support php_sapi_name function
|| empty($_SERVER['PHP_SELF'])//If PHP is running as a command-line processor this variable contains the script name since PHP 4.3.0. Previously it was not available.
) {
return true;
} else {
return false;
}
}
/**
* 是否类unix系统
* @return Boolean
*/
static public function isUnixLike() {
$os = strtolower(PHP_OS);
if (in_array($os, array('linux', 'freebsd', 'unix', 'netbsd'))) {
return true;
}
return false;
}
/**
*
* 分发请求,调用Controller以及对应的action
*/
public function dispatch() {
$params = $this->params;
$controllerName = self::getController($params);
if (!class_exists($controllerName)) {
throw new Exception("controller: {$controllerName} not exists!");
}
$action = self::getAction($params);
$controller = new $controllerName();
$controller->setAction($action);
$controller->run();
if (method_exists($controller, 'display')) {
$controller->display();
}
}
public function getController() {
$c = self::param('c');
$c = trim($c, '_');
$arr_class_path = array_map(function ($tmpV) {
return ucfirst($tmpV);
}, explode('_', $c));
$c = join('\\', $arr_class_path);
$NS = Config::getInstance()->get('Namespace');
$controller = "{$NS}\Controller\\{$c}";
return $controller;
}
public function getAction(array $params = null) {
$action = self::param('a');
return $action;
}
}