Маг::журнал записывает на экран
У меня есть система разработки, display_errors включен, Magento находится в режиме разработчика, и я попытался
Mage::log($layered_navigation_filter_block); // Mage_Catalog_Block_Layer_Filter_Attribute
И все было записано на экран вместо файла журнала, почему?
Это выглядит так:
// app/Mage.php:837
if (is_array($message) || is_object($message)) {
$message = print_r($message, true);
}
Но второй аргумент из print_r игнорируется:
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
Хорошо, произошла фатальная ошибка, функция shutdown_function не зарегистрирована, так почему же повторяется print_r? :-) Я все еще не понимаю, что такое происходящий.
3 answers
Для этого я создал действительно короткий и приятный воспроизводимый тестовый пример:
<?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);
}
Причина, по которой вы видите вывод информации, заключается в том, что print_r
использует внутреннюю буферизацию вывода для сбора этой информации. Взгляните на определение функции print_r
из источника 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;
}
}
Поскольку PHP исчерпывает память и умирает, выходной буфер очищается до того, как print_r
очистит его с помощью вызова php_ob_get_buffer
Я не уверен, что там будет во всяком случае, вокруг этого. Просто убедитесь, что вы отключили этот вход в рабочую среду или запустили mod_security, чтобы этот тип вывода не попадал на страницу.
Важно то, на что указывает дэвидалгер. Объект, который вы пытаетесь зарегистрировать, слишком велик и вызывает нехватку памяти в PHP. В зависимости от вашего лимита памяти и размера вашего блока вы можете использовать:
Mage::log($layered_navigation_filter_block->debug());
Все объекты, расширяющие Varien_Object, могут использовать debug() для рекурсивного вывода базового свойства _data.
Ознакомьтесь с этим сообщением в блоге одного из моих коллег для более подробного объяснения.
Может ли это быть причиной?
Https://stackoverflow.com/questions/9329877/using-print-r-in-ob-start
"Из документации PHP: При использовании возвращаемого параметра эта функция использует внутреннюю буферизацию вывода, поэтому ее нельзя использовать внутри функции обратного вызова ob_start()". Более подробная информация здесь: [php.net/manual/en/function.print-r.php ]