Codeigniter 裡面有一個功能叫 drivers,但官方的文件著墨很少,網路上討論的文章也不算多,但我覺得以一個不是使用 namespace 那麼方便做 DI 以及調用資源的 framework 來說,這個功能還頗好應用的,一般人使用 CI 都會用他的 library 功能,把自己的 class 放在這邊調用,但大部分就是一層式的沒有階級觀念,就不用提 interface 了,dirvers 可以靈活的做到調用,先來講怎麼設定 driver 環境,以各家第三方登入為例。
首先我們先建立目錄
Auth
Auth/Auth.php
Auth/drivers
Auth/drivers/Auth_facebook.php
Auth/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
的全貌,怎麼變化應用讓功能更有彈性就要視不同的情況去配置了。
沒有留言:
張貼留言