OutputBuffering.php 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. <?php /* vim: set expandtab sw=4 ts=4 sts=4: */
  2. /**
  3. * Output buffering wrapper
  4. *
  5. * @package PhpMyAdmin
  6. */
  7. namespace PhpMyAdmin;
  8. /**
  9. * Output buffering wrapper class
  10. *
  11. * @package PhpMyAdmin
  12. */
  13. class OutputBuffering
  14. {
  15. private static $_instance;
  16. private $_mode;
  17. private $_content;
  18. private $_on;
  19. /**
  20. * Initializes class
  21. */
  22. private function __construct()
  23. {
  24. $this->_mode = $this->_getMode();
  25. $this->_on = false;
  26. }
  27. /**
  28. * This function could be used eventually to support more modes.
  29. *
  30. * @return integer the output buffer mode
  31. */
  32. private function _getMode()
  33. {
  34. $mode = 0;
  35. if ($GLOBALS['cfg']['OBGzip'] && function_exists('ob_start')) {
  36. if (ini_get('output_handler') == 'ob_gzhandler') {
  37. // If a user sets the output_handler in php.ini to ob_gzhandler, then
  38. // any right frame file in phpMyAdmin will not be handled properly by
  39. // the browser. My fix was to check the ini file within the
  40. // PMA_outBufferModeGet() function.
  41. $mode = 0;
  42. } elseif (function_exists('ob_get_level') && ob_get_level() > 0) {
  43. // happens when php.ini's output_buffering is not Off
  44. ob_end_clean();
  45. $mode = 1;
  46. } else {
  47. $mode = 1;
  48. }
  49. }
  50. // Zero (0) is no mode or in other words output buffering is OFF.
  51. // Follow 2^0, 2^1, 2^2, 2^3 type values for the modes.
  52. // Useful if we ever decide to combine modes. Then a bitmask field of
  53. // the sum of all modes will be the natural choice.
  54. return $mode;
  55. }
  56. /**
  57. * Returns the singleton OutputBuffering object
  58. *
  59. * @return OutputBuffering object
  60. */
  61. public static function getInstance()
  62. {
  63. if (empty(self::$_instance)) {
  64. self::$_instance = new OutputBuffering();
  65. }
  66. return self::$_instance;
  67. }
  68. /**
  69. * This function will need to run at the top of all pages if output
  70. * output buffering is turned on. It also needs to be passed $mode from
  71. * the PMA_outBufferModeGet() function or it will be useless.
  72. *
  73. * @return void
  74. */
  75. public function start()
  76. {
  77. if (! $this->_on) {
  78. if ($this->_mode && function_exists('ob_gzhandler')) {
  79. ob_start('ob_gzhandler');
  80. }
  81. ob_start();
  82. if (! defined('TESTSUITE')) {
  83. header('X-ob_mode: ' . $this->_mode);
  84. }
  85. register_shutdown_function(
  86. array(OutputBuffering::class, 'stop')
  87. );
  88. $this->_on = true;
  89. }
  90. }
  91. /**
  92. * This function will need to run at the bottom of all pages if output
  93. * buffering is turned on. It also needs to be passed $mode from the
  94. * PMA_outBufferModeGet() function or it will be useless.
  95. *
  96. * @return void
  97. */
  98. public static function stop()
  99. {
  100. $buffer = OutputBuffering::getInstance();
  101. if ($buffer->_on) {
  102. $buffer->_on = false;
  103. $buffer->_content = ob_get_contents();
  104. if (ob_get_length() > 0) {
  105. ob_end_clean();
  106. }
  107. }
  108. }
  109. /**
  110. * Gets buffer content
  111. *
  112. * @return string buffer content
  113. */
  114. public function getContents()
  115. {
  116. return $this->_content;
  117. }
  118. /**
  119. * Flushes output buffer
  120. *
  121. * @return void
  122. */
  123. public function flush()
  124. {
  125. if (ob_get_status() && $this->_mode) {
  126. ob_flush();
  127. } else {
  128. flush();
  129. }
  130. }
  131. }