Mage :: log menulis ke layar

21

Saya memiliki sistem pengembangan, display_errors aktif, Magento dalam mode pengembang dan saya mencoba

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

Dan semuanya ditulis di layar alih-alih file log, mengapa?

Ini terlihat seperti ini:

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

tetapi argumen kedua dari print_r diabaikan:

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, kesalahan fatal terjadi, tidak ada shutdown_function terdaftar, jadi mengapa print_r digaungkan? :-) Saya masih tidak mengerti apa yang sedang terjadi.

Fabian Blechschmidt
sumber
Apakah output yang Anda dapatkan di layar adalah objek blok dump atau itu pengecualian? Anda bisa mendapatkan pengecualian sebelum Mage :: log dipanggil.
mybluevan
Apa, tepatnya, apa yang tertulis di layar?
Alan Storm
memperbarui pertanyaan
Fabian Blechschmidt
Stack, Magento, dan / atau versi PHP apa yang Anda gunakan?
B00MER
MAMP PRO (Apache / 2.2.22, PHP 5.4.3) magento 1.7.0.2
Fabian Blechschmidt

Jawaban:

29

Saya membuat test case yang benar-benar pendek dan manis untuk ini:

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

Alasan Anda melihat informasi dikeluarkan karena print_rmenggunakan buffering output secara internal untuk menangkap informasi itu. Lihatlah definisi print_rfungsi dari sumber 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;
    }
}

Karena PHP kehabisan memori dan sekarat, buffer output sedang disiram sebelum print_rmembersihkannya melalui panggilan ituphp_ob_get_buffer

Saya tidak yakin akan ada lagi hal ini. Pastikan Anda menonaktifkan produksi log in, atau menjalankan mod_security untuk mencegah jenis output ini pergi ke halaman.

davidalger
sumber
Terima kasih banyak atas jawaban terperinci ini. Saya harus memulai kembali belajar C dan membaca kode sumber php :)
Fabian Blechschmidt
6

Apa yang ditunjukkan davidalger adalah penting. Objek yang Anda coba masuk terlalu besar dan menyebabkan PHP kehabisan memori. Bergantung pada batas memori Anda dan ukuran blok Anda, Anda mungkin dapat menggunakan:

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

Semua objek yang memperluas Varien_Object dapat menggunakan debug () untuk menampilkan properti _data yang mendasarinya secara rekursif.

Lihat posting blog ini oleh salah satu rekan kerja saya untuk penjelasan lebih rinci.

mybluevan
sumber
2

Dapatkah ini menjadi alasan?

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

"Dari dokumentasi PHP: Ketika parameter return digunakan, fungsi ini menggunakan buffering output internal sehingga tidak dapat digunakan di dalam fungsi panggilan balik ob_start ()." Info lebih lanjut di sini: [php.net/manual/en/function.print-r.php]

ProxiBlue
sumber