2012年08月26日

【PHP/Smarty】Fatal error: Class 'Smarty_Internal_TemplateCompilerBase' not found in /usr/local/apache/www/htdocs/prestadev.pl/tools/smarty/sysplugins/smarty_internal_smartytemplatecompiler.php on line 127

PHPベースでちょこっとフレームワークを自作してたら、
下記のようなエラーが出てきて、半日開発が止まりました。
Fatal error: Class 'Smarty_Internal_TemplateCompilerBase' not found in /usr/local/apache/www/htdocs/prestadev.pl/tools/smarty/sysplugins/smarty_internal_smartytemplatecompiler.php on line 127


というか英語サイトとかばっかり出てくるのに、
これだ!という解決作がどうしても見つけられなかった訳なんですよ。

で、細かくいろんな条件を変えたりして、時にはSmartyのキャッシュに惑わされたりして、
私の環境ではある特定条件下で発生する事が発覚しました。

【条件と回避方法】
1.Smartyのバージョンが3.xである事
 Smartyのバージョンを2.xにダウンさせる事で、このエラーは出なくなります。
 バージョンダウンして問題無いのであれば、こちらをおすすめします。
 多少の性能ダウンは起こるかもしれませんが、
 このバグを回避する手間暇を考えると、おそらくすごく楽です。

2.__autoloadを使っている
 index.phpからClassLoader機能を持つファイルをインクルードして、
 Smartyをインクルードするような処理が部分的にありました。
 ちなみにSmartyをインクルードする部分だけをautoloadを一切返さずに読み込む事で、
 なぜか回避する事が出来ます。

 私のソースコードでは、
 Smartyを継承しているクラス(SmartyControl)をautoloadで読み込み、
 SmartyControl.phpの先頭でダイレクトにSmarty.classを読み込むソースです。
 このソースコードにて、
 SmartyControlをautoloadを使わずにダイレクトインクルードする事で
 なぜかこのバグは発生しなくなりました。

 見た感じ、autoloadでクラスを読んだ場合に、
 さらにその中でincludeが発生すると、
 普通にincludeを読み込むのとは少し違う動作をしているっぽいのですが、
 残念ながら具体的に何が原因でバグになっているのかは分かりませんでした。

【結論】
Smarty2.xに置き換えるか、
Smarty周りのインクルードを単純なインクルードに差し替えてしまえば、
高い確率で回避する事が出来る。
これ以上調べるのは骨が折れるので、手を出したくない。
この記事へのコメント
今更ここを読まれているかは不明ですが。

私も同様の現象になりました。
おそらくですが、おっしゃるとおり、
autoloadを独自に定義されていることが原因で、
先に独自autoloadが定義されているため、
smartyのautoloadが機能しなかったのでは、と。

また、独自autoloadの中で例外throwしていた場合などは、
そこで止まってしまいますし…。

回避策としては、
1) spl_autoload_register()を使って独自autoload処理を登録。そして、独自autoload関数を登録する処理の前にSmarty.classをベタでインクルードする。
(こうすればSmartyのautoloaderが先に実行されます)

2) spl_autoload_register()を使って独自autoload登録。かつ、独自autoload関数内で例外をthrowしない。

という感じでしょうか。
Posted by t_______h at 2013年04月20日 02:46
コメントを書く
お名前: [必須入力]

メールアドレス:

ホームページアドレス:

コメント: [必須入力]


この記事へのトラックバック
×

この広告は1年以上新しい記事の投稿がないブログに表示されております。