如果用户会话中存在子域,我希望所有 Cakephp url 都使用子域......所以如果用户会话中有一个条目“子域:用户”,所有页面都将以“用户”作为前缀:例如用户.example.com、user.example.com/settings。
是否有捷径可寻?
谢谢,
kSeudo
您可以使用自定义路由类。在 APP/Lib/Route 中创建一个名为 UserSubdomainRoute.php 的文件并将其放入其中。
<?php
App::uses('AuthComponent', 'Controller/Component');
class UserSubdomainRoute extends CakeRoute {
/**
* @var CakeRequest
*/
private $Request;
/**
* Length of domain's TLD
*
* @var int
*/
public static $_tldLength = 1;
public function __construct($template, $defaults = array(), $options = array()) {
parent::__construct($template, $defaults, $options);
$this->Request = new CakeRequest();
$this->options = array_merge(array('protocol' => 'http'), $options);
}
/**
* Sets tld length
*
* @param $length
* @return mixed void|int
*/
public static function tldLength($length = null) {
if (is_null($length)) {
return self::$_tldLength;
}
self::$_tldLength = $length;
}
/**
* Writes out full url with protocol and subdomain
*
* @param $params
* @return string
*/
protected function _writeUrl($params) {
$protocol = $this->options['protocol'];
$subdomain = AuthComponent::user('subdomain');
if (empty($subdomain)) {
$subdomain = 'www';
}
$domain = $this->_getDomain();
$url = parent::_writeUrl($params);
return "{$protocol}://{$subdomain}.{$domain}{$url}";
}
/**
* Get domain name
*
* @return string
*/
protected function _getDomain() {
return $this->Request->domain(self::$_tldLength);
}
}
该类的一项改进可能是使 $Request 静态。
不幸的是,在 Cake 2.0 中没有办法设置 defaultRotueClass,但是,我在 2.1+ 中添加了该功能,我不想告诉您升级,因此您将不得不在第三个中为您的所有路线手动指定它像这样的参数:
Router::connect(..., ..., array('routeClass' => 'UserSubdomainRoute');
一定要在 routes.php 的顶部添加
App::uses('UserSubdomainRoute', 'Lib/Route');
如果你升级到 2.1+,你可以在你的 routes.php 顶部添加这个
Router::defaultRouteClass('UserSubdomainRoute');
然后之后指定的任何路由都将使用该路由类。
路由类的主要部分是_writeUrl
方法。subdomain
它检查会话中是否存在密钥集,否则使用www
并构建完整的 url 以返回。
注意:还没有测试过课程,还在学校只是想给你一个快速的开始。它只是我的 SubdomainRoute 的修改版本,它的工作方式有点不同(它过去只匹配设置某个子域时的路由,例如在我的应用程序中匹配clients
子域到我的ClientsAdminPanel
插件。你可以在这里获取:http://bin .cakephp.org/view/50699397因此,如果您需要UserSubdomainRoute
和我的组合SubdomainRoute
(在链接中),您也可以看到它是如何完成的。
希望这对现在有所帮助。让我知道是否有任何问题。
编辑:这是强制重定向的方法 - 有些东西告诉我有更好的方法。如果我能想到它,我会更新。
public function beforeFilter() {
$subdomains = $this->request->subdomains();
$subdomain = $this->Auth->user('subdomain');
if (!empty($subdomain) && !in_array($subdomain, $subdomains)) {
$this->redirect('http://' . $subdomain . '.site.com' . $this->request->here);
}
}
好吧,如果您希望对所有链接都这样做,可能您使用相同的方式在您的网站上显示所有网址,您是否使用类似 $this->html->link('/blah/asd/','blah '); ?
IN 蛋糕/路线/路线
class SubdomainRoute extends CakeRoute {
public function match($params) {
$subdomain = isset($params['subdomain']) ? $params['subdomain'] : null;
unset($params['subdomain']);
$path = parent::match($params);
if ($subdomain) {
$path = 'http://' . $subdomain . '.localhost' . $path;
}
return $path;
}
}
创建链接时,您可以执行以下操作以使链接指向其他子域。
echo $this->Html->link(
'Other domain',
array('subdomain' => 'test', 'controller' => 'posts', 'action' => 'add')
);