마법사 :: log가 화면에 씁니다.


21

개발 시스템이 있고 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이 반향됩니까? :-) 나는 아직도 무슨 일이 일어나고 있는지 이해하지 못한다.


화면에 나타나는 출력이 블록 개체 덤프입니까 아니면 예외입니까? Mage :: log가 호출되기 전에 예외를 잡을 수 있습니다.
mybluevan

정확히 무엇을 화면에 기록 했습니까?
Alan Storm

질문을 업데이트
Fabian Blechschmidt

어떤 스택, 마 젠토 및 / 또는 PHP 버전을 사용하고 있습니까?
B00MER

MAMP PRO (아파치 /2.2.22, PHP 5.4.3) 마 젠토 1.7.0.2
Fabian Blechschmidt

답변:


29

나는 이것을 위해 짧고 달콤한 재현 가능한 테스트 사례를 만들었습니다.

<?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_rPHP 소스에서 함수 의 정의를 살펴보십시오 .

/* {{{ 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를 ​​실행하여 이러한 유형의 출력이 페이지로 이동하지 않도록하십시오.


이 자세한 답변에 감사드립니다. 나는 C 학습을 다시 시작하고 PHP 소스 코드를 읽어야합니다 :)
Fabian Blechschmidt

6

무엇 davidalger 포인트 아웃하는 것이 중요합니다. 기록하려는 객체가 너무 커서 PHP의 메모리가 부족합니다. 메모리 제한과 블록 크기에 따라 다음을 사용할 수 있습니다.

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

Varien_Object를 확장하는 모든 객체는 debug ()를 사용하여 기본 _data 속성을 재귀 적으로 출력 할 수 있습니다.

자세한 설명은 동료 중 한 명이이 블로그 게시물 을 확인하십시오 .


2

이것이 이유가 될 수 있습니까?

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

"PHP 문서에서 : return 매개 변수를 사용하면이 함수는 내부 출력 버퍼링을 사용하므로 ob_start () 콜백 함수 내에서 사용할 수 없습니다." 자세한 정보는 여기 : [php.net/manual/en/function.print-r.php]

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.