CodeIgniterを利用したWebサイトで、当惑するような問題が発生しました。1つのPHPクラス(TChild)は、断続的に「クラスを再宣言できません」エラーをスローし始め、それを使用するすべてのページを壊します。宣言するコードが一度だけ実行されるようにするために私が行った長さは、率直に言ってばかげていますが、役に立ちません。tchild.phpの上部は現在次のようになっています。
(!( isset( $GLOBALS['tchild_counter'] ) ))
? $GLOBALS['tchild_counter'] = 1
: $GLOBALS['tchild_counter']++ ;
log_message("info", "tchild has been included " . $GLOBALS['tchild_counter'] . " times");
if($GLOBALS['tchild_counter'] != 1) {
log_message("info", "STOP RUNNING TWICE");
} else {
if ( ! defined('BASEPATH')) {
log_message("error", "BASEPATH not set; no direct script access allowed");
exit('No direct script access allowed');
}
log_message("info", "Basepath is fine, checking if tchild exists (proc".getmypid().")");
log_message("info", "why does that last line seem to run twice?");
if ( ! class_exists('TChild')) {
log_message("info", "TChild does not exist, creating it");
if(class_exists('tchild')) {
log_message("info", "tchild apparently exists?");
} else {
log_message("info","okay, I'm extra-sure that tchild doesn't exist");
}
class TChild extends ActiveRecord\Model {
それは...何かの巨大な山ですが、少なくともTChildが一度だけ定義されることを保証する必要がありますよね?うーん、ダメ。ほとんどの場合、正常に動作しますが、サーバーが奇妙な状態になり、それとは反対のすべての証拠があるにもかかわらず、TChildが2回宣言されていると判断する場合があります。私が追加した広範なロギングステートメントから、tchild.phpは最初に単一のrequire_onceにのみ含まれ、クラス定義に2回以上到達することはないと確信しています。(ただし、正常に実行されている場合でも、2つの「STOPRUNNING TWICE」ログエントリが出力されます。理由はわかりませんが、少なくとも何も壊れません。)
失敗し始めると、(通常は)数分間すべてを壊し続け、その後、最初の失敗と同じくらい不思議な理由で自分自身を修正します。
ここで何が起こっているのかわかりません。グーグルで調べてみると、php.iniにapc.enabled = 0を追加しようとしましたが、クラッシュやパフォーマンスに違いはありませんでした。(そもそも有効になっているとは思いませんが、一見の価値があります。)
アップデート:
ああ、ファイルを複数回インクルードしているサードパーティのライブラリにrequireステートメントがありました。宣言をラップしたすべてのif/elseブロックにもかかわらず、クラスが再宣言された理由はまだわかりませんが、少なくとも現在は機能しているようです。