Mage :: log écrit à l'écran

21

J'ai un système de développement, display_errors est activé, Magento est en mode développeur et j'ai essayé de

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

Et tout a été écrit à l'écran au lieu du fichier journal, pourquoi?

Il ressemble à ce cas:

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

mais le deuxième argument de print_r est ignoré:

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, une erreur fatale se produit, aucune fonction shutdown_function n'est enregistrée, alors pourquoi le print_r est-il répété? :-) Je ne comprends toujours pas ce qui se passe.

Fabian Blechschmidt
la source
La sortie que vous obtenez à l'écran est-elle le vidage d'objet bloc ou est-ce une exception? Vous pourriez être en train d'attraper une exception avant que Mage :: log soit appelé.
mybluevan
Qu'est-ce qui est exactement écrit sur l'écran?
Alan Storm
a mis à jour la question
Fabian Blechschmidt
Quelle version de Stack, Magento et / ou PHP utilisez-vous?
B00MER
MAMP PRO (Apache / 2.2.22, PHP 5.4.3) magento 1.7.0.2
Fabian Blechschmidt

Réponses:

29

J'ai créé un cas de test reproductible vraiment court et doux pour cela:

<?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);
}

La raison pour laquelle vous voyez les informations publiées est due à l' print_rutilisation de la mémoire tampon de sortie en interne pour capturer ces informations. Jetez un œil à la définition de la print_rfonction à partir de la source PHP:

/* {{{ 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;
    }
}

Parce que PHP manque de mémoire et est en train de mourir, le tampon de sortie est vidé avant de l' print_reffacer via son appel àphp_ob_get_buffer

Je ne suis pas sûr qu'il y en aura de toute façon. Assurez-vous simplement de désactiver cette journalisation en production ou d'exécuter mod_security pour empêcher ce type de sortie d'accéder à la page.

davidalger
la source
Merci beaucoup pour cette réponse détaillée. Je devrais recommencer à apprendre C et lire le code source php :)
Fabian Blechschmidt
6

Ce que davidalger souligne est important. L'objet que vous essayez de consigner est trop gros et entraîne un manque de mémoire de PHP. En fonction de votre limite de mémoire et de la taille de votre bloc, vous pourrez peut-être utiliser:

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

Tous les objets qui étendent Varien_Object peuvent utiliser debug () pour sortir récursivement la propriété _data sous-jacente.

Consultez ce billet de blog par l'un de mes collègues pour une explication plus détaillée.

mybluevan
la source
2

cela pourrait-il être la raison?

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

"De la documentation PHP: Lorsque le paramètre de retour est utilisé, cette fonction utilise la mise en mémoire tampon de sortie interne de sorte qu'elle ne peut pas être utilisée à l'intérieur d'une fonction de rappel ob_start ()." Plus d'informations ici: [php.net/manual/en/function.print-r.php]

ProxiBlue
la source