2016-11-11 74 views
1

我在database.php中如下配置:Laravel 4 equolent - 如何動態更改默認數據庫?

'connections' => array(

    'sqlite' => array(
     'driver' => 'sqlite', 
     'database' => __DIR__.'/../database/production.sqlite', 
     'prefix' => '', 
    ), 

    'mysql-primary' => array(
     'driver' => 'mysql', 
     'host'  => 'host1', 
     'port'  => '3306', 
     'database' => 'test', 
     'username' => 'root', 
     'password' => '', 
     'charset' => 'utf8', 
     'collation' => 'utf8_unicode_ci', 
     'prefix' => '', 
    ), 

    'mysql-slave' => array(
     'driver' => 'mysql', 
     'host'  => 'host2', 
     'port'  => '3306', 
     'database' => 'test', 
     'username' => 'root', 
     'password' => '', 
     'charset' => 'utf8', 
     'collation' => 'utf8_unicode_ci', 
     'prefix' => '', 
    ), 

    'default' => 'mysql-primary', 
) 

我想什麼來實現從主DB切換到從DB中不可用的情況下比方說,用戶嘗試登錄:

$user = User::where('username', '=', $username)->first(); 

我想在這裏,如果有PDOException(這是應該在不可用的情況下,拋出)切換默認數據庫並重試操作。我知道它可能在用戶模型中,但我想切換到所有模型。

我都沒有成功嘗試:

App::error(function(PDOException $exception) 
{ 
    Log::error("Error connecting to database: ".$exception->getMessage()); 
    DB::setDefaultConnection('mysql-slave'); 
}); 

在filters.php

'default' => getDatabase() 


function getDatabase() 
{ 
    try{ 
    DB::connection('mysql-master')->getDatabaseName(); 
    }catch(PDOException $e){ 
    return 'mysql-slave'; 
    } 
    return 'mysql-master'; 
} 

在database.php中

兩個不工作。 Laravel 4中有這種行爲嗎?

回答

1

簡短的回答是:你不能使用外牆(DB :: etc)來做到這一點。

爲什麼?外觀使用內部單例實例,該實例在第一次訪問外觀時被初始化。如果深入研究Laravel代碼,您會發現,在包括DB服務提供者的服務提供者的引導程序/註冊函數中,存在以單例創建的內部DB對象。該對象屬於Illuminate \ Database \ Connectors \ ConnectionFactory類,並具有一個預先初始化的內部PDO對象,該對象通過存儲在配置變量中的配置創建。

較長的答案是您可以使用類似於數據庫服務提供程序中的引導代碼的代碼創建一個或多個您自己的Illuminate \ Database \ Connectors \ ConnectionFactory類的對象。我建議您仔細閱讀引導程序代碼並熟悉它,並且可以在此處找到代碼和文檔:https://laravel.com/api/4.2/Illuminate/Database/DatabaseServiceProvider.html

可能還有其他解決方法,包括提供額外的Illuminate連接器\ Database \ Connection(所有這些都可以像配置一樣在配置中設置)連接到ConnectionFactory。這將涉及擴展現有的ConnectionFactory類,並將DB服務提供者更改爲使用您自己的擴展而不是Laravel本機類。然後,您可以讓ConnectionFactory提供一個內置故障轉移的連接。它相當複雜但可能 - 我已經爲ViewFactory類完成了它,但從未爲ConnectionFactory類完成過。

對不起,這不是一個簡單的HOWTO來回答你的問題,但它讓你知道爲什麼這不起作用,只是你給的例子。例如,使用MySQL代理或負載平衡服務可能比較簡單,例如,它可以自動檢測哪個服務器正在運行並向其發送請求。