WordPress使用scssphp编译SCSS报Cannot destroy active lambda function如何解决
你对报错原因的判断是正确的,scssphp的编译逻辑内部会调用输出缓冲区,嵌套在ob_start的回调函数中就会触发该致命错误。同时你原有代码还存在两处可优化点:一是全局定义的$compiler实例无法在匿名回调中直接访问,存在作用域问题;二是preg_replace的正则参数缺少分隔符,会导致替换失败。
下面是两种可行的解决方法:
方案1:提前编译SCSS(优先推荐)
把SCSS编译操作放到输出缓冲区启动前完成,回调中仅执行字符串替换,完全避开嵌套缓冲区冲突:
add_action( 'template_redirect', 'replace_scss', -100 ); function replace_scss(){ // 提前完成SCSS编译,不放入ob回调内执行 $compiler = new ScssPhp\ScssPhp\Compiler(); $scss = 'body { p { color: red; } }'; $compiled_css = ''; try { $compiled_css = $compiler->compile($scss); } catch (\Exception $e) { // 编译异常时记录日志,避免页面输出错误 error_log('SCSS编译错误:' . $e->getMessage()); } // 用use将编译结果传入回调 ob_start( function( $buffer ) use ($compiled_css) { if(!empty($compiled_css) && is_string($compiled_css)) { // 补充正则分隔符,修正原有替换逻辑问题 return preg_replace('#scss_compiled#', $compiled_css, $buffer ); } return $buffer; }); }
方案2:通过shutdown钩子处理最终输出
如果你的业务逻辑需要先拿到完整HTML内容再做SCSS编译,可以使用shutdown钩子在PHP执行末尾处理输出,避开ob回调的嵌套限制:
// 第一步:启动输出缓冲区,不绑定回调 add_action( 'template_redirect', 'custom_buffer_start', -100 ); function custom_buffer_start() { ob_start(); } // 第二步:在shutdown钩子中处理缓冲区内容 add_action( 'shutdown', 'custom_buffer_process', 0 ); function custom_buffer_process() { $buffer = ob_get_clean(); if(!is_string($buffer)) return; // 在此处执行SCSS编译逻辑,不会触发嵌套缓冲区冲突 $compiler = new ScssPhp\ScssPhp\Compiler(); $scss = 'body { p { color: red; } }'; try { $css = $compiler->compile($scss); if(!empty($css)) { $buffer = preg_replace('#scss_compiled#', $css, $buffer); } } catch (\Exception $e) { error_log('SCSS编译错误:' . $e->getMessage()); } // 输出处理后的最终内容 echo $buffer; }
内容的提问来源于stack exchange,提问作者Kling93
相关产品推荐
相关产品推荐

