Symfoware

Symfowareについての考察blog

CodeIgniter 3 自分で作成したモデルを継承する

CodeIgniter 3でCI_Modelを継承しモデルを定義。

・Base_model


  1. <?php
  2. // Base_modelを継承したモデル
  3. // Controllerからはこれを使用したい
  4. class Ext_model extends Base_model {
  5.     
  6.     public function say() {
  7.         echo 'Ext_model'.PHP_EOL;
  8.     }
  9.     
  10. }




このモデルを再度継承して拡張モデルを定義したい。

・Ext_model


  1. <?php
  2. // CI_Modelを継承したモデル
  3. // これを継承元としたい
  4. class Base_model extends CI_Model {
  5.     
  6.     public function say() {
  7.         echo 'Base_model'.PHP_EOL;
  8.     }
  9.     
  10. }




この状態で使用するとエラーになります。

・Test.php


  1. <?php
  2. class Test extends CI_Controller {
  3.     
  4.     // 作成した継承モデルの呼び出し
  5.     public function index() {
  6.         
  7.         $this->load->model('ext_model');
  8.         $this->ext_model->say();
  9.         
  10.     }
  11.     
  12. }





# php index.php test
PHP Fatal error: Class 'Base_model' not found in /var/dev/php/ci3/application/models/Ext_model.php on line 5

Fatal error: Class 'Base_model' not found in /var/dev/php/ci3/application/models/Ext_model.php on line 5

A PHP Error was encountered

Severity:    Error
Message:     Class 'Base_model' not found
Filename:    /var/dev/php/ci3/application/models/Ext_model.php
Line Number: 5

Backtrace:




まあ、Base_modelがロードされていないので当然なのですが。





解決策1



Base_modelがロードされていないことが原因なので、事前にロードしてやります。


  1. <?php
  2. class Test extends CI_Controller {
  3.     
  4.     // 作成した継承モデルの呼び出し
  5.     public function index() {
  6.         
  7.         // 事前にbase_modelをロード
  8.         $this->load->model('base_model');
  9.         $this->load->model('ext_model');
  10.         $this->ext_model->say();
  11.         
  12.     }
  13.     
  14. }




# php index.php test
Ext_model




動くには動きますし、modelのautoloadに指定してしまえば良いのですが、
あんまりしっくりきません。





解決策2



解決策1と似たような発想で、Ext_modelにBase_modelがロード済みか
チェックするロジックを入れてしまいます。

・Ext_model


  1. <?php
  2. // Base_modelを継承したモデル
  3. // Controllerからはこれを使用したい
  4. // 事前にBase_modelがロード済みかチェック
  5. if (!class_exists('Base_model')) {
  6.     // 未ロードならロード
  7.     get_instance()->load->model('base_model');
  8. }
  9. class Ext_model extends Base_model {
  10.     
  11.     public function say() {
  12.         echo 'Ext_model'.PHP_EOL;
  13.     }
  14.     
  15. }




これで呼び出せるようになりました。


  1. <?php
  2. class Test extends CI_Controller {
  3.     
  4.     // 作成した継承モデルの呼び出し
  5.     public function index() {
  6.         
  7.         $this->load->model('ext_model');
  8.         $this->ext_model->say();
  9.         
  10.     }
  11.     
  12. }




# php index.php test
Ext_model







解決策3



Hookとspl_autoload_registerの組み合わせを試してみます。

CodeIgniter 3 処理のフック(General Topics - Hooks - Extending the Framework Core)
PHP spl_autoload_registerでautoloadを自前で実装


※以下、例外処理のない適当な実装です。

まずHookを有効化。
application/config/config.phpのenable_hooksをtrueにします。


  1. /*
  2. |--------------------------------------------------------------------------
  3. | Enable/Disable System Hooks
  4. |--------------------------------------------------------------------------
  5. |
  6. | If you would like to use the 'hooks' feature you must enable it by
  7. | setting this variable to TRUE (boolean). See the user guide for details.
  8. |
  9. */
  10. $config['enable_hooks'] = TRUE;




application/config/hooks.phpを編集
pre_systemでspl_autoload_registerを登録します。


  1. <?php
  2. defined('BASEPATH') OR exit('No direct script access allowed');
  3. /*
  4. | -------------------------------------------------------------------------
  5. | Hooks
  6. | -------------------------------------------------------------------------
  7. | This file lets you define "hooks" to extend CI without hacking the core
  8. | files. Please see the user guide for info:
  9. |
  10. |    https://codeigniter.com/user_guide/general/hooks.html
  11. |
  12. */
  13. $hook['pre_system'][] = spl_autoload_register(function($className) {
  14.     // Base_modelの解決
  15.     get_instance()->load->model($className);
  16. });




これで動いてくれました。



わかりやすさから、解決策2のモデルクラスの先頭でチェックするのが良さそうでした。



関連記事

テーマ:プログラミング - ジャンル:コンピュータ

  1. 2017/02/14(火) 00:02:13|
  2. PHP
  3. | トラックバック:0
  4. | コメント:0
  5. | 編集