Mage :: log schreibt auf den Bildschirm

21

Ich habe ein Entwicklungssystem, display_errors ist aktiviert, Magento befindet sich im Entwicklermodus und ich habe es versucht

Mage::log($layered_navigation_filter_block); // Mage_Catalog_Block_Layer_Filter_Attribute

Und alles wurde anstelle der Protokolldatei auf den Bildschirm geschrieben, warum?

Es sieht so aus:

// app/Mage.php:837
if (is_array($message) || is_object($message)) {
    $message = print_r($message, true);
}

Das zweite Argument von print_r wird ignoriert:

Mage_Catalog_Block_Layer_Filter_Category Object ( [_filter:protected] => ...

 

[28-Jan-2013 22:48:43 UTC] PHP Fatal error:  Allowed memory size of 268435456 bytes exhausted (tried to allocate 241434624 bytes) in /var/www/app/code/local/MyCompany/Motif/Model/Observer.php on line 47
[28-Jan-2013 22:48:43 UTC] PHP Stack trace:
[28-Jan-2013 22:48:43 UTC] PHP   1. {main}() /var/www/index.php:0
[28-Jan-2013 22:48:43 UTC] PHP   2. Mage::run() /var/www/index.php:87
[28-Jan-2013 22:48:43 UTC] PHP   3. Mage_Core_Model_App->run() /var/www/app/Mage.php:683
[28-Jan-2013 22:48:43 UTC] PHP   4. Mage_Core_Controller_Varien_Front->dispatch() /var/www/app/code/core/Mage/Core/Model/App.php:354
[28-Jan-2013 22:48:43 UTC] PHP   5. Mage_Core_Controller_Varien_Router_Standard->match() /var/www/app/code/core/Mage/Core/Controller/Varien/Front.php:176
[28-Jan-2013 22:48:43 UTC] PHP   6. Mage_Core_Controller_Varien_Action->dispatch() /var/www/app/code/core/Mage/Core/Controller/Varien/Router/Standard.php:250
[28-Jan-2013 22:48:43 UTC] PHP   7. Mage_Catalog_CategoryController->viewAction() /var/www/app/code/core/Mage/Core/Controller/Varien/Action.php:419
[28-Jan-2013 22:48:43 UTC] PHP   8. Mage_Core_Controller_Varien_Action->generateLayoutBlocks() /var/www/app/code/core/Mage/Catalog/controllers/CategoryController.php:146
[28-Jan-2013 22:48:43 UTC] PHP   9. Mage_Core_Model_Layout->generateBlocks() /var/www/app/code/core/Mage/Core/Controller/Varien/Action.php:344
[28-Jan-2013 22:48:43 UTC] PHP  10. Mage_Core_Model_Layout->generateBlocks() /var/www/app/code/core/Mage/Core/Model/Layout.php:210
[28-Jan-2013 22:48:43 UTC] PHP  11. Mage_Core_Model_Layout->_generateBlock() /var/www/app/code/core/Mage/Core/Model/Layout.php:205
[28-Jan-2013 22:48:43 UTC] PHP  12. Mage_Core_Model_Layout->addBlock() /var/www/app/code/core/Mage/Core/Model/Layout.php:239
[28-Jan-2013 22:48:43 UTC] PHP  13. Mage_Core_Model_Layout->createBlock() /var/www/app/code/core/Mage/Core/Model/Layout.php:472
[28-Jan-2013 22:48:43 UTC] PHP  14. Mage_Core_Block_Abstract->setLayout() /var/www/app/code/core/Mage/Core/Model/Layout.php:456
[28-Jan-2013 22:48:43 UTC] PHP  15. Mage::dispatchEvent() /var/www/app/code/core/Mage/Core/Block/Abstract.php:239
[28-Jan-2013 22:48:43 UTC] PHP  16. Mage_Core_Model_App->dispatchEvent() /var/www/app/Mage.php:447
[28-Jan-2013 22:48:43 UTC] PHP  17. Mage_Core_Model_App->_callObserverMethod() /var/www/app/code/core/Mage/Core/Model/App.php:1317
[28-Jan-2013 22:48:43 UTC] PHP  18. MyCompany_Motif_Model_Observer->coreBlockAbstractPrepareLayoutAfter() /var/www/app/code/core/Mage/Core/Model/App.php:1338
[28-Jan-2013 22:48:43 UTC] PHP  19. print_r() /var/www/app/code/local/MyCompany/Motif/Model/Observer.php:47

Ok, ein schwerwiegender Fehler ist aufgetreten. Es ist keine shutdown_function registriert. Warum wird also print_r zurückgemeldet? :-) Ich verstehe immer noch nicht, was passiert.

Fabian Blechschmidt
quelle
Ist die Ausgabe, die Sie auf dem Bildschirm erhalten, der Blockobjektspeicherauszug oder ist es eine Ausnahme? Möglicherweise tritt eine Ausnahme auf, bevor Mage :: log aufgerufen wird.
Mybluevan
Was genau wurde auf den Bildschirm geschrieben?
Alan Storm
Die Frage wurde aktualisiert
Fabian Blechschmidt
Welche Stack-, Magento- und / oder PHP-Version verwenden Sie?
B00MER
MAMP PRO (Apache / 2.2.22, PHP 5.4.3) magento 1.7.0.2
Fabian Blechschmidt

Antworten:

29

Ich habe dafür einen wirklich kurzen und süßen reproduzierbaren Testfall erstellt:

<?php

error_reporting(-1);
ini_set('display_errors', true);
ini_set('memory_limit', '1M');

$chunk = base64_encode(openssl_random_pseudo_bytes(1024));

while (true) {
    $a[] = print_r($chunk, true);
}

Der Grund, warum die Informationen print_rausgegeben werden, liegt in der internen Verwendung des Ausgabepuffers zur Erfassung der Informationen. Schauen Sie sich die Definition der print_rFunktion aus der PHP-Quelle an:

/* {{{ proto mixed print_r(mixed var [, bool return])
   Prints out or returns information about the specified variable */
PHP_FUNCTION(print_r)
{
    zval *var;
    zend_bool do_return = 0;

    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|b", &var, &do_return) == FAILURE) {
        RETURN_FALSE;
    }

    if (do_return) {
        php_start_ob_buffer (NULL, 0, 1 TSRMLS_CC);
    }

    zend_print_zval_r(var, 0 TSRMLS_CC);

    if (do_return) {
        php_ob_get_buffer (return_value TSRMLS_CC);
        php_end_ob_buffer (0, 0 TSRMLS_CC);
    } else {
        RETURN_TRUE;
    }
}

Da PHP nicht mehr genügend Arbeitsspeicher hat und nicht mehr funktioniert, wird der Ausgabepuffer geleert, bevor print_rer über den Aufruf von gelöscht wirdphp_ob_get_buffer

Ich bin mir nicht sicher, ob es sowieso darum geht. Stellen Sie einfach sicher, dass Sie diese Protokollierung in der Produktion deaktivieren, oder führen Sie mod_security aus, um zu verhindern, dass diese Art von Ausgabe auf die Seite gelangt.

Davidalger
quelle
Vielen Dank für diese ausführliche Antwort. Ich sollte C neu lernen und PHP-Quellcode lesen :)
Fabian Blechschmidt
6

Was Davidalger hervorhebt , ist wichtig. Das Objekt, das Sie protokollieren möchten, ist zu groß und führt dazu, dass PHP nicht mehr genügend Arbeitsspeicher hat. Abhängig von Ihrer Speicherkapazität und der Größe Ihres Blocks können Sie möglicherweise Folgendes verwenden:

Mage::log($layered_navigation_filter_block->debug());

Alle Objekte, die Varien_Object erweitern, können debug () verwenden, um die zugrunde liegende Eigenschaft _data rekursiv auszugeben.

In diesem Blogbeitrag von einem meiner Mitarbeiter finden Sie eine ausführlichere Erklärung.

mybluevan
quelle
2

könnte das der grund sein

/programming/9329877/using-print-r-in-ob-start

"Aus der PHP-Dokumentation: Wenn der Rückgabeparameter verwendet wird, verwendet diese Funktion die interne Ausgabepufferung, sodass sie nicht in einer ob_start () - Rückruffunktion verwendet werden kann." Mehr Infos hier: [php.net/manual/en/function.print-r.php]

ProxiBlue
quelle