Php Laravel 4——动态多域路由中断模型绑定&;链接

Php Laravel 4——动态多域路由中断模型绑定&;链接,php,laravel,laravel-4,Php,Laravel,Laravel 4,我在Laravel有一个应用程序堆栈,我们将继续使用它,并切换到SaaS模型。为了做到这一点,我假设我可以使用动态域属性将我的所有路由封装在一个组中,启动一个过滤器,然后观察$route参数以实现这一点 我应该注意到,这实际上是一个多租户应用程序,但实际上我们已经决定为这个应用程序分离数据库 现在我们开始: 在我的routes.php文件中,我得到了以下内容: Route::group(array('domain' => '{domain}.{tld}', 'before' => '

我在Laravel有一个应用程序堆栈,我们将继续使用它,并切换到SaaS模型。为了做到这一点,我假设我可以使用动态域属性将我的所有路由封装在一个组中,启动一个过滤器,然后观察$route参数以实现这一点

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

现在我们开始:

在我的
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
中定义的
数据库.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}', 'PackageController@get');
对于这样定义的模型:

Route::model('package', 'Package');
不幸的是,结果总是这样:

No query results for model [Package].
现在,如果我从路由中删除我的过滤器,一切都会正常工作,但是默认数据库将用于我的应用程序

最后,所有的permalink结构似乎都被完全破坏了。而不是在我将鼠标悬停在链接上时看到我的域,例如:

http://example.com/shipping/packages/package
相反,我看到:

%7Bdomain%7D.%7Btld%7D/shipping/packages/package
我不知道为什么会这样

我尝试过重载响应对象,更改过滤器中站点配置的设置,以及许多其他事情,但我总是以某种方式遇到同样的问题


如果有人对如何解决这个问题有任何线索,我将不胜感激。

好的,我已经找到了问题所在

我显然没有把文档读得足够好。如果您遍历路由器组调用,它最终将调用mergeGroup(),在这个特定函数中,您可以观察以下代码:

$new['where'] = array_merge(array_get($old, 'where', []), array_get($new, 'where', []));
在这里,我们可以看到他们只是使用一个堆栈来跟踪这些值,所以
{domain}.{tld}
的文本解释被推到堆栈上

这在一开始运行良好,因为我的过滤器实际上会显式地捕获它们:

$domain = $route->getParameter('domain').'.'.$route->getParameter('tld');
为了解决这个问题,我只需要创建我自己的helper函数来获取$host(这是一个非常基本的实现,但为了清晰起见应该会有所帮助)

然后在我的helpers文件中,我添加了
get\u 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();

这现在可以很好地工作。

您可以尝试在您的应用程序中使用
'domain'=>'{domain}.{tld}.example.com'
$domain=$route->getParameter('domain')。$route->getParameter('tld')。example.com'
code@ChetanAmeta可以我试一试。结果是没有找到帐户条目,因为域在数据库中不匹配,所以我转到了Saas服务的页面,而不是客户端的页面。好的,只有更改应用程序域才有效,
Config::set('app.domain',$domain'.example.com')离开
$domain=$route->getParameter('domain')。$route->getParameter('tld')按原样was@ChetanAmeta不幸的是,它没有起作用。我感谢你的努力。
Route::filter('database.setup', function($route, $request){
$domain = get_domain();