MODx 0.9.7でのスニペットの処理方法

MODxのスニペットの実行速度が遅い原因を調べていた際に、MODx 0.9.7でのスニペットの処理方法についても調べたので書いておきます(結果としてはMODxが原因ではありませんでした)。

きっかけは、あるWeb APIからXMLを取得・処理するために作っていたスニペットです。これがものすごく遅かったんです。結果が返ってくるまで10~20秒ほど… :(

MODxのスニペットやプラグインはeval()で実行されますが、PHPのeval()はかなり遅いらしいです。使っているWeb API自体が重いわけでもないので、最初はこのeval()が原因だと思っていました。

MODx 0.9.7では、「オープンソースCMS、MODx 0.9.7のalpha版がリリース」でも書いたように、スニペット等の実行にeval()が使われなくなります。eval()が原因だとすれば、0.9.7の真似をすれば良いということで調べました。

MODx 0.9.6のDocumentParser APIにあるスニペットを実行するためのrunSnippet()メソッドからたどっていきました。MODx 0.9.7でDocumentParser APIにあたるものは/core/model/modx/modx.class.phpにあります。PDOというのがよくわかっていないのであれなんですが、取得したmodSnippetオブジェクトのメソッドを通してスニペットを実行しているようです。

modSnippetクラスは、xPDOObject → modAccessibleObject → modAccessibleSimpleObject → modElement → modScript → modSnippetのように継承しています。スニペットなどのスクリプトを処理するのはmodScript->process()です(modElement->process()をオーバーライド)。ちなみに、プラグイン・モジュールなどもmodScriptクラスの派生クラスです。テンプレート・テンプレート変数・チャンクなどはmodElementクラスの派生クラスです。

modScript->process()を見ると、スニペットなどのスクリプトのキャッシュファイル名を取得するためのgetScriptFileName()が呼び出したりしています。ここからたどっていくと(いかなくてもわかりやすいディレクトリ名ですが)、スニペットのキャッシュファイルのありかがわかります。スニペットを一度でも実行すると、/core/cache/web/elements/modSnippet/に次のようなキャッシュファイルができます(webの部分がコンテキストというやつになるみたいです)。

1.cache.php
<?php 
function web_elements_modSnippet_1($scriptProperties= array()) {
global $modx;
if (is_array($scriptProperties)) {
extract($scriptProperties, EXTR_SKIP);
}
return 'test';
}

ただの関数ですね。0.9.7では、スニペットを関数宣言化したPHPファイルをキャッシュとして保存しています。そして、このキャッシュファイルの関数をオブジェクトのメソッドとして読み込んで(?)実行するようです。

素人にはきついのでここで力尽きましたが、MODx 0.9.7では、こんな感じでeval()しなくてもスクリプトを実行できるようになっているみたいです。それを知っても、到底、真似できるものではなく、この後、素のPHPスクリプトで試した結果、実行速度が遅いのはMODxが原因ではないということに気付くわけですが…(おまけに、サーバが悪いのか何なのかは未だわからず…)。

それにしても、0.9.7は内部的には全く変わってしまってますね。プログラマな人なら、クラスを拡張して、簡単に大幅な機能拡張もできそうなことはわかりました。一番、使いそうなAPIに関しては、modx.class.phpを見ると0.9.6との互換性は高いみたいなので、その点の心配はいらなかったみたいです。

コメント (0)

この記事へのコメントはまだありません。

コメントフォーム

トラックバック (0)

この記事へのトラックバックはまだありません。

この記事のトラックバックURI
http://dxd8.com/archives/117/trackback/
この記事のURI
http://dxd8.com/archives/117/