globalfunctions.phpに関する考察
2007年12月17日
某掲示板でも指摘されていた、globalfunctions.phpについて。この記事の最後に、globalfunctions.phpの概要をまとめてみた。それを参考に話を進めたい。まず始めに確認しておきたいのは、globalfunctions.phpはconfig.phpから呼び出されるため、Nucleusの何かしらの機能を使おうとすると必ずパースされることである。ここにある無駄は、Nucleusの機能全体に影響を及ぼす。
第一の無駄は、このphpファイルが2000行と、かなり長いこと。使わないかもしれない関数、例えば selector() などのパースが行われている。この関数はスキンをパースするときには必要だが、それ以外のとき、例えば管理画面などではこれは不必要で、不必要な関数のパースのためにサーバのリソースが消費されている。無論この無駄は、eAccelarator などのJITをキャッシュするような仕組みを導入すると、かなり軽減される。
第二の無駄は、使わないかもしれないクラスのパースが必ず行われること。これには、ACTIONLOG, PARSER, SKIN, BLOG, BODYACTIONS, COMMENTS, BAN, PAGEFACTORY, SEARCH, entity といった、半端でない数のクラスが含まれ、それらのパースに費やされるサーバのリソースも半端ではないはず。繰り返しになるが、この無駄も、eAccelaratorr などで、かなり軽減される。
第三の無駄は、グローバル変数を使いすぎていること。これは、無駄なコードの実行というだけではなく、SQL インジェクション・XSS・リモートスクリプトインジェクションなどの脆弱性にも絡んでくる問題である。
必要最小限のglobalfunctions.phpの機能を考えてみると、次のようになるかもしれない。
・$manager 初期化
・MySQLへの接続
次に、比較的必要であろうと思われる機能は次のとおり
・ログイン・ログアウト機能
・グローバル関数の関数名の登録(コードのパースはしない)
ログイン機能が必要かどうかは、ユーザからのパラメータを見れば判断できるので、必要最小限の機能には含めない。グローバル関数の関数名の登録については、現状のNucleusでは必須であろう。ただ、それらの関数が呼び出されたときに外部ファイルをインクルードして実行するなどの方法で、コードのパースを後回しにすることは出来るはず。ここで問題にしている無駄については、PHP5の__autoload()関数を用いればかなり軽減されるはずだから、今後の仕様に期待するところである。
最後に、これからのNucleusに私が期待するところであるが…。つい先日、3.32の仕様のロードマップが発表された。このページや、Nucleus 5 の仕様の予定などを見ていると、『Nucleusよ、お前もか』と感じる部分が多々ある。私はNucleusの現状の機能に満足していて、これ以上の機能のプラスアルファは必要としていないのであるが(セキュリティーの向上は必要)、今後の予定ではコアへの新しい機能の追加が盛りだくさん。例えば、記事のオートドラフトセーブは使ったことは無いが、3.3ではコアに入ってしまっている。これはプラグインに任せれば良いのではないかと思っている機能の一つ。そんな風に、Nucleusコアがどんどん肥大化していくと、このツールの良さがどんどん失われていってしまうのではないかと感じてしまう。逆に、コアの機能をもっと少なくし、スキンパースのためのコードや、管理画面さえもプラグインにしてしまったらどうだろうかと考える、今日この頃である。
(参考データ:globalfunctions.php の概要)
globalfunctions.php 約2000行
$CONF グローバル変数の設定
sanitizeParams();
$blogid 等のグローバル変数の設定
インクルード
include($DIR_LIBS . 'mysql.php');
include($DIR_LIBS . 'MEMBER.php');
include($DIR_LIBS . 'ACTIONLOG.php');
include($DIR_LIBS . 'MANAGER.php');
include($DIR_LIBS . 'PLUGIN.php');
$manager 初期化
管理画面のとき、インクルード
include($DIR_LIBS . 'xmlrpc.inc.php'); // XML-RPC client classes
include_once($DIR_LIBS . 'ADMIN.php');
MySQL に接続
MySQL から、$CONF 値を取得
$member 初期化
secureCookieKey 設定
ログイン・ログアウト設定
ticketForPlugin();
インクルード
include($DIR_LIBS . 'PARSER.php');
include($DIR_LIBS . 'SKIN.php');
include($DIR_LIBS . 'TEMPLATE.php');
include($DIR_LIBS . 'BLOG.php');
include($DIR_LIBS . 'BODYACTIONS.php');
include($DIR_LIBS . 'COMMENTS.php');
include($DIR_LIBS . 'COMMENT.php');
include($DIR_LIBS . 'NOTIFICATION.php');
include($DIR_LIBS . 'BAN.php');
include($DIR_LIBS . 'PAGEFACTORY.php');
include($DIR_LIBS . 'SEARCH.php');
include($DIR_LIBS . 'entity.php');
言語ファイル初期化
decode path_info
グローバル関数郡の登録(これは、実際にはパース時、つまり一番初めに行われる)
第一の無駄は、このphpファイルが2000行と、かなり長いこと。使わないかもしれない関数、例えば selector() などのパースが行われている。この関数はスキンをパースするときには必要だが、それ以外のとき、例えば管理画面などではこれは不必要で、不必要な関数のパースのためにサーバのリソースが消費されている。無論この無駄は、eAccelarator などのJITをキャッシュするような仕組みを導入すると、かなり軽減される。
第二の無駄は、使わないかもしれないクラスのパースが必ず行われること。これには、ACTIONLOG, PARSER, SKIN, BLOG, BODYACTIONS, COMMENTS, BAN, PAGEFACTORY, SEARCH, entity といった、半端でない数のクラスが含まれ、それらのパースに費やされるサーバのリソースも半端ではないはず。繰り返しになるが、この無駄も、eAccelaratorr などで、かなり軽減される。
第三の無駄は、グローバル変数を使いすぎていること。これは、無駄なコードの実行というだけではなく、SQL インジェクション・XSS・リモートスクリプトインジェクションなどの脆弱性にも絡んでくる問題である。
必要最小限のglobalfunctions.phpの機能を考えてみると、次のようになるかもしれない。
・$manager 初期化
・MySQLへの接続
次に、比較的必要であろうと思われる機能は次のとおり
・ログイン・ログアウト機能
・グローバル関数の関数名の登録(コードのパースはしない)
ログイン機能が必要かどうかは、ユーザからのパラメータを見れば判断できるので、必要最小限の機能には含めない。グローバル関数の関数名の登録については、現状のNucleusでは必須であろう。ただ、それらの関数が呼び出されたときに外部ファイルをインクルードして実行するなどの方法で、コードのパースを後回しにすることは出来るはず。ここで問題にしている無駄については、PHP5の__autoload()関数を用いればかなり軽減されるはずだから、今後の仕様に期待するところである。
最後に、これからのNucleusに私が期待するところであるが…。つい先日、3.32の仕様のロードマップが発表された。このページや、Nucleus 5 の仕様の予定などを見ていると、『Nucleusよ、お前もか』と感じる部分が多々ある。私はNucleusの現状の機能に満足していて、これ以上の機能のプラスアルファは必要としていないのであるが(セキュリティーの向上は必要)、今後の予定ではコアへの新しい機能の追加が盛りだくさん。例えば、記事のオートドラフトセーブは使ったことは無いが、3.3ではコアに入ってしまっている。これはプラグインに任せれば良いのではないかと思っている機能の一つ。そんな風に、Nucleusコアがどんどん肥大化していくと、このツールの良さがどんどん失われていってしまうのではないかと感じてしまう。逆に、コアの機能をもっと少なくし、スキンパースのためのコードや、管理画面さえもプラグインにしてしまったらどうだろうかと考える、今日この頃である。
(参考データ:globalfunctions.php の概要)
globalfunctions.php 約2000行
$CONF グローバル変数の設定
sanitizeParams();
$blogid 等のグローバル変数の設定
インクルード
include($DIR_LIBS . 'mysql.php');
include($DIR_LIBS . 'MEMBER.php');
include($DIR_LIBS . 'ACTIONLOG.php');
include($DIR_LIBS . 'MANAGER.php');
include($DIR_LIBS . 'PLUGIN.php');
$manager 初期化
管理画面のとき、インクルード
include($DIR_LIBS . 'xmlrpc.inc.php'); // XML-RPC client classes
include_once($DIR_LIBS . 'ADMIN.php');
MySQL に接続
MySQL から、$CONF 値を取得
$member 初期化
secureCookieKey 設定
ログイン・ログアウト設定
ticketForPlugin();
インクルード
include($DIR_LIBS . 'PARSER.php');
include($DIR_LIBS . 'SKIN.php');
include($DIR_LIBS . 'TEMPLATE.php');
include($DIR_LIBS . 'BLOG.php');
include($DIR_LIBS . 'BODYACTIONS.php');
include($DIR_LIBS . 'COMMENTS.php');
include($DIR_LIBS . 'COMMENT.php');
include($DIR_LIBS . 'NOTIFICATION.php');
include($DIR_LIBS . 'BAN.php');
include($DIR_LIBS . 'PAGEFACTORY.php');
include($DIR_LIBS . 'SEARCH.php');
include($DIR_LIBS . 'entity.php');
言語ファイル初期化
decode path_info
グローバル関数郡の登録(これは、実際にはパース時、つまり一番初めに行われる)
コメント
yu (2007年12月21日 23:01:18)
なるほど、globalfunctions自体がもっとコンパクトになるとスマートですね。
Nucleusのロードマップの話。
skinable admin areaの考え方は、「管理画面さえもプラグインに」と近いですよね。僕が今後のNucleusに期待してるものの1つはそこなんですが、あんまり開発が進んでないみたいな・・
Nucleusのロードマップの話。
skinable admin areaの考え方は、「管理画面さえもプラグインに」と近いですよね。僕が今後のNucleusに期待してるものの1つはそこなんですが、あんまり開発が進んでないみたいな・・
Kat (2007年12月22日 12:53:08)
>あんまり開発が進んでないみたいな
ですねぇ。一度できてしまったものを、互換性を保ちながら新しくするのは、並大抵のことでは無いということかもしれません。
簡単なコードを書きながら思考実験すると、コアの機能としては action, skinver, templatevar, event の管理だけで良さそうです。コアの殆どのクラスをプラグインのように扱い、管理画面そのものもスキンで記述して、それぞれのアクションもプラグイン化されたクラスで扱う様にすると、すっきりし、かつカスタマイズも容易になると思っています。
ですねぇ。一度できてしまったものを、互換性を保ちながら新しくするのは、並大抵のことでは無いということかもしれません。
簡単なコードを書きながら思考実験すると、コアの機能としては action, skinver, templatevar, event の管理だけで良さそうです。コアの殆どのクラスをプラグインのように扱い、管理画面そのものもスキンで記述して、それぞれのアクションもプラグイン化されたクラスで扱う様にすると、すっきりし、かつカスタマイズも容易になると思っています。
yu (2007年12月23日 22:40:12)
>コアの殆どのクラスをプラグインのように扱い、管理画面そのものもスキンで記述して、それぞれのアクションもプラグイン化されたクラスで扱う様にする
ほんと、このレベルまで行ってくれればNucleusらしさ全開ってかんじで素敵なんですが。
ほんと、このレベルまで行ってくれればNucleusらしさ全開ってかんじで素敵なんですが。
Kat (2007年12月24日 11:58:42)
一つは、PHP5の__autoload()関数の活用でしょうね。globalfunctions.phpで一気にクラスのパースを行っていますが、これを全部省略することが出来ます。あと、selector()などの長いコードを持つグローバル関数に関しては、関数の定義だけしておいて、そのままSKIN::selector()メソッドか何かに転送するようにしておけば、ずいぶん軽くなると思います。
本家は、来年の8月になるまで、PHP5への完全移行はしないようです。私は年明けに完全移行しても良いと思うのですが…。
本家は、来年の8月になるまで、PHP5への完全移行はしないようです。私は年明けに完全移行しても良いと思うのですが…。
yama (2008年2月19日 08:19:06)
> 管理画面そのものもスキンで記述
実際にモックを作ったことがありますが、管理画面を構成するスキン変数をいくつか提供するプラグインがあれば、本当に作れると思いましたよ。実際にはスペシャルスキンパーツの仕様をもう少し柔軟にするとか、コア側の対応も多少は必要になりそうですが。
管理画面をNucleusそのもので作れたら、フレームワーク感覚で面白いものが作れそうです。
実際にモックを作ったことがありますが、管理画面を構成するスキン変数をいくつか提供するプラグインがあれば、本当に作れると思いましたよ。実際にはスペシャルスキンパーツの仕様をもう少し柔軟にするとか、コア側の対応も多少は必要になりそうですが。
管理画面をNucleusそのもので作れたら、フレームワーク感覚で面白いものが作れそうです。
Kat (2008年2月19日 14:41:11)
そのあたりは、開発中のJeansで実装予定です。管理画面のカスタマイズは、Jeansだとずいぶん楽になるのではと思っています。管理機能をカスタマイズした派生バージョンなども、作りやすくなるはずです。