能否更新Timber与Twig适配PHP8?旧Sage主题兼容问题求助
问题根源
你的报错核心是Twig 1.24.1与PHP8严格类型检查不兼容:旧版Twig的getAttribute方法错误地将Timber\Menu对象传递给array_key_exists函数(PHP8要求该函数第二个参数必须是数组)。同时2016年的旧版Timber本身完全不支持PHP8,单独替换Twig文件无法解决Timber底层的兼容性问题。
分步解决步骤
1. 彻底移除主题内置的旧依赖
- 删除主题目录
wp-content/themes/wobs-theme/vendor下的timber和twig文件夹 - 打开主题的
functions.php或autoload.php,移除所有引用旧vendor目录的代码(比如require_once get_template_directory() . '/vendor/autoload.php';这类语句)
2. 用Composer安装兼容PHP8的Timber版本
- 若主题根目录无
composer.json,先初始化:composer init --no-interaction - 安装支持PHP8的Timber 2.x版本(自带适配的Twig 3.x,无需单独安装Twig):
composer require timber/timber:^2.0 - 在主题
functions.php中添加新的自动加载代码:require_once get_template_directory() . '/vendor/autoload.php';
3. 适配主题代码到新版Timber
- 命名空间调整:旧版全局类改为命名空间格式:
// 旧代码 $menu = new TimberMenu('main-menu'); // 新代码 $menu = new \Timber\Menu('main-menu'); - 菜单调用修复:报错来自
get_items方法,新版Timber中Timber\Menu直接提供items属性,修改header.twig:// 旧代码 {% for item in menu.get_items %} // 新代码 {% for item in menu.items %}
4. 修复Twig模板兼容性
Twig 3.x与1.x存在语法差异,需检查模板文件:
- 替换过时过滤器,比如
|escape改为|e - 检查自定义函数/过滤器的注册逻辑,新版Timber的注册API已更新
- 避免依赖旧版魔术方法,优先直接访问对象属性而非调用getter方法
5. 解决插件冲突
之前安装Timber插件报错是因为旧版内置Timber与插件冲突。现在移除旧版后,二选一即可:保留Composer安装的主题内置Timber,或卸载Composer版并安装官方Timber插件(推荐前者,与主题绑定更稳定)
错误信息参考
PHP Fatal error: Uncaught TypeError: array_key_exists(): Argument #2 ($array) must be of type array, Timber\Menu given in /nas/content/live/site/wp-content/themes/wobs-theme/vendor/twig/twig/lib/Twig/Template.php:533
Stack trace:
#0 /nas/content/live/site/wp-content/themes/wobs-theme/vendor/twig/twig/lib/Twig/Environment.php(403) : eval()'d code(23): Twig_Template->getAttribute(Object(Timber\Menu), 'get_items', Array)
#1 /nas/content/live/site/wp-content/themes/wobs-theme/vendor/twig/twig/lib/Twig/Template.php(387): __TwigTemplate_eada0446f028acb9eb859e593a68397ec9225f348f46a00ab74866dfa38d8f16->doDisplay(Array, Array)
#2 /nas/content/live/site/wp-content/themes/wobs-theme/vendor/twig/twig/lib/Twig/Template.php(355): Twig_Template->displayWithErrorHandling(Array, Array)
#3 /nas/content/live/site/wp-content/themes/wobs-theme/vendor/twig/twig/lib/Twig/Template.php(366): Twig_Template->display(Array)
#4 /nas/content/live/site/wp-content/themes/wobs-theme/vendor/twig/twig/lib/Twig/Environment.php(347): Twig_Template->render(Array)
#5 /nas/content/live/site/wp-content/themes/wobs-theme/vendor/timber/timber/lib/Loader.php(72): Twig_Environment->render('header.twig', Array)
#6 /nas/content/live/site/wp-content/themes/wobs-theme/vendor/timber/timber/lib/Timber.php(281): Timber\Loader->render('header.twig', Array, false, 'default')
#7 /nas/content/live/site/wp-content/themes/wobs-theme/vendor/timber/timber/lib/Timber.php(317): Timber\Timber::compile('header.twig', Array, false, 'default', true)
#8 /nas/content/live/site/wp-content/themes/wobs-theme/vendor/timber/timber/lib/Timber.php(332): Timber\Timber::fetch('header.twig', Array, false, 'default')
#9 /nas/content/live/site/wp-content/themes/wobs-theme/templates/header.php(37): Timber\Timber::render('header.twig', Array)
#10 /nas/content/live/site/wp-includes/template.php(785): require('/nas/content/li...')
#11 /nas/content/live/site/wp-includes/template.php(718): load_template('/nas/content/li...', false, Array)
#12 /nas/content/live/site/wp-includes/general-template.php(204): locate_template(Array, true, false, Array)
#13 /nas/content/live/site/wp-content/themes/wobs-theme/base-front-page.php(19): get_template_part('templates/heade...')
#14 /nas/content/live/site/wp-includes/template-loader.php(106): include('/nas/content/li...')
#15 /nas/content/live/site/wp-blog-header.php(19): require_once('/nas/content/li...')
#16 /nas/content/live/site/index.php(17): require('/nas/content/li...')
#17 {main}
thrown in /nas/content/live/site/wp-content/themes/wobs-theme/vendor/twig/twig/lib/Twig/Template.php on line 533
内容的提问来源于stack exchange,提问作者Robert Lodi

