【PHP】CodeIgniter3の知られざる機能【CodeIgniter3】

CodeIgniterの知られざる機能

この記事は、CodeIgniterAdventCalendar 2016 14日目の記事です。

qiita.com






こんばんは

マークアップエンジニアの です。

CodeIgniter4のリリースまであと4ヶ月ほどですね。

そんなCodeIgniter4の話題とは違いCodeIgniter3.1.xの現時点でドキュメンテーションされていない機能のご紹介記事です。

この記事では下記5機能のリファレンスと使用方法をご紹介します。

  • CI_DB_oci8_driver::stored_procedure
  • CI_Utf8::convert_to_utf8
  • CI_Config::site_url
  • CI_Utf8::is_ascii
  • CI_Hook::call_hook

CI_DB_oci8_driver::stored_procedure

oci8ドライバを使っているときはstored_procedureメソッドが使えます。
このメソッドはOracleに登録されているストアドプロシージャーを実行します。
平たく言えば「BEGIN PDB.STORED_PROCEDURE_NAME (数'...) END;」というクエリを発行してくれます。

リファレンス

stored_procedure($package, $procedure, $params)

Parameters:

  • $package (string) – PackageName
  • $procedure (string) - ProcedureName
  • $params (array) - ProcedureArguments

Returns: \CI_DB_result instance (method chaining)
Return type: \CI_DB_result

使い方
<?php
Hoge_model extends CI_Model {

    public function get_hoge_object()
    {
        $this->load->library('Hoge_object');
        // 第三引数にはname,value,type,lengthのキーを渡す。(省略可能)
        $result = $this->db->stored_procedure('TEST', 'FUNC', [
            [
                 'name' => 'HOGE', 
                 'value'  => 'hogehoge', 
                 'type'    => SQLT_CHR, 
                 'length' => 8
            ],
            [
                 'name' => 'FUGA',
                 'value'  => 'fuga'
            ]
        ]);
        return ($result && $result->row_num() > 0) ? $result->row(0, 'Hoge_object') : null ;
    }
}

CI_Utf8::convert_to_utf8

文字コードUTF-8に変換したい時に便利です。
マルチバイト系の関数が無い時にはiconvでUTF-8に変換を試みるのでアプリケーションの
実行環境が統一されていない場合などは重宝するかもしれません。
ただし、どちらもサポートしていない環境ではFALSEを返すので注意が必要です。

リファレンス

convert_to_utf8($str, $encoding)

Parameters:

  • $str (string) – BeforeConvertString
  • $encoding (string) - Encoding

Returns: ConvertedString
Return type: mixed string|bool

使い方
<?php
Hoge_model extends CI_Model {

    public function get_hoge_utf_8()
    {
        $cp932_hoge_str = $this->load->view('cp932_template', ['hoge' => 'fuga'], TRUE);
        
        return $this->utf8->convert_to_utf8($shiftjis_hoge_str, 'CP932');
    }
}

CI_Config::site_url

殆どの機能はドキュメンテーションされているので説明不要なurl_helperの関数
但し、実体はConfigクラスにあるので注意が必要です。

Configクラスの実装を見てみると第二引数がかなり便利になっているのにその機能がドキュメンテーションされていないのでご紹介
ドキュメントでは第二引数にプロトコルが指定できる様になっているのですがこのプロトコルに空文字を指定すると
「//hoge.example.com
この様なURIスキーマを省略してくれるので非常に便利になっています。
base_urlも同様の挙動をします。

リファレンス

site_url($uri, $protocol = NULL)

Parameters:

  • $uri (string) – BeforeConvertString
  • $protocol (string) - Protocol, e.g. ‘http’ or ‘https

Returns: Site URL
Return type: string

使い方
<!DOCTYPE html>
<html>
    <head>
        <title>Hoge</title>
        <!-- <script src="//hoge.example.com/hoge/hoge.js">が出力されます。 -->
        <script src="<?php echo base_url('hoge/hoge.js', '');?>">
    </head>
    <body>
       HelloWorld!!
    </bod>
</html>

sslでアクセスしてくるのかわからない時に有効です。

CI_Utf8::is_ascii

ASCII文字かどうかを判定してくれます。
また、CodeIgniterのInputクラスから値を取得するときはこのメソッドでチェックされているのであまり実用的ではないかもしれません。

リファレンス

is_ascii($str)

Parameters:

  • $str (string) – Check String

Returns: Is ascii
Return type: bool

使い方
<?php
class Hoge_model {

    public function validation_ascii(array $inputs)
    {
        $this->form_validation->reset_validation();
        $this->form_validation->set_data($inputs);
        $this->form_validation->set_rules('hoge',
            'ほげ',
            ['is_ascii' => $this->utf8->is_ascii],
            ['is_ascii' => '%s はASCII文字で許可されている文字を入力してください。']
        ]);
        return $this->form_validation->run();
    }

}

CI_Hooks::call_hook

Hookクラスに実装されています。
hookポイントの追加ができます。
CodeIgniterではデフォルトで7つのhookポイントがあります。

  • pre_system
  • pre_controller
  • post_controller_constructor
  • post_controller
  • display_override
  • cache_override
  • post_system

CodeIgniter4の Before Filterの様にRoutingが完了していてControllerがインスタンス化前などの欲しい場所にhookポイントが無いことがあります。

そのためコンストラクタが肥大化することはCodeIgniter3ではよく見る現象ですが
call_hookを使えばhookポイントを自由に追加することができますので、コンストラクタにhookポイントの追加をすれば、コンストラクタの肥大化を防ぐことができます。(あまり褒められた使い方ではないですが)

リファレンス

call_hook($which = '')

Parameters:

  • $which (string) – Hook point name

Returns: run hook status
Return type: bool

使い方

application/core/MY_Controller.php

<?php
abstract class MY_Controller extends CI_Controller {

    public function __construct()
    {
         parent::__construct();
         // Loaderクラス読み込み後のhookポイント追加
         $this->hook->call_hook('loading_controller_constructor');
    }

}

application/hooks/Auth.php

<?php
class Auth {

    public function is_login()
    {
        $ci =& get_instance();
        $ci->load->model('auth_model');
        if ( $ci->auth_model->is_loggedin() ) {
            return;
        }
        redirect('auth/login');
    }

}

application/config/hooks.php

<?php
// 追加したhook pointの名前
$hook['loading_controller_constructor'] = [
        'class'    => 'Auth',
        'function' => 'is_login',
        'filename' => 'Auth.php',
        'filepath' => 'hooks',
        'params'   => []
];

application/config/config.php

<?php
...
$config['enable_hooks'] = TRUE;

上記の様に記載するだけでControllerのインスタンス化中に認証を行うことができます。
これで、controllerのテストが書きやすくなりそうですね。

まとめ

  • CI_DB_oci8_driver::stored_procedure・・・Oracleのストアドプロシージャを呼び出すことができる
  • CI_Utf8::convert_to_utf8・・・UTF-8の文字列に変換してくれる
  • CI_Config::site_url・・・第2引数に空の文字列を入れることでURIスキーマを省略できる
  • CI_Utf8::is_ascii・・・ASCIIコードだけで構成された文字列かチェックしてくれる
  • CI_Hook::call_hook・・・hookポイントの追加を行うことができる


次回は@noldorinfoさんです。
お楽しみに。