我在我们的 CodeIgniter 支持的网站中遇到了一个令人困惑的问题。一个 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 被声明了两次。从我添加的大量日志语句来看,我相当肯定 tchild.php 一开始只包含在一个 require_once 中,而且它绝对不会多次到达类定义。(然而,它确实会吐出两个“停止运行两次”日志条目,即使事情运行良好。我不知道为什么,但至少这不会破坏任何东西。)
一旦它开始失败,它会继续破坏一切(通常)几分钟,然后以与最初失败一样神秘的原因自行修复。
我不知道这里发生了什么。谷歌搜索导致我尝试将 apc.enabled = 0 添加到我的 php.ini 中,但它并没有对崩溃或性能产生影响。(我不认为它一开始就启用了,但值得一试。)
更新:
啊哈,第三方库中有一个 require 语句多次包含该文件。我仍然不知道为什么要重新声明该类,尽管我将声明包含在所有 if/else 块中,但至少现在看来一切正常。