用drupal建立多站点是一件方便的事,最近遇到多站点的项目,需要共享用户数据,在此记录下多种实现方案。电脑配置是win 7,drupal 7,apache,仅在本地测试,放到虚拟主机上,需要配置好dns,或者还需要空间商的帮助。
方案一:同一个drupal core,同一个数据库。
我们将建立dsjz.cn,a.dsjz.cn,b.dsjz.cn三个站点。
首先,打开Apache 配置文件 httpd.conf,
#virtual hosts
# Include conf/extra/httpd-vhosts.conf
修改成
#virtual hosts
Include conf/extra/httpd-vhosts.conf
接下来在其中添加虚拟主机的配置:
# VirtualHost saydrual.com <VirtualHost *:80> DocumentRoot "D:/Apache/saydrupal" ServerName a.dsjz.cn
ServerAlias www.a.dsjz.cn </virtualhost>
<VirtualHost *:80>
DocumentRoot "D:/Apache/saydrupal" ServerName b.dsjz.cn
ServerAlias www.b.dsjz.cn </virtualhost>
<VirtualHost *:80>
DocumentRoot "D:/Apache/saydrupal" ServerName www.dsjz.cn ServerAlias dsjz.cn </virtualhost>
可能你已经发现了,ServerName有个www.的区别。
这里面用到一个trick,后面将提及到。重启Apache服务器。
上面的配置是最简单的配置,如果对虚拟主机的配置不了解,可以在这里http://httpd.apache.org/docs/2.2/vhosts/ 查看虚拟机的指令。
添加DNS记录,打开c:\windows\system32\drivers\etc\hosts 127.0.0.1 localhost
127.0.0.1 www.dsjz.cn dsjz.cn 127.0.0.1 a.dsjz.cn www.a.dsjz.cn 127.0.0.1 b.dsjz.cn www.b.dsjz.cn
为不同的站点添加目录。“D:/Apache/saydrupal”文件夹是我们的安装目录,接下来就该是在/sites的下面新建三个空文件夹,www.dsjz.cn, a.dsjz.cn, b.dsjz.cn。
在mysql数据库里,新建一个database saydrupal。
现在,可以安装这三个站点了。
注意,不要在浏览器里使用localhost/saydrupal。
浏览器地址栏里输入www.dsjz.cn安装总站,安装过程,在database配置页面,database name 是saydrupal,prefix里输入main_。地址栏里输入a.dsjz.cn安装第一个分站,在database 配置页面,database name 是saydrupal,prefix里输入a_。第二个分站同理。
安装完毕后,打开dsjz.cn文件夹下面的settings.php,修改权限,让它可写。
找到这句,$cookie_domain = \'.dsjz.cn\'; 去掉前面的„#‟,注意dsjz.cn前面有个点。
同理打开a.dsjz.cn文件夹下面的settings.php,$cookie_domain = \'.dsjz.cn\';这句是一样的处理方式。
分站还要处理database配置:
..................虚线范围是数据库调用,拷贝下面的数据,按照你自己数据库名称改动就可以了.......................................................
$databases = array ( \'default\' => array ( \'default\' => array (
\'database\' => \'sadrupal\', \'username\' => \'admin\', \'password\' => \'admin\', \'host\' => \'localhost\', \'port\' => \'\',
\'driver\' => \'mysql\', \'prefix\' => array( \'default\' => \'a_\', \'users\' => \'main_\', \'sessions\' => \'main_\', \'role\' => \'main_\', \'authmap\' => \'main_\', ) ), ), );
.......................注意_有的数据库前缀是没有_的..................................................
这样,分站a.dsjz.cn就会与总站dsjz.cn共享用户数据。注意开始安装的时候,总站跟分站的超级用户,也就是安装用户,用户名跟密码应该是一样的。
现在,可以新建一个用户,尝 试在几个站点间试试用户共享了。
这里对上面的几点再做些补充。
第一步,配置虚拟主机的时候,假如ServerName 写的是dsjz.cn而不是www.dsjz.cn,然后文件夹名称也是dsjz.cn。那么在安装完总站后,其余的分站可能就装不起来了。按照drupal搜索配置文件,也就是搜索settings.php文件的规则,假如先安装了dsjz.cn,下次安装a.dsjz.cn的时候,它会先在a.dsjz.cn文件夹下面寻找settings.php,如果没有找到,它会在dsjz.cn文件夹下寻找配置文件。OK,我们之前已经安装了dsjz.cn,那么它当然会在dsjz.cn文件夹下找到settings.php,所以浏览器就会把我们带到dsjz.cn的页面,而不是预期的a.dsjz.cn的安装页面。所以,在安装dsjz.cn的时候,使用的文件夹是www.dsjz.cn,ServerName同样是www.dsjz.cn。那么如果在地址栏里输入dsjz.cn,能否安装呢?可以,我们使用了ServerAlias dsjz.cn这会让dsjz.cn重定向到www.dsjz.cn。当然,也可以使用drupal的sites.php文件来达到这个效果。
从这里的描述,可以衍生出很多变种的配置的方法。例如,安装a.dsjz.cn的时候,也可以用文件夹www. a.dsjz.cn。注意,所有的站点,都应该用同一个$cookie_domain。
方案二:同一个drupal core,不同的数据库。
这个方案,跟上面的方案差不多。唯一的区别是,配置数据库的时候,每个分站都应该使用自己的数据库名,表前缀就不需要了,例如saydrupal,asaydrupal,bsaydrupal。安装完毕后,修改分站的database 配置:
我们在这里修改a.dsjz.cn下的settings.php:
$databases = array ( \'default\' => array ( \'default\' => array (
\'database\' => \'asaydrupal\', \'username\' => \'admin\', \'password\' => \'admin\', \'host\' => \'localhost\', \'port\' => \'\',
\'driver\' => \'mysql\', \'prefix\' => array(
\'default\' => \'asaydrupal.\', \'users\' => \'saydrupal.\', \'sessions\' => \'saydrupal.\',
\'role\' => \'saydrupal.\', \'authmap\' => \'saydrupal.\', ) ), ), );
这里表的前缀,使用的数据库名。当然,这些数据库应该在同一个host上面,例如,localhost。还有一个需要注意的还是,$cookie_domain也应该是一样。
这里也衍生出其他的配置方案。例如,可以使用不同的drupal core分别建立属于自己的独立站点,包括数据库也是独立 的。也可以是完全不同的一级域名,例如dsjz.cn跟hellodrupal.com。当然,用第一种方案,同样可以做出来不同的一级域名,效果类似。
只要将不同的数据库都保存在一个host上面,就可以通过数据库名做前缀,来达到共享数据的目的。如果不同的数据库在安装的时候,使用了table prefix,例如saydrupal的数据库表的前缀是main_,a.dsjz.cn的数据库asaydrupal里表的前缀a_,那么分站a.saydruapl.com数据库就该这样配置,
$databases = array ( \'default\' => array ( \'default\' => array (
\'database\' => \'asaydrupal\', \'username\' => \'admin\', \'password\' => \'admin\', \'host\' => \'localhost\', \'port\' => \'\',
\'driver\' => \'mysql\', \'prefix\' => array(
\'default\' => \'asaydrupal.a_\', \'users\' => \'saydrupal.main_\', \'sessions\' => \'saydrupal.main_\', \'role\' => \'saydrupal.main_\', \'authmap\' => \'saydrupal.main_\', ) ), ), );
还有一个需要注意的是,这些数据库,应该使用相同的username,以及password,否则一个站点不够权限去链接另一个站点的数据库。
方案三:
这个是对方案一的补充,使用domain 模块,http://drupal.org/project/domain。
一个core,
一个database,
这个方案除了可以顺利共享数据库外,还可以很方便地共享网站的所有node content。这是一个很好的方案,如果总站跟分站,还有分站跟分站之间需要共享很多数据的话,不仅仅是用户的数据,这个方案很不错。安装之前,需要仔细阅读它的安装文件,否则会一头雾水。
这个更多的是将所有的content物理上放到一起,然后通过分配权限,来读取。如果使用第一种,或第二种方案,要共享数据的话,可以共享更多的table。如果不这样的做,有个方案是,用feed来读取不同网站的数据。
总的来说,共享table是一件危险的事。这会为日后网站升级更新,以及功能开发,留下安全隐患。共享用户的数据表,那么在今后对user 做了深度开发,例如添加了一个user profile field后,需要及时更新settings.php的配置。应该尽可能地减少共享数据表的数目,并且应该只是对drupal高级开发者适用。