Magento 1.7 Cannot send headers; headers already s

2019-07-29 07:45发布

问题:

SOLVED I solved this issue with Jonathan Hussey help I changed this line:

$mModel->getCollection()->load($mId)->getData();

for this:

$mModel->getCollection()->addFieldToFilter('met_id',$Id)->getSelect();

Problem
I created custom module which added tab to admin product page with additional text field. When I try save this product I get this error:

a:5:{i:0;s:140:"Cannot send headers; headers already sent in /home/nano/domains/mydomain/public_html/gw/lib/Varien/Data/Collection/Db.php, line 693";i:1;s:1630:"#0 /home/nano/domains/mydomain/public_html/gw/lib/Zend/Controller/Response/Abstract.php(148): Zend_Controller_Response_Abstract->canSendHeaders(true)...

I saw that this error created in Observer.php:

$mId = $collection['m_id'];         
$mModel->getCollection()->load($mId)->getData(); <-- this line give an error

$data['met_id'] = $mId;
$data['product_id'] = $product->getId();
$data['metf1'] = $this->_getRequest()->getPost('f1');
$mModel->setData($data);
$mModel->save();

Do you have any ideas how fix this ?

EDIT content of admin template tab file:

<?php
$product = Mage::registry('current_product');
$mItem = Mage::getModel('mmodel/mmodel')->getCollection()->
addFilter('product_id',$product->getId())->getFirstItem();

echo '<div class="input-field">
 <label for="f1">File</label>
 <input type="text" class="input-text" name="f1" id="f1" value='.$mItem['f1'].' />
</div>';


Debug backtrace after line $mModel->getCollection()->load($mId)->getData(); from Observer.php

SELECT `main_table`.* FROM `mmodel` AS `main_table`
    Debug Backtrace:
    File    Line    Function
    /home/nano/domains/mydomain/public_html/gw/app/code/local/GW/MModel/Model/Observer.php  42  printDebugBacktrace
    /home/nano/domains/mydomain/public_html/gw/app/code/core/Mage/Core/Model/App.php    1338    saveProductTabData
    /home/nano/domains/mydomain/public_html/gw/app/code/core/Mage/Core/Model/App.php    1317    _callObserverMethod
    /home/nano/domains/mydomain/public_html/gw/app/Mage.php 468 dispatchEvent
    /home/nano/domains/mydomain/public_html/gw/app/code/core/Mage/Core/Model/Abstract.php   466 dispatchEvent
    /home/nano/domains/mydomain/public_html/gw/app/code/core/Mage/Catalog/Model/Product.php 548 _afterSave
    /home/nano/domains/mydomain/public_html/gw/app/code/core/Mage/Core/Model/Abstract.php   319 _afterSave
    /home/nano/domains/mydomain/public_html/gw/app/code/core/Mage/Adminhtml/controllers/Catalog/ProductController.php   714 save
    /home/nano/domains/mydomain/public_html/gw/app/code/core/Mage/Core/Controller/Varien/Action.php 419 saveAction
    /home/nano/domains/mydomain/public_html/gw/app/code/core/Mage/Core/Controller/Varien/Router/Standard.php    250 dispatch
    /home/nano/domains/mydomain/public_html/gw/app/code/core/Mage/Core/Controller/Varien/Front.php  176 match
    /home/nano/domains/mydomain/public_html/gw/app/code/core/Mage/Core/Model/App.php    354 dispatch
    /home/nano/domains/mydomain/public_html/gw/app/Mage.php 704 run
    /home/nano/domains/mydomain/public_html/gw/index.php    87  run

回答1:

When working with collections you should only pass arguments to ->load() if you want the SQL for that collection to be logged or output. If you don't want the collection to return all items you can pull the select object from the collection with ->getSelect() and filter with standard Zend methods this way.

If you trace back your collection command you will see because you pass an argument it echo's out the collection SQL.

$mModel->getCollection()->load($mId)->getData();

Have a look at lib/Varien/Data/Collection/Db.php as per the error message and find the load() method. You will see that it accepts two aguments, $printQuery and $logQuery, you have passed an argument to $printQuery. A few lines down in the method you see:

$this->printLogQuery($printQuery, $logQuery);

Looking at the printLogQuery() method you will see that anything passed as the $printQuery argument which evaluates to true triggers the echo on line 693 as per the error message:

echo is_null($sql) ? $this->getSelect()->__toString() : $sql;

This is what is sending headers in your case. Remove the argument from ->load() or pass false and it should fix your problem.