2015-11-06 247 views
0

我在Laravel中有一个应用程序堆栈,我们将继续并切换到SaaS模型。为了做到这一点,我只是假设我可以将所有路由包含在一个具有动态域属性的组中,激发一个过滤器,然后观察$ route参数以使其发生。Laravel 4--动态多域路由中断模型绑定和链接

我应该注意到这实际上是一个多租户应用程序,但实际上我们已经决定将这个数据库分开。

所以在这里,我们去:

在我routes.php文件,我有以下几点:

Route::group(array('domain' => '{domain}.{tld}', 'before' => 'database.setup'), function() 
{ 


    Route::group(array('prefix' => 'backend', 'before' => 'auth'), function() { 
     //all of my routes 
    }); 
}); 

正如你可以从上面的,当所要求的任何途径看,它要的我已经在filters.php得到了定义database.setup过滤器:

Route::filter('database.setup', function($route, $request){ 
    $domain = $route->getParameter('domain').'.'.$route->getParameter('tld'); 

    $details = DB::table('my_table')->where('domain', '=', $domain)->first(); 
    if($details){ 

     Config::set('database.connections.account', [ 
      'driver' => 'mysql', 
      'host' => 'my_host', 
      'database' => Encryption::decrypt($details->db_hash, 'my_salt'), 
      'username' => 'my_username', 
      'password' => 'my_password', 
      'collation' => 'utf8_unicode_ci', 
      'prefix' => '', 
      'charset' => 'utf8', 
     ]); 


     //these are things I was doing to get the URL-permalink working. 
     Config::set('app.url', 'http://' . $domain); 
     Config::set('app.domain', $domain); 
     Config::set('session.domain', '.' . $domain); 

     //This actually works exactly as I've intended 
     Config::set('database.connections.default', 'account'); 
     DB::setDefaultConnection('account'); 
    } 

}); 

现在开始我以为这是工作的罚款。正确的记录从表格中拉出来,数据库在没有问题的情况下开启,同时销毁前一个实例。

但是,我注意到我已经在路线中丢失了所有模型绑定关系。

路由像这样:

Route::get('/shipping/packages/{package}', '[email protected]'); 

被定义为这样一种模式:

Route::model('package', 'Package'); 

不幸的是总会产生这样的:

No query results for model [Package]. 

现在,如果我删除我的从路由过滤器,一切工作正常,但默认的数据库将被使用一个大的没有不适用于我的应用程序

最后,所有的永久链接结构似乎已被彻底打破。

http://example.com/shipping/packages/package 

我反而看到:不是看到我的域名,当我将鼠标悬停在链接,如

%7Bdomain%7D.%7Btld%7D/shipping/packages/package 

我不知道这是为什么发生。

我试着重载响应对象,更改过滤器中的站点配置以及其他东西的设置,但我总是以某种方式结束相同的问题。

如果有人对如何解决这个问题有任何线索,我会非常感激。

+0

你可以试试''域'=>'{域}。{tld} .example.com'和$域= $ route-> getParameter('域')。'。'。$ route- > getParameter('tld')。'。example.com'在你的代码中 –

+0

@ChetanAmeta好的。我放弃了这一点。结果是没有找到帐户条目,因为该域在数据库中不匹配,所以它将我带到了Saas服务的页面,而不是客户端的页面。 – Ohgodwhy

+0

好吧,只有更改应用程序域才能工作,'Config :: set('app.domain',$ domain。'example.com');'leave'$ domain = $ route-> getParameter('domain') '。'。$ route-> getParameter('tld');'因为它是 –

回答

0

好的,我已经找出问题所在。

我明显没有仔细阅读文档。如果你穿过路由器组调用它最终会调用mergeGroup(),在这个特殊的功能,你可以看到下面的代码:

$new['where'] = array_merge(array_get($old, 'where', []), array_get($new, 'where', [])); 

在这里,我们可以看到,他们只是使用栈跟踪这些值,所以{domain}.{tld}的字面解释被推入堆栈。

这是最初的工作很好,因为我的过滤器实际上抓住他们明确:

$domain = $route->getParameter('domain').'.'.$route->getParameter('tld'); 

要解决这个问题,我只需要创建自己的辅助函数,将抢$主机(这是一个非常基本的实现,而应帮助清晰度)

$domain = get_domain(); 

Route::group(array('domain' => $domain, 'before' => 'database.setup'), function() 

然后在我的助手文件,我已经添加了get_domain()功能:

if (! function_exists('get_domain')) 
{ 
    function get_domain() 
    { 
     $url_parts = parse_url(Request::root()); 

     return $url_parts['host']; 
    } 
} 

然后,我可以简单地调用get_domain()在我的过滤器,以及它会始终保持同步:

Route::filter('database.setup', function($route, $request){ 
$domain = get_domain(); 

现在这完美的作品。