1

我在 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

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

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

有趣的是,这并不总是发生,最初加载的 WSDL 对我来说很好,最初我绞尽脑汁想看看我们的安装可能进行了哪些自定义来导致这种情况,但是我已经完成了跟踪似乎表明这一切都完全发生在核心内部。

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

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

有什么想法吗?

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

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

4

2 回答 2

2

我会向 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 请求。

于 2012-04-05T20:16:42.973 回答
0

这个答案并不意味着取代现有的答案。但是我想在这里删除一些代码,以防有人遇到这个问题,并且注释实际上不允许代码格式化。

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

不期望此修复程序需要非常长寿或升级友好,b/c 我希望他们在下一个版本左右修复此问题。

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

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

    ...
}
于 2012-04-12T22:29:18.280 回答