PHP 7.1 在 Cake 中使用 Traits PHP 2 应用程序抛出碰撞错误

PHP 7.1 usage with Traits in Cake PHP 2 application throws collision errors

我在Cake PHP 2应用程序中编码 运行 PHP 7.1,由于业务限制,我无法升级PHP版本或Cake版本,我我正在构建一个自定义“模块”系统,它有一个使用 PHP 特征的 Traits 文件夹,我的控制器正在调用这些特征,每个特征都包含其他特征,因为这意味着我可以轻松地重用代码.

我遇到的问题是,直到 PHP 7.3,PHP 抛出“与其他特征方法冲突”的致命错误,现在我不记得有任何重复的方法名称每个特征,有没有一种方法可以安静地关闭这个特定的 PHP 错误或稍微修改我的代码,这样我就不必在我拥有的所有特征中以不同的方式重命名每个 function/method ?

我的仪表板控制器是

<?php

App::uses('AppController', 'Controller');
App::uses('CakeEvent', 'CakeEventManager', 'Event');

// traits
App::uses('Settings', 'modules/QueueManagerModule/Traits');
App::uses('Presenters', 'modules/QueueManagerModule/Traits');
App::uses('Statistics', 'modules/QueueManagerModule/Traits');
App::uses('Jobs', 'modules/QueueManagerModule/Traits');
App::uses('Dates', 'modules/QueueManagerModule/Traits');

class QueueController extends AppController
{
    use Settings, Presenters, Statistics, Jobs, Dates;

    /**
    * View: Queue/dashboard
    */
    public function dashboard()
    {
        // dashboard
    }

}

我称之为 Jobs 的 7 个特征之一:

<?php

App::uses('ClassRegistry', 'Utility');

// Traits
App::uses('Helpers', 'modules/QueueManagerModule/Traits');
App::uses('Settings', 'modules/QueueManagerModule/Traits');

trait Jobs {
    use Helpers, Settings;

    // methods
}

I don't recall having any duplicate method names in each trait

这不是这里的问题。 问题是您正在这样做:

trait Jobs {
    use Helpers, Settings;
}

然后是这个:

class QueueController extends AppController
{
    use Settings, Presenters, Statistics, Jobs, Dates;
}

Jobs 特征使用 Settings 特征,而 QueueController class 同时使用 JobsSettings traits 正在制造问题。

更一般地说,应用一个已经在使用其他特征的特征,然后直接包含其他特征也会导致问题。

考虑这个更简单的例子:

<?php

trait FooTrait {
    function foo()
    {}
}

trait BarTrait {
    function bar()
    {}
}

trait BazTrait {
    use FooTrait, BarTrait;

    function baz()
    {}
}

class Test {
    use FooTrait, BarTrait, BazTrait;

    function doSomething()
    {}
}

$test = new Test;

var_dump(get_class_methods($test));

如果你执行它,你会看到抛出同样的错误:

Fatal error: Trait method foo has not been applied, because there are collisions with other trait methods on Test in /in/H54W0 on line 20

没有办法“安静地关闭这个特定的 PHP 错误”,这不是您可以忽略的 warningnotice。这是一个 总是 出现的 fatal error,解决它的唯一方法是更改​​您的代码,这样您就不会将相同的特征应用到 class(甚至 间接 ,如您的情况)。

所以,第四个例子,解决方案是从 QueueController class 中删除 Settings 特征,因为它已经包含在 Jobs 特征中(并且对所有其他在自身内部使用特征的特征做同样的事情):

<?php

App::uses('AppController', 'Controller');
App::uses('CakeEvent', 'CakeEventManager', 'Event');

// traits
App::uses('Settings', 'modules/QueueManagerModule/Traits');
App::uses('Presenters', 'modules/QueueManagerModule/Traits');
App::uses('Statistics', 'modules/QueueManagerModule/Traits');
App::uses('Jobs', 'modules/QueueManagerModule/Traits');
App::uses('Dates', 'modules/QueueManagerModule/Traits');

class QueueController extends AppController
{
    use Presenters, Statistics, Jobs, Dates;

    /**
    * View: Queue/dashboard
    */
    public function dashboard()
    {
        // dashboard
    }

}
<?php

App::uses('ClassRegistry', 'Utility');

// Traits
App::uses('Helpers', 'modules/QueueManagerModule/Traits');
App::uses('Settings', 'modules/QueueManagerModule/Traits');

trait Jobs {
    use Helpers, Settings;

    // methods
}