2015-11-06 242 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(); 

現在這完美的作品。