ThinkPHP3.2.3 二级域名设置深入(包括一系列问题的解决方案)
一直在学习,转载很多,也没为大家做点什么,今天花了大半天时间研究这个,中途看了几集<人民的名义>,达康书记确实不容易.书归正传,查了很多资料,大家都在说tp路由,不过没找到讲二级路由实现原理的,也没人给出在哪个文件封装了方法,探索·发现开始:
第一步:参考了tp手册,关于开启设置的很多文章
先在convention.php找到这两个设置,具体的方法参考TP手册:http://www.w3cschool.cn/thinkphp323/3xm2lozt.html
开启域名部署
无论是子域名还是IP部署,首先要在应用配置文件中开启APP_SUB_DOMAIN_DEPLOY
,这是前提,然后配置域名部署规则APP_SUB_DOMAIN_RULES
。
'APP_SUB_DOMAIN_DEPLOY' => 1, // 开启子域名或者IP配置
'APP_SUB_DOMAIN_RULES' => array( /* 域名部署配置 *格式1: '子域名或泛域名或IP'=> '模块名[/控制器名]'; *格式2: '子域名或泛域名或IP'=> array('模块名[/控制器名]','var1=a&var2=b&var3=*'); */
)
域名部署的定义格式2和1的区别在于格式2可以隐式传入额外的参数。
第二步:如果是本地要在host设置ip绑定,如果是线上服务器需要域名解析到服务器根目录
host设置ip绑定
然后配置虚拟主机路径用*号表示匹配所有的子域名到本域名下
此时该配置的都配完毕了,下一步该测试了:
问题一:BIND_MODULE常量已设置
你以为这就完成了吗?其实根本没有指向Blog模块,他走了默认模块,于是发现问题应该出在默认设置:
入口文件index.php设置了绑定模块
需要注销这个,但是后来我发现问题的关键并不是默认的问题,而是在tp子域名部署方法里,又定义了一次这个BIND_MODULE常量,导致路由出错,可以把默认模块绑定DEFAULT_MODEL常量代替
问题二:到底域名部署在哪?
我们常常设置了一个常量,true/false,然后功能就出来了,于是渐渐的就把这个设置当做理所当然,很好奇"开关"的背后,终于找到了.
代码如下:
// 开启子域名部署if(C('APP_SUB_DOMAIN_DEPLOY')) {$rules = C('APP_SUB_DOMAIN_RULES'); //array(2) { ["blog"]=> string(4) "Blog" ["home"]=> string(4) "Home" } if(isset($rules[$_SERVER['HTTP_HOST']])) { // 完整域名或者IP配置define('APP_DOMAIN',$_SERVER['HTTP_HOST']); // 当前完整域名$rule = $rules[APP_DOMAIN];}else{if(strpos(C('APP_DOMAIN_SUFFIX'),'.')){ // com.cn net.cn $domain = array_slice(explode('.', $_SERVER['HTTP_HOST']), 0, -3);}else{$domain = array_slice(explode('.', $_SERVER['HTTP_HOST']), 0, -2); }if(!empty($domain)) {$subDomain = implode('.', $domain);define('SUB_DOMAIN',$subDomain); // 当前完整子域名$domain2 = array_pop($domain); // 二级域名if($domain) { // 存在三级域名$domain3 = array_pop($domain);}if(isset($rules[$subDomain])) { // 子域名$rule = $rules[$subDomain]; // string(4)"Blog" }elseif(isset($rules['*.' . $domain2]) && !empty($domain3)){ // 泛三级域名$rule = $rules['*.' . $domain2];$panDomain = $domain3;}elseif(isset($rules['*']) && !empty($domain2) && 'www' != $domain2 ){ // 泛二级域名$rule = $rules['*'];$panDomain = $domain2;}} }if(!empty($rule)) {// 子域名部署规则 '子域名'=>array('模块名[/控制器名]','var1=a&var2=b');if(is_array($rule)){list($rule,$vars) = $rule;}$array = explode('/',$rule);// 模块绑定define('BIND_MODULE',array_shift($array)); 注意:此处常量可能在入口index.php重复设置!!!!!// 控制器绑定 if(!empty($array)) {$controller = array_shift($array);if($controller){define('BIND_CONTROLLER',$controller);}}if(isset($vars)) { // 传入参数parse_str($vars,$parms);if(isset($panDomain)){$pos = array_search('*', $parms);if(false !== $pos) {// 泛域名作为参数$parms[$pos] = $panDomain;} } $_GET = array_merge($_GET,$parms);}}}// 分析PATHINFO信息if(!isset($_SERVER['PATH_INFO'])) {$types = explode(',',C('URL_PATHINFO_FETCH'));foreach ($types as $type){if(0===strpos($type,':')) {// 支持函数判断$_SERVER['PATH_INFO'] = call_user_func(substr($type,1));break;}elseif(!empty($_SERVER[$type])) {$_SERVER['PATH_INFO'] = (0 === strpos($_SERVER[$type],$_SERVER['SCRIPT_NAME']))?substr($_SERVER[$type], strlen($_SERVER['SCRIPT_NAME'])) : $_SERVER[$type];break;}}}$depr = C('URL_PATHINFO_DEPR');define('MODULE_PATHINFO_DEPR', $depr);if(empty($_SERVER['PATH_INFO'])) {$_SERVER['PATH_INFO'] = '';define('__INFO__','');define('__EXT__','');}else{define('__INFO__',trim($_SERVER['PATH_INFO'],'/'));// URL后缀define('__EXT__', strtolower(pathinfo($_SERVER['PATH_INFO'],PATHINFO_EXTENSION)));$_SERVER['PATH_INFO'] = __INFO__; if(!defined('BIND_MODULE') && (!C('URL_ROUTER_ON') || !Route::check())){if (__INFO__ && C('MULTI_MODULE')){ // 获取模块名$paths = explode($depr,__INFO__,2);$allowList = C('MODULE_ALLOW_LIST'); // 允许的模块列表$module = preg_replace('/\.' . __EXT__ . '$/i', '',$paths[0]);if( empty($allowList) || (is_array($allowList) && in_array_case($module, $allowList))){$_GET[$varModule] = $module;$_SERVER['PATH_INFO'] = isset($paths[1])?$paths[1]:'';}}} }// URL常量define('__SELF__',strip_tags($_SERVER[C('URL_REQUEST_URI')]));// 获取模块名称define('MODULE_NAME', defined('BIND_MODULE')? BIND_MODULE : self::getModule($varModule));// 检测模块是否存在if( MODULE_NAME && (defined('BIND_MODULE') || !in_array_case(MODULE_NAME,C('MODULE_DENY_LIST')) ) && is_dir(APP_PATH.MODULE_NAME)){// 定义当前模块路径define('MODULE_PATH', APP_PATH.MODULE_NAME.'/');// 定义当前模块的模版缓存路径C('CACHE_PATH',CACHE_PATH.MODULE_NAME.'/');// 定义当前模块的日志目录C('LOG_PATH', realpath(LOG_PATH).'/'.MODULE_NAME.'/');// 模块检测Hook::listen('module_check');// 加载模块配置文件if(is_file(MODULE_PATH.'Conf/config'.CONF_EXT))C(load_config(MODULE_PATH.'Conf/config'.CONF_EXT));// 加载应用模式对应的配置文件if('common' != APP_MODE && is_file(MODULE_PATH.'Conf/config_'.APP_MODE.CONF_EXT))C(load_config(MODULE_PATH.'Conf/config_'.APP_MODE.CONF_EXT));// 当前应用状态对应的配置文件if(APP_STATUS && is_file(MODULE_PATH.'Conf/'.APP_STATUS.CONF_EXT))C(load_config(MODULE_PATH.'Conf/'.APP_STATUS.CONF_EXT));// 加载模块别名定义if(is_file(MODULE_PATH.'Conf/alias.php'))Think::addMap(include MODULE_PATH.'Conf/alias.php');// 加载模块tags文件定义if(is_file(MODULE_PATH.'Conf/tags.php'))Hook::import(include MODULE_PATH.'Conf/tags.php');// 加载模块函数文件if(is_file(MODULE_PATH.'Common/function.php'))include MODULE_PATH.'Common/function.php';$urlCase = C('URL_CASE_INSENSITIVE');// 加载模块的扩展配置文件load_ext_file(MODULE_PATH);}else{E(L('_MODULE_NOT_EXIST_').':'.MODULE_NAME);}if(!defined('__APP__')){$urlMode = C('URL_MODEL');if($urlMode == URL_COMPAT ){// 兼容模式判断define('PHP_FILE',_PHP_FILE_.'?'.$varPath.'=');}elseif($urlMode == URL_REWRITE ) {$url = dirname(_PHP_FILE_);if($url == '/' || $url == '\\')$url = '';define('PHP_FILE',$url);}else {define('PHP_FILE',_PHP_FILE_);}// 当前应用地址define('__APP__',strip_tags(PHP_FILE));}// 模块URL地址$moduleName = defined('MODULE_ALIAS')? MODULE_ALIAS : MODULE_NAME;define('__MODULE__',(defined('BIND_MODULE') || !C('MULTI_MODULE'))? __APP__ : __APP__.'/'.($urlCase ? strtolower($moduleName) : $moduleName));if('' != $_SERVER['PATH_INFO'] && (!C('URL_ROUTER_ON') || !Route::check()) ){ // 检测路由规则 如果没有则按默认规则调度URLHook::listen('path_info');// 检查禁止访问的URL后缀if(C('URL_DENY_SUFFIX') && preg_match('/\.('.trim(C('URL_DENY_SUFFIX'),'.').')$/i', $_SERVER['PATH_INFO'])){send_http_status(404);exit;}// 去除URL后缀$_SERVER['PATH_INFO'] = preg_replace(C('URL_HTML_SUFFIX')? '/\.('.trim(C('URL_HTML_SUFFIX'),'.').')$/i' : '/\.'.__EXT__.'$/i', '', $_SERVER['PATH_INFO']);$depr = C('URL_PATHINFO_DEPR');$paths = explode($depr,trim($_SERVER['PATH_INFO'],$depr));if(!defined('BIND_CONTROLLER')) {// 获取控制器if(C('CONTROLLER_LEVEL')>1){// 控制器层次$_GET[$varController] = implode('/',array_slice($paths,0,C('CONTROLLER_LEVEL')));$paths = array_slice($paths, C('CONTROLLER_LEVEL'));}else{$_GET[$varController] = array_shift($paths);}}// 获取操作if(!defined('BIND_ACTION')){$_GET[$varAction] = array_shift($paths);}// 解析剩余的URL参数$var = array();if(C('URL_PARAMS_BIND') && 1 == C('URL_PARAMS_BIND_TYPE')){// URL参数按顺序绑定变量$var = $paths;}else{preg_replace_callback('/(\w+)\/([^\/]+)/', function($match) use(&$var){$var[$match[1]]=strip_tags($match[2]);}, implode('/',$paths));}$_GET = array_merge($var,$_GET);}// 获取控制器的命名空间(路径)define('CONTROLLER_PATH', self::getSpace($varAddon,$urlCase));// 获取控制器和操作名define('CONTROLLER_NAME', defined('BIND_CONTROLLER')? BIND_CONTROLLER : self::getController($varController,$urlCase));define('ACTION_NAME', defined('BIND_ACTION')? BIND_ACTION : self::getAction($varAction,$urlCase));// 当前控制器的UR地址$controllerName = defined('CONTROLLER_ALIAS')? CONTROLLER_ALIAS : CONTROLLER_NAME;define('__CONTROLLER__',__MODULE__.$depr.(defined('BIND_CONTROLLER')? '': ( $urlCase ? parse_name($controllerName) : $controllerName )) );// 当前操作的URL地址define('__ACTION__',__CONTROLLER__.$depr.(defined('ACTION_ALIAS')?ACTION_ALIAS:ACTION_NAME));//保证$_REQUEST正常取值$_REQUEST = array_merge($_POST,$_GET,$_COOKIE); // -- 加了$_COOKIE. 保证哦..}/*** 获得控制器的命名空间路径 便于插件机制访问*/static private function getSpace($var,$urlCase) {$space = !empty($_GET[$var])?strip_tags($_GET[$var]):'';unset($_GET[$var]);return $space;}/*** 获得实际的控制器名称*/static private function getController($var,$urlCase) {$controller = (!empty($_GET[$var])? $_GET[$var]:C('DEFAULT_CONTROLLER'));unset($_GET[$var]);if($maps = C('URL_CONTROLLER_MAP')) {if(isset($maps[strtolower($controller)])) {// 记录当前别名define('CONTROLLER_ALIAS',strtolower($controller));// 获取实际的控制器名return ucfirst($maps[CONTROLLER_ALIAS]);}elseif(array_search(strtolower($controller),$maps)){// 禁止访问原始控制器return '';}}if($urlCase) {// URL地址不区分大小写// 智能识别方式 user_type 识别到 UserTypeController 控制器$controller = parse_name($controller,1);}return strip_tags(ucfirst($controller));}/*** 获得实际的操作名称*/static private function getAction($var,$urlCase) {$action = !empty($_POST[$var]) ?$_POST[$var] :(!empty($_GET[$var])?$_GET[$var]:C('DEFAULT_ACTION'));unset($_POST[$var],$_GET[$var]);if($maps = C('URL_ACTION_MAP')) {if(isset($maps[strtolower(CONTROLLER_NAME)])) {$maps = $maps[strtolower(CONTROLLER_NAME)];if(isset($maps[strtolower($action)])) {// 记录当前别名define('ACTION_ALIAS',strtolower($action));// 获取实际的操作名if(is_array($maps[ACTION_ALIAS])){parse_str($maps[ACTION_ALIAS][1],$vars);$_GET = array_merge($_GET,$vars);return $maps[ACTION_ALIAS][0];}else{return $maps[ACTION_ALIAS];}}elseif(array_search(strtolower($action),$maps)){// 禁止访问原始操作return '';}}}return strip_tags( $urlCase? strtolower($action) : $action );}
里面有很多严谨的步骤,可以消化一段时间了
问题三:解决thinkphp3.2出现无法加载控制器:Index的问题
有时候由于各种不小心,把命名空间弄错了,就会出现这个问题,注意命名空间
问题四,开启路由并设置各自的路由规则
这样一总结,感觉也没多少问题,洗洗睡了.
ThinkPHP5.0完全开发手册最新域名路由: http://www.kancloud.cn/manual/thinkphp5/118039
ThinkPHP3.2.3 二级域名设置深入(包括一系列问题的解决方案)相关推荐
- Nginx-部署2个vue项目(多个项目)-二级域名设置代理
前言 最近在实际开发过程中,需要在服务器部署2个项目.需要nginx二级域名. 开始时候在网上查了一圈,各有说法,不是很全,很头大.这里把自己成功的二级域名代理记录一下. 网上有很多文章说要该rout ...
- 蚂蚁分类信息系统Nginx伪静态规则支持二级域名设置方法
蚂蚁分类信息系统Nginx伪静态规则支持二级域名设置方法 nginx环境中蚂蚁分类信息系统支持二级域名访问实现方法 1.后台生成所有城市目录 2.nginx伪静态增加配置 if ( $host ~* ...
- 帝国cms如何域名html的专题,帝国cms 二级域名绑定栏目的最完美的解决方案
帝国cms 二级域名绑定栏目的最完美的解决方案 发布时间:2011-11-10 22:40:06 作者:佚名 我要评论 帝国cms 二级域名绑定栏目的最完美的解决方案,需要绑定二级域名的朋友可 ...
- linux 二级域名设置
首先,你的拥有一个有泛域名解析的顶级域名,例如: domain.com 其次,在 httpd.conf 中打开 mod_rewrite 之后,在 httpd.conf 的最后,添加以下内容: Rewr ...
- apache 二级域名设置
1. 你要拥有一个有泛域名解析的顶级域名,例如:test.com 在dns服务上设置,域名服务商都提供此服务 www.test.com 指向服务器IP test.com 指 ...
- php 跨二级域名 设置cookie
登入也设置cookie setcookie('user_id', authlogin("user_id", "ENCODE"), time()+(3600*24 ...
- 二级域名三级域名设置方法
因为网站需要,要设定二级和三域名,写个东西出来,大家看看. 比如您的域名是haoday.com,需要增加一个二级域名bbs.haoday.com,当然www.haoday.com也是二级域名,只不过是 ...
- 子域名绑定html,DEDE二级域名(多站点)绑定详解
关键字描述:详解 站点 栏目 顶级   设置 绑定 目录 支持 二级域名 首先,DEDE在绑定多域名之前,需先作如下准备: 1.服务器或空间支持, 2.将你的域名指定到目录 接着我们就 ...
- tomcat中配置二级域名
1.二级域名可以在域名提供商网站上进行解析设置 例如将二级域名设置为image解析方式设置方法如下: 2.设置完域名解析后在tomcat配置文件tomcat\conf\server.xml中配置 &l ...
最新文章
- sci-learn fit_transform() 与 transform()
- 今天来说一下我的SAMC
- 【Java从0到架构师(2),Java面试问题
- e影安全智能浏览器_【启耀玻璃】智能调光玻璃有什么特点? - 调光艺术玻璃|防火防弹玻璃|LOW-E节能玻璃|隔音隔热玻璃|特种安全玻璃|夹层中空玻璃-...
- 将Swagger与Spring Boot REST API集成
- windows10 计算文件的HASH(SHA256\MD5等)
- 成功的MES项目,前期都做了些什么?
- Intellij Idea 创建maven WebAPP项目
- 【在大学的快乐生活】锐捷校园网无感认证通过路由器mac地址克隆实现一账号多终端
- discuz论坛引入iframe
- 微信小程序tab切换效果
- c语言程序设计景点售票系统,c语言售票系统.docx
- 美团23届秋招全面启动!5000+机会,60+岗位,3次笔试机会!
- | ERROR: [2] bootstrap checks failed. You must address the points described in the following [2] lin
- 电脑开机出现警报音后提示要按F1才能进入的分析处理
- 增加检测类别?这是一份目标检测的基础指南
- Quartz源码解读-任务是如何定时执行的
- C++上机实验六第2题
- 锁定计算机忘记密码,笔记本防盗锁忘记密码_笔记本电脑锁忘记密码
- LeetCode刷题——36.有效的数独