You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Guzzle更新致MediaWiki 1.39.3 LTS崩溃,如何规避依赖问题?

MediaWiki与Guzzle版本冲突导致的崩溃问题分析与解决方案

问题现象

底层致命错误

Fatal error: Declaration of MWCallbackStream::write($string) must be compatible with Psr\Http\Message\StreamInterface::write(string $string): int in /var/www/html/includes/http/MWCallbackStream.php on line 49

下游客户端表现

Did not get a valid JSON response from the server. Check that you used the correct hostname. If you did, the server might be wrongly configured or experiencing temporary problems.

重现场景

目标为MediaWiki 1.39 LTS时失败

wikipush -l -s master -t crm -p "Concept:Action"
copying 1pages from master to crm
1/1 ( 100%): copying Concept:Action ...❌:Did not get a valid JSON response from the server. Check that you used the correct hostname. If you did, the ...

非1.39 LTS环境正常运行

wikipush -l -s master -t wiki -p "Concept:Action" -f
copying 1pages from master to wiki
1/1 ( 100%): copying Concept:Action ...✅

相关代码

Python推送逻辑

def push(self):
    """
    push according to my command line args
    """
    if not self.args.source:
        raise "missing source wiki"
    if self.args.topics:
        topic_names=self.args.topics
    else:
        topic_names=self.context.topics.keys()
    login=self.args.login
    force=self.args.force
    ignore=True
    wikiPush=WikiPush(fromWikiId=self.args.source,toWikiId=self.smwAccess.wikiId,login=login,verbose=not self.args.quiet,debug=self.args.debug)
    if not self.args.quiet:
        print(f"pushing concept {self.args.context} from {self.args.source} to {self.wikiId} ...")
    all_failed=[]
    for topic_name in topic_names:
        failed=wikiPush.push(pageTitles=[f"Concept:{topic_name}"],force=force,ignore=ignore,withImages=True)
        all_failed.extend(failed)
        pass
    if len(all_failed)>0:
        print(f"Warning {len(all_failed)} uploads failed")

MediaWiki调试配置(用于定位根因)

error_reporting( -1 );
ini_set( 'display_errors', 1 );
$wgShowExceptionDetails=true;

核心问题

  1. Guzzle更新为何轻易导致MediaWiki崩溃?
  2. 该现象的根本原因是什么?
  3. 未来如何避免此类问题?

当前使用Guzzle版本为"guzzlehttp/guzzle": "7.4.5",仅找到临时解决方案,未明确根因,需制定长期方案规避依赖版本冲突导致的CI崩溃问题。

问题解答

1. Guzzle更新触发崩溃的原因

Guzzle 7.x依赖的PSR-7规范中,Psr\Http\Message\StreamInterface::write方法的签名明确要求string类型参数和int类型返回值。MediaWiki 1.39 LTS的MWCallbackStream::write方法未声明参数类型与返回类型,当Guzzle更新到严格遵循PSR规范的版本后,PHP的方法签名兼容性检查会直接触发致命错误,导致服务崩溃。

2. 根本原因

  • 接口契约不兼容:MediaWiki 1.39 LTS的MWCallbackStream类实现了PSR-7的StreamInterface,但未严格匹配接口的方法签名,缺少参数类型和返回类型声明。
  • 依赖版本管控缺失:MediaWiki的依赖配置中未对Guzzle及相关PSR包做严格版本约束,允许自动更新到不兼容版本,触发了PHP严格类型检查的错误。
  • 场景触发局限性:仅当操作涉及流写入(如包含图片的页面推送)时才会加载MWCallbackStream类,这也是问题仅在部分页面出现的原因。

3. 长期规避方案

  • 锁定依赖版本:在MediaWiki的composer.json中对Guzzle及PSR相关依赖添加精确版本约束,指定与1.39 LTS兼容的版本范围,避免自动更新到不兼容版本。
  • 修复接口实现:修改MWCallbackStream::write方法,使其签名与StreamInterface完全一致:
    public function write(string $string): int {
        // 原有业务逻辑保持不变
    }
    
  • CI流程校验:在CI环节添加依赖版本校验步骤,确保部署的依赖版本与测试通过的版本完全一致,避免依赖更新导致的CI崩溃。
  • 遵循官方依赖清单:严格使用MediaWiki LTS版本对应的官方推荐依赖版本,不随意升级第三方依赖包。

内容的提问来源于stack exchange,提问作者Wolfgang Fahl

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 15:52:51