如果本文对您有帮助,或者节约了您的时间,欢迎打赏瓶饮料,建立下友谊关系。
本博客不欢迎:各种镜像采集行为。请尊重原创文章内容,转载请保留链接信息。

一般来说,正常的thinkphp项目都会有多个模块,包括:面向用户的pc版网站,面向用户的m版网站,面向管理员的用户界面。在项目实际上线后,这些模块往往会要求有不同的域名,比如:pc版和手机版不同域名,后台管理要单独的域名。在代码层面,这些不同的域名上线部署,需要我们做些额外的配置。在本文中,苏南大叔将以thinkcmf为例,说说:如何给不同的模块配置不同的域名。服务器容器使用的是nginx。

背景描述

因为thinkcmf的代码默认根目录是/public/,默认入口文件是/public/index.php。这样的话,我们新建一个/public/m.php作为手机版的入口文件,然后新建一个/public/admin.php作为后台管理的入口文件。根据不同的使用场景,新建的这两个文件,苏南大叔将采用两种写法来配置,各有利弊。本文涉及的thinkcmf的版本为5.0.180123

/public/index.php的代码如下:

define("APP_DEBUG", false);
define('CMF_ROOT', __DIR__ . '/../');
define('APP_PATH', CMF_ROOT . 'app/');
define('CMF_PATH', CMF_ROOT . 'framework/cmf/');
define('PLUGINS_PATH', __DIR__ . '/plugins/');
define('EXTEND_PATH', CMF_ROOT . 'framework/extend/');
define('VENDOR_PATH', CMF_ROOT . 'framework/vendor/');
define('RUNTIME_PATH', CMF_ROOT . 'data/runtime/');
define('THINKCMF_VERSION', '5.0.180123');
require CMF_ROOT . 'framework/thinkphp/base.php';
\think\App::run()->send();

下图是本文中,涉及的nginx的版本号。

thinkcmf高级应用之多模块自定义域名及入口文件 - nginx_v

thinkcmf高级应用之多模块自定义域名及入口文件(图2-1)

本文中的pc站的nginx配置如下:

server{
    listen 80;
    server_name <pc版的域名>;
    root /<代码路径>/public/;
    location / {
        index  index.php index.html index.htm;
        if (!-e $request_filename){
            rewrite ^/(.*)$ /index.php/$1;
         }
    }
    location ~ \.php {
      include fastcgi_params;
      set $path_info "";
      set $real_script_name $fastcgi_script_name;
      if ($fastcgi_script_name ~ "^(.+?\.php)(/.+)$") {
        set $real_script_name $1;
        set $path_info $2;
      }
      fastcgi_param SCRIPT_FILENAME $document_root$real_script_name;
      fastcgi_param SCRIPT_NAME $real_script_name;
      fastcgi_param PATH_INFO $path_info;
      fastcgi_intercept_errors on;
      fastcgi_pass   127.0.0.1:9000;
   }
   location ^~ /upload/ {
        alias  /<用户的上传文件的路径>/usr/upload/ ;
   }
   location ^~ /admin/ {
        deny all;
   }
   location ^~ /m/ {
        rewrite ^(.*)$  http://<手机站的域名>/$1 permanent;
   }
}

第一种方案:最简单最小化的方案。

在这种方案下,/public/admin.php仅仅是做个跳转,后面的一切请求还是由/public/index.php来承担,比较适合作为后台的入口文件处理方案。这种方案改动最小。

但是这种方案,也会有些问题,就是:页面地址url中,会一直出现着/admin/这个模块名称。这对于有洁癖的人来说,也许是个负担,毕竟已经启用了独立的域名用于后台管理了。所以,url中这个一直出现的/admin/字样是有些多余的。

不过考虑到:后台的使用人员相对固定,而且对于url地址一般不敏感。所以,这个小问题是可以忽略不计的。

thinkcmf高级应用之多模块自定义域名及入口文件 - admin_ui

thinkcmf高级应用之多模块自定义域名及入口文件(图2-2)

/public/admin.php的代码如下:

header("Location:/admin/");

管理后台的nginx配置如下,仅仅写出个关键点,其余配置请参考pc版的nginx配置内容。

server{
    server_name <后台的域名>;
    // ...
    location / {
        index  admin.php;
        if (!-e $request_filename){
            rewrite ^/(.*)$ /index.php/$1;
         }
    }
    #location ^~ /portal/ {
    #     rewrite ^(.*)$  http://<pc站的域名>/$1 permanent;
    #}
    location ^~ /m/ {
         rewrite ^(.*)$  http://<手机站的域名>/$1 permanent;
    }
    # ...
}

这里请注意:对于以/portal/开头的请求,理论上来说,应该都是前台pc版的内容。但是事实上,thinkcmf的后台页面中,也是有几个页面(内容管理)功能是调用的/portal/开头的地址。苏南大叔认为:这个是thinkcmf代码构架本身的问题。修复的方案,在后面的文章中,苏南大叔会做相关介绍。

作为最简单弱智的方案来说,nginx里面就暂时对于/portal/开头的请求,不做任何拦截处理了。否则,后台中的一些功能是不能使用的,具体表现就是:后台的文章内容管理模块。

第二个方案:近乎完美版方案

针对上一个方案中,页面的地址栏会一直存在/<模块名称>/的弊端。对于这个对象广大用户的手机版来说,这样似乎是不妥当的,所以在这里,苏南大叔提出了一个新的方案,近乎完美,但是为了兼容模板里面资源文件的写法,需要修改thinkcmf的一个核心文件。当然,苏南大叔认为,这个也许是thinkcmf的一个小小bug。

/public/m.php的代码如下:

define('BIND_MODULE','m');
require_once "index.php";

手机版网站的nginx配置如下,仅仅写出个关键点,其余配置请参考pc版的nginx配置内容。

server{
    server_name <手机版的域名>;
    // ...
    location / {
        index  m.php;
        if (!-e $request_filename){
            rewrite ^/(.*)$ /m.php/$1;  //注意这里
         }
    }
    location ^~ /portal/ {
         rewrite ^(.*)$  http://<pc站的域名>/$1 permanent;
    }
    location ^~ /admin/ {
        deny all;
    }
    # ...
}

这里,/public/m.php全权负责起入口文件的责任,替代了/public/index.php文件的存在。当然出于代码复用角度来看,苏南大叔includeindex.php。其实,主要的作用点就是下面这句话,指定了这个入口文件m.php的对应的模块的是m

define('BIND_MODULE','m');

在nginx配置中,注意:除了默认首页配置为m.php外,所有的不存在实体文件的请求,也都由m.php来处理。这样配置之后,访问页面,会出现很多的404错误。模板中常用的变量,比如__STATIC__也会被替换成显然有错误的/m.php/static/,而不是期待的/static/。注意,第一种方案是没有这个问题的,因为所有文件还是由/public/index.php处理的。

不细说调试过程,说一下解决方案。就是修改thinkcmf的内核文件。请找到如下内核文件:/<framework目录>/cmf/common.php,切换到函数cmf_get_root()

修改前的cmf_get_root()函数:

function cmf_get_root()
{
    $request = Request::instance();
    $root    = $request->root();
    $root    = str_replace('/index.php', '', $root);
    if (defined('APP_NAMESPACE') && APP_NAMESPACE == 'api') {
        $root = preg_replace('/\/api$/', '', $root);
        $root = rtrim($root, '/');
    }
    return $root;
}

苏南大叔修改后的cmf_get_root()函数:

function cmf_get_root()
{
    $request = Request::instance();
    $root    = $request->root();
    //$root    = str_replace('/index.php', '', $root);
    //主要是入口文件不是index.php的话,就出各种问题了.....
    $root    = dirname($root);
    if (defined('APP_NAMESPACE') && APP_NAMESPACE == 'api') {
        $root = preg_replace('/\/api$/', '', $root);
    }
    $root = rtrim($root, '/');
    return $root;
}

这样修改这个内核文件后,就可以愉快的新增新的入口文件,并且可以愉快的使用__STATIC__等系统常量了。perfect~

结论

这两种新增入口文件的方案,一个简单一个完美。根据您的实际情况。选择一个即可。本文的内容,较为高级。一般来说,不会有这么高级的需求的。对吧?最终的结果就是:三个入口文件,对应于三个不同域名。访问不同的域名的时候,显示的内容是完全不一样的。

更多thinkcmf的经验文章,请点击这里查看:https://newsn.net/tag/thinkcmf/

  【php】秘籍文章入口,仅传授于有缘之人  php    thinkphp

欢迎转载传播本篇原创文章,转载请保留链接及作者信息。
本站采用创作共用版权协议, 要求署名、非商业用途和相同方式共享。
转载本站内容必须也遵循“署名-非商业用途-相同方式共享”的创作共用协议。
程序如此灵动~》下所有原创文章,如被用于商业用途,请您按规定支付稿费。

苏南大叔需要你的支持

打赏任意金额,发送截图到邮箱 shang@newsn.net ,可以领取精选回馈如下(任选其一):
  • 《前端视频教程大礼包》一套
  • 《wordpress精选皮肤》一套
  • 《dedecms织梦精选模板》一套
感谢您的打赏,让我更有动力,将更多精彩教程文章,呈现给大家!谢谢!

岁月静好

关注互联网发展,关注苏南大叔的《程序如此灵动~》博客
本文章来自:程序如此灵动~
博客地址为:https://newsn.net/
原文地址为:https://newsn.net/say/thinkcmf-module-domain.html
上一篇好文:thinkcmf模板执行php代码的两种方式
下一篇好文:thinkcmf高级应用之分离前台及管理模块

如果您转载了本文章,出于某种原因,并没有注明作者或者出处。
在这里,苏南大叔也表示理解和支持。因为苏南大叔深深地明白:
您会在合适的时机,合适的地方,给本博客一个外链。对吧?
您若开心,便是安好!岁月静好,但愿世界和平,没有纷争~