Idea2
クラス変数版
| Table of Contents |
クラス化
global 変数や定数の代わりをクラス変数で行います。 PHP4 ではクラス変数が使用できませんが、 クラス変数の「ようなもの」を定義するテクニックを使用で回避します。
概略
class PluginXxx {
static $... /* define()していた設定用定数やグローバル変数など */
var $... /* インスタンス変数 */
function PluginXxx() { /* インスタンスの初期化 */ }
function action() { /* plugin_xxx_action() */ }
function convert() { /* plugin_xxx_convert() */ }
function inline() { /* plugin_xxx_inline() */ }
ただし、PHP4 ではこのように static を使用できないので、クラス変数の「ようなもの」を定義するテクニックを使用する。
詳細
<?php class PluginXxx { /* define()していた設定用定数やグローバル変数など */ var $conf; /* メンバ変数 */ var $var; function PluginXxx() { // define()していた設定用定数やグローバル変数など // PHP4 でクラス変数の「ようなもの」を定義するテクニックを使用する。 static $conf = array( ); $this->conf = & $conf; // インスタンスの初期化。そもそもメンバ変数を作る必要がない場合も多い。 $this->var = ...; } function convert() { // function_xxx_convert() } function inline() { // function_xxx_inline() } function action() { // function_xxx_action() } } function plugin_xxx_convert() { $plugin_xxx = new PluginXxx(); $args = func_get_args(); return call_user_func_array(array(&$plugin_xxx, 'convert'), $args); } function plugin_xxx_inline() { $plugin_xxx = new PluginXxx(); $args = func_get_args(); return call_user_func_array(array(&$plugin_xxx, 'inline'), $args); } function plugin_xxx_action() { $plugin_xxx = new PluginXxx(); return $plugin_xxx->action(); } ?>
ユーザ設定(Plus!)
Pukiwiki Plus! にあるユーザ設定機能をどのように使うか。プラグインファイルが読み込まれる前に読み込まれます。
init/xxx.ini.php では以下のように初期設定を行えます。
<?php exist_plugin('xxx'); // require_once $plugin_xxx = new PluginXxx(); $plugin_xxx->conf['key'] = ....; ?>
しかし、このままでは (似非)シングルトン版 ではできた、関数のオーバーライドができないので劣っている気がします。そこで plugin_xxx_init 関数に工夫をし、プラグイン関数を次のように実行します。
function plugin_xxx_init() { global $plugin_xxx_class; if (class_exists('PluginXxxUser')) { $plugin_xxx_class = 'PluginXxxUser'; } else { $plugin_xxx_class = 'PluginXxx'; } } function plugin_xxx_convert() { global $plugin_xxx_class; $plugin_xxx = new $plugin_xxx_class(); $args = func_get_args(); return call_user_func_array(array(&$plugin_xxx, 'convert'), $args); }
init/xxx.ini.php では以下のように関数のオーバーライドができるようになります。 PluginXxxUser のように、対策された名前限定になりますが、大した問題ではないでしょう。
<?php exist_plugin('xxx'); // require_once class PluginXxxUser extends PluginXxx { function PluginXxxUser() { parent::PluginXxx(); $this->conf = '.....'; } } ?>
ちなみにPukiWiki 本家のほうでもこの機能に対応するには、プラグインファイルの先頭に
if (! defined('INIT_DIR')) // if not Plus! if (file_exists(DATA_HOME . 'init/xxx.ini.php')) include_once(DATA_HOME . 'init/xxx.ini.php');
を追加しておけば可能です。
UnitTest について考える
UnitTestForPlugins 参照。
UnitTest を行う場合は、関数実行後や、プラグイン実行後のインスタンス変数の値を参照したいものです。 なのでインスタンスをグローバル変数として定義してしておきます。
function plugin_xxx_convert() { global $plugin_xxx; $plugin_xxx = new PluginXxx(); $args = func_get_args(); return call_user_func_array(array(&$plugin_xxx, 'convert'), $args); }
また、UnitTest 用ユーザ定義をしたい場合も考えられるので、
function plugin_xxx_init() { global $plugin_xxx_class; if (class_exists('PluginXxxUnitTest')) { $plugin_xxx_class = 'PluginXxxUnitTest'; } elseif (class_exists('PluginXxxUser')) { $plugin_xxx_class = 'PluginXxxUser'; } else { $plugin_xxx_class = 'PluginXxx'; } }
と用意しておくことにします。
まとめ
統合してみると次のようなコードになります。
<?php if (! defined('INIT_DIR')) // if not Plus! if (file_exists(DATA_HOME . 'init/xxx.ini.php')) include_once(DATA_HOME . 'init/xxx.ini.php'); class PluginXxx { /* define()していた設定用定数やグローバル変数など */ var $conf; /* インスタンス変数 */ var $var; function PluginXxx() { // define()していた設定用定数やグローバル変数など // PHP4 でクラス変数の「ようなもの」を定義するテクニックを使用する。 static $conf = array( // .... ); /* static 宣言で直接代入できない場合 (関数を呼ぶ必要があるなど) は、 static $conf = array(); if (empty($conf)) { $conf = array( // .... );} と書くと良いかもしれない。*/ $this->conf = & $conf; // インスタンスの初期化 $this->var = ...; } function convert() { // function_xxx_convert() } function inline() { // function_xxx_inline() } function action() { // function_xxx_action() } } function plugin_xxx_init() { global $plugin_xxx_class; if (class_exists('PluginXxxUnitTest')) { $plugin_xxx_class = 'PluginXxxUnitTest'; } elseif (class_exists('PluginXxxUser')) { $plugin_xxx_class = 'PluginXxxUser'; } else { $plugin_xxx_class = 'PluginXxx'; } } function plugin_xxx_convert() { global $plugin_xx, $plugin_xxx_class; $plugin_xxx = new $plugin_xxx_class(); $args = func_get_args(); return call_user_func_array(array(&$plugin_xxx, 'convert'), $args); } function plugin_xxx_inline() { global $plugin_xx, $plugin_xxx_class; $plugin_xxx = new $plugin_xxx_class(); $args = func_get_args(); return call_user_func_array(array(&$plugin_xxx, 'inline'), $args); } function plugin_xxx_action() { global $plugin_xx, $plugin_xxx_class; $plugin_xxx = new $plugin_xxx_class(); $args = func_get_args(); return $plugin_xxx->action(); } ?>


