Codeigniter 裡面有一個功能叫 drivers,但官方的文件著墨很少,網路上討論的文章也不算多,但我覺得以一個不是使用 namespace 那麼方便做 DI 以及調用資源的 framework 來說,這個功能還頗好應用的,一般人使用 CI 都會用他的 library 功能,把自己的 class 放在這邊調用,但大部分就是一層式的沒有階級觀念,就不用提 interface 了,dirvers 可以靈活的做到調用,先來講怎麼設定 driver 環境,以各家第三方登入為例。
首先我們先建立目錄

AuthAuth/Auth.phpAuth/driversAuth/drivers/Auth_facebook.phpAuth/drivers/Auth_google.php
命名規則就是檔名必須跟目錄名稱相同,第一個字首要大寫(包含初始的目錄),只要任何一個名稱取錯都不會動,我試過了。
Auth.php
class Auth extends CI_Driver_Library
{
protected $valid_drivers;
public function __construct()
{
$this->valid_drivers = array('facebook', 'google');
}
public function login()
{
echo 'login from auth driver'.PHP_EOL;
}
}
$valid_drivers 是必要參數,他表示允許調用的 dirver 名稱,呼叫的時候不需要帶 parent name,這樣寫起來也比較清爽。
Auth_facebook.php
class Auth_facebook extends CI_Driver
{
public function login()
{
echo 'login from auth facebook'.PHP_EOL;
}
}
基本上被調用的 driver 子項目很簡單,繼承 CI_Driver 就可以了,我們接著建立一個叫 Login 的 controller。
application/controllers/Login.php
class Login extends CI_Controller
{
public function index()
{
$this->load->driver('auth');
$this->auth->login();
$this->auth->facebook->login();
}
}
在 command line 執行 php index.php login index 會得到
login from auth driver login from auth facebook
寫到這就知道前面部屬好的話,之後要調用各家的 login 只要在 Auth/drivers 下增加,並且加入 $valid_drivers 設定即可,根據 SOLID 原則,會變動的 config 內容不應該存在在 class 裡面,所以我們在 config 增加一個 auth.php
application/config/auth.php
$config['valid_drivers'] = array('facebook', 'google');
然後將 Auth.php 改寫如下。
class Auth extends CI_Driver_Library
{
protected $valid_drivers;
protected $ci;
public function __construct()
{
$this->ci =& get_instance();
$this->ci->config->load('auth', true);
$this->valid_drivers = $this->ci->config->item('valid_drivers', 'auth');
}
public function login()
{
echo 'login from auth driver'.PHP_EOL;
}
}
這樣的話之後要加內容只要改 config 就好,但這樣的彈性還不是最好的,我們應該要讓 Login controller 可以接受變數選擇調用哪個登入才對,來對他動一點手腳。
class Login extends CI_Controller
{
public function index($method = null)
{
$this->load->driver('auth');
$this->auth->login();
$this->auth->{$method}->login();
}
}
然後執行 php index.php login index facebook,這樣會得到跟上面一樣的結果,但我們應該更嚴謹一點,檢查該 method 是否存在,在來強化一下。
class Login extends CI_Controller
{
public function index($method = null)
{
$this->config->load('auth', true);
if (!in_array($method, $this->config->item('valid_drivers', 'auth'))) {
die('method not exists');
}
$this->load->driver('auth');
$this->auth->login();
$this->auth->{$method}->login();
}
}
如果亂執行一通 php index.php login index twitter,會得到 method not exists,這大致上是 drivers 的全貌,怎麼變化應用讓功能更有彈性就要視不同的情況去配置了。
沒有留言:
張貼留言