OJS 3.4插件兼容性问题:AppLocale类报错适配方案咨询
解决OJS 3.3与3.4插件兼容:AppLocale类弃用问题
问题场景
服务器安装OJS 3.4后,自定义插件安装时出现致命错误:
PHP Fatal error: Uncaught Error: Class "AppLocale" not found in /app/plugins/generic/My_plugin/MyPlugin.inc.php:105
出错代码为:
AppLocale::requireComponents(LOCALE_COMPONENT_APP_COMMON, LOCALE_COMPONENT_PKP_MANAGER);
该插件在OJS 3.X(3.3及以下)版本运行正常,错误表明AppLocale类在OJS 3.4中已被弃用:
@deprecated The class \APP\i18n\AppLocale has been replaced by PKP\facades\Locale
尝试修改为以下代码后,出现新错误:
use PKP\facades\Locale; use PKP\i18n\PKPLocale; Locale::requireComponents(PKPLocale::LOCALE_COMPONENT_APP_COMMON, PKPLocale::LOCALE_COMPONENT_APP_MANAGER);
错误信息:
NOTICE: PHP message: PHP Fatal error: Uncaught Error: Undefined constant PKP\i18n\PKPLocale::LOCALE_COMPONENT_APP_COMMON in /app/plugins/generic/My_plugin/MyPlugin.inc.php:114
错误原因
- OJS 3.4中
AppLocale类仅在非严格模式下存在别名,且已被官方标记为弃用,推荐使用PKP\facades\Locale替代。 LOCALE_COMPONENT_*系列常量是全局常量,并非PKPLocale类的成员属性,不能通过PKPLocale::访问。- OJS 3.4中
PKPLocale::requireComponents()方法已被废弃,内部为空实现,官方说明所有locale组件已自动加载,无需手动调用。
兼容3.3与3.4的解决方案
1. 核心修改:兼容requireComponents调用
直接通过类存在性判断,分别处理两个版本的逻辑:
// 兼容OJS 3.3及以下版本 if (class_exists('AppLocale') && method_exists('AppLocale', 'requireComponents')) { AppLocale::requireComponents(LOCALE_COMPONENT_APP_COMMON, LOCALE_COMPONENT_PKP_MANAGER); } else { // OJS 3.4+ 版本无需手动加载locale组件,所有键已自动加载 // 若需保持调用形式,可启用以下代码(实际无执行逻辑) // use PKP\facades\Locale; // Locale::requireComponents(LOCALE_COMPONENT_APP_COMMON, LOCALE_COMPONENT_PKP_MANAGER); }
2. 其他AppLocale方法的兼容处理
如果插件中还有AppLocale的其他调用(如getLocale()、getPrimaryLocale()),同样采用类存在性判断:
// 获取当前用户选中的语言 if (class_exists('AppLocale') && method_exists('AppLocale', 'getLocale')) { $currentLocale = AppLocale::getLocale(); } else { use PKP\facades\Locale; $currentLocale = Locale::getLocale(); } // 获取当前上下文的主语言 if (class_exists('AppLocale') && method_exists('AppLocale', 'getPrimaryLocale')) { $primaryLocale = AppLocale::getPrimaryLocale(); } else { use PKP\facades\Locale; $primaryLocale = Locale::getPrimaryLocale(); }
关键说明
- OJS 3.4中
Localefacade的requireComponents()方法实际无任何执行逻辑,因为官方已自动加载所有locale组件,因此在3.4+版本中可以直接跳过该调用。 - 全局常量
LOCALE_COMPONENT_*在3.3和3.4版本中均存在,直接使用即可,无需通过类访问。
内容的提问来源于stack exchange,提问作者Mohammed Amin
相关产品推荐
相关产品推荐

