You need to enable JavaScript to run this app. Yii2下使用BotMan2.1出现对话属性跨步骤丢失问题求助
优惠活动
大模型
产品
解决方案
定价
更多

Yii2下使用BotMan2.1出现对话属性跨步骤丢失问题求助

核心根因

BotMan 2.x 版本的多轮对话流程,并不会在同一个PHP生命周期内持续持有Conversation类的实例。每次用户发送消息触发对话回调时,框架都会走固定流程:

  • 从缓存中取出上一轮对话序列化存储的状态
  • 反序列化重建全新的Conversation类实例
  • 调用对应步骤的回调方法处理用户输入
    你现在遇到的属性全为NULL的问题,本质是对话对象在序列化存缓存的环节就已经损坏,和缓存驱动选型没有关系。

为什么首次回调能读到正确值

askTitle方法里的回调是和该方法在同一个请求生命周期内执行的,赋值$this->alertTitle后立刻打日志时,值还存在内存里,自然能正常输出。等用户下一次发消息触发后续步骤时,框架会从缓存里反序列化重建对象,这时候之前存的属性已经因为序列化损坏丢失,读出来就全是NULL。

序列化损坏的直接原因

你在类里定义的public $bot属性是导致问题的核心:BotMan实例内部持有当前请求的HTTP上下文、驱动连接资源、不可序列化的临时对象,PHP在对整个Conversation类执行序列化时,遇到这类不可序列化的资源会直接丢弃对应属性,甚至连带截断整个序列化字符串,导致你自定义的alert*属性根本没被成功存进缓存。
不管你把缓存从SymfonyCache换成Redis还是其他存储,本质存的都是已经损坏的序列化字符串,自然读不回正确值。

排查验证方法

在askTitle的回调赋值完$this->alertTitle之后,手动执行:

$serialized = serialize($this);
\Yii::warning($serialized);

检查输出的序列化字符串:绝大多数场景下你会看不到自己赋值的alertTitle内容,同时日志里会出现关于不可序列化对象的警告,直接验证问题根源。

落地方案
  1. 移除冗余的不可序列化属性
    不要在类里手动持有构造函数传入的$bot对象。BotMan的Conversation基类本身已经提供了$this->getBot()方法,可以在任意对话步骤中获取当前请求上下文对应的Bot实例,完全不需要自己存。
    删掉类里的public $bot;属性和构造函数的传参逻辑,避免序列化时携带不可序列化的资源。
  2. 明确指定需要持久化的序列化属性
    如果确实需要在类里存临时对象,通过PHP魔术方法明确告诉框架哪些属性需要序列化存缓存:
    /**
     * 指定需要序列化持久化到缓存的属性列表
     */
    public function __sleep()
    {
        return [
            'alertTitle',
            'alertDescription',
            'alertLatitude',
            'alertLongitude',
            'alertAuthorId',
            'alertAuthorName'
        ];
    }
    
    /**
     * 反序列化完成后,重新初始化当前请求需要的上下文
     */
    public function __wakeup()
    {
        // 反序列化时不会执行构造函数,这里手动获取当前请求的Bot实例
        $this->bot = $this->getBot();
    }
    
  3. 优先使用框架内置的状态存储
    BotMan的Conversation基类自带设计好的跨步骤状态存储$this->state,这个组件本身就是为了序列化持久化设计的,不需要自己管理类属性的序列化兼容性。
    把原来直接读类属性的逻辑替换成state读写,可靠性会高很多:
    // 赋值示例
    $this->state->set('alertTitle', $this->askSomethingWithLettersCounting(...));
    // 取值示例
    $this->state->get('alertTitle');
    

内容的提问来源于stack exchange,提问作者Илья Шах

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.11.14 12:24:03