无法重新声明类 - 检查类是否已经存在。

4
我正在处理一个脚本,它调用同一个类两次,并抛出以下错误信息:
Fatal: Cannot redeclare class urlConverter (/var/www/core/cache/includes/elements/modsnippet/23.include.cache.php:14)

我尝试将以下代码放置在:

if( !class_exists( 'urlConverter', false ) )
{
    $urlConverter = new urlConverter( $modx );
}

然而,我所使用的CMS报告了500错误,但我无法从日志中看出它为什么会出现这种错误。

有人知道如何检查该类是否已正确声明吗?

编辑:

我正在使用CMS,因此该类位于片段中而不是实际文件中。这是他们调用片段的方式:

$data['viewonlinelink'] = $this->modx->runSnippet( 'urlConverter', array(
                                            'action' => 'encrypt',
                                            'string' => http_build_query( $string ) ) );

我需要再次调用它以获得不同的结果。
编辑2:
这是urlConverter:
<?php
class urlConverter {

public $modx;

public function __construct( modX &$modx )
{
    $this->modx =& $modx;
}


public function action( $scriptProperties )
{
    return $this->$scriptProperties['action']( $scriptProperties['string'] );
}

private function encrypt( $str )
{
    return $str;
}


private function decrypt( $str )
{
      return $str;
}


}
}
 $urlConverter = new urlConverter( $modx );
 return $urlConverter->action( $scriptProperties );

现在我从另一个脚本中调用以下内容:
    $data['viewonlinelink'] = $this->modx->runSnippet( 'urlConverter', array(
                                            'action' => 'encrypt',
                                            'string' => http_build_query( $string ) ) );
    $data['confirmonline']  = $this->modx->runSnippet( 'urlConverter', array(
                                            'action' => 'encrypt',
                                            'string' => http_build_query( $reversed ) ) );

在我的urlConverter类中运行加密函数,我应该得到两个不同的结果。


1
你是否在包含/需要类文件?如果是的话,请使用include_oncerequire_once - Sampson
2
你可能在某个地方重复了require/include。 - Tim Withers
我有点在包含中。我正在使用一个名为MODx的CMS。我将使用他们的CMS中的require语句修改我的问题。 - Peter
@TimWithers 我猜你指的是 if (file_exists($file)) { $o = include $file; } else { $o = '文件未找到:'.$file; } return $o;我想我可以尝试一下..虽然我没有那样引用他们的片段,但这样做也无妨。 - Peter
@TimWithers 我是这样引用我的代码片段的 http://rtfm.modx.com/display/revolution20/modX.runSnippet - Peter
显示剩余2条评论
4个回答

9
在使用更新后的代码时,请将类文件更改为以下内容:
<?php
if(!class_exists('urlConverter')){
    class urlConverter {

        public $modx;

        public function __construct( modX &$modx ){
            $this->modx =& $modx;
        }
        public function action( $scriptProperties ){
            return $this->$scriptProperties['action']( $scriptProperties['string'] );
        }

        private function encrypt( $str ){
            return $str;
        }


        private function decrypt( $str ){
          return $str;
        }

    }
 }
$urlConverter = new urlConverter( $modx );
return $urlConverter->action( $scriptProperties );

哦,我现在明白了!MODx使用PDO将类缓存到它们的注册表中。这个方法非常有效。 - Peter

5

redeclare class 错误不是由创建类的实例引起的,而是在同一符号上调用 class 运算符时引起的。您可能多次包含了 urlConverter 类定义文件。


是的,那似乎是正确的。我不知道如何不这样做。我正在使用的CMS会自动执行此操作,而我没有太多选择。 - Peter
@Peter 如果你不能修改CMS,就修改你的代码,仅当该类尚未被创建时才创建类(而不是实例)。 - Sampson
@JonathanSampson 你是什么意思? - Peter

4

如果您无法修改将类文件引入CMS的方式(使用require_onceinclude_once),请修改您的代码片段:

if( !class_exists( 'urlConverter' ) ) {
    class urlConverter {
        /* Build class */
    }
}

当然,如果您在同一文件中有其他内容,则需要确保它不会尝试运行两次。

嗯...这样抑制了错误,但是第二次尝试从类中获取输出时没有返回任何内容。 - Peter
@Peter 你能更新一下你目前正在尝试什么吗?这应该是你唯一调用 class_exists 的地方。 - Sampson

2
看起来定义类的文件被包含了多次,这就是为什么会出现第一个错误(无法重新声明类)的原因。 /var/www/core/cache/includes/elements/modsnippet/23.include.cache.php 的第 14 行似乎是多次包含该类的原因。如果可能的话,请将 include 更改为 include_once,以便不会多次定义该类。
要进一步调试(而不是看到 500 内部服务器错误),请尽早将以下内容添加到您的代码中:
error_reporting(E_ALL);
ini_set('display_errors', 1);

否则,请检查服务器的error_log(Apache),看看是否有关于500错误的有用信息。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接