【问题标题】:Why is Mage_Persistent breaking /api/wsdl?soap为什么 Mage_Persistent 会破坏 /api/wsdl?soap
【发布时间】:2012-04-05 18:34:23
【问题描述】:

我在 Magento CE 1.6.1.0 中收到以下错误

Warning: session_start() [<a href='function.session-start'>function.session-start</a>]: Cannot send session cookie - headers already sent by (output started at /home/dev/env/var/www/user/dev/wdcastaging/lib/Zend/Controller/Response/Abstract.php:586) in /home/dev/env/var/www/user/dev/wdcastaging/app/code/core/Mage/Core/Model/Session/Abstract/Varien.php on line 119

访问/api/soap/?wsdl

显然,在已经输出 WSDL 文件的全部内容之后,正在尝试 session_start(),从而导致错误。

为什么 magento 会在输出所有数据后尝试启动会话?我很高兴你问。所以看起来 controller_front_send_response_after 被 Mage_Persistent 钩住以调用 synchronizePersistentInfo(),这反过来又导致 session_start() 被触发。

有趣的是,这并不总是发生,最初加载的 WSDL 对我来说还不错,最初我绞尽脑汁想看看我们的安装可能进行了哪些自定义导致这个,但我所做的跟踪似乎表明这一切都发生在核心内部。

我们也经历了一点点(完全不相关的)对 Mage_Persistent 的陌生感,这让我在这一点上更愿意举起手来。

我在 SO 上进行了一些搜索,发现了一些与整个“标头已发送”相关的问题,但不是这种特定情况。

有什么想法吗?

哦,我的临时解决方法是通过 persistent/options/enable 配置数据禁用 Mage_Persistent。我还进行了一些研究,以了解是否可以观察一个事件以便为 WSDL 控制器禁用此模块only(因为这似乎是唯一有问题的模块),但看起来该模块完全依赖此配置标志来确定它的启用状态。

更新:已报告错误:http://www.magentocommerce.com/bug-tracking/issue?issue=13370

【问题讨论】:

  • Magento 版本? Mage_Persistant 是一个相对较新的功能,如果它漏掉了我也不会感到惊讶。
  • 嘿艾伦,是的,好问题 - ME 1.11.0

标签: api session magento


【解决方案1】:

我会向 Magento 团队报告这是一个错误。 Magento API 控制器都通过标准 Magento 动作控制器对象进行路由,并且所有这些对象都继承自 Mage_Api_Controller_Action 类。这个类有一个preDispatch 方法

class Mage_Api_Controller_Action extends Mage_Core_Controller_Front_Action
{
    public function preDispatch()
    {
        $this->getLayout()->setArea('adminhtml');
        Mage::app()->setCurrentStore('admin');
        $this->setFlag('', self::FLAG_NO_START_SESSION, 1); // Do not start standart session
        parent::preDispatch();
        return $this;
    }
    //...
}

其中包括设置一个标志以确保 API 方法不会启动正常的会话处理。

$this->setFlag('', self::FLAG_NO_START_SESSION, 1);

所以,听起来synchronizePersistentInf 中的代码假定存在会话对象,并且当它使用它时会话被初始化,从而导致您看到的错误。通常,这不是问题,因为此时每个其他控制器都已初始化会话,但 API 控制器明确将其关闭。

就修复而言,您最好的选择(可能是您从 Magento 支持部门获得的快速回答)将禁用默认配置设置的持久购物车功能,然后为需要它的特定商店启用它.这会让购物车

自行提出解决方案将是一个未知领域,我想不出一种方法来做到这一点,它不是非常笨拙/不稳定。最直接的方法是在 synchronizePersistentInf 上重写类,调用它的父方法,除非您检测到这是一个 API 请求。

【讨论】:

  • 哎呀,对不起,我在 ME 1.11.0 中做了很多工作,但有问题的实例实际上是 CE 1.6.1.0 - 我想同样的根本原因正在发挥作用不过。
【解决方案2】:

此答案并非要替换现有答案。但是我想在这里放一些代码以防有人遇到这个问题,而 cmets 并不允许代码格式化。

我使用了一个简单的 local 代码池覆盖 Mage_Persistent_Model_Observer_Session 以退出 /api/* 内的任何 URL 路由的函数

不希望这个修复需要非常长的生命周期或升级友好,b/c 我希望他们在下一个版本左右修复这个。

public function synchronizePersistentInfo(Varien_Event_Observer $observer)
{
    ...

    if ($request->getRouteName() == 'api') {
        return;
    }

    ...
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-03-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多