Last active
December 22, 2015 00:28
-
-
Save arjenschol/6389030 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Fatal error: Cannot destroy active lambda function in /mnt/serve-a-lot_arjen/public_html/php/bug-ob-start-closure/test2.php on line 549 | |
Program received signal SIGSEGV, Segmentation fault. | |
zend_mm_remove_from_free_list (heap=0xf43290, mm_block=0x7ffff6139d60) at /home/arjen/php/php-5.4/php-src/Zend/zend_alloc.c:805 | |
warning: Source file is more recent than executable. | |
805 ZEND_MM_CHECK_TREE(mm_block); | |
(gdb) bt full | |
#0 zend_mm_remove_from_free_list (heap=0xf43290, mm_block=0x7ffff6139d60) at /home/arjen/php/php-5.4/php-src/Zend/zend_alloc.c:805 | |
index = 14 | |
rp = <optimized out> | |
cp = <optimized out> | |
prev = <optimized out> | |
next = 0x7ffff6139d60 | |
#1 0x00000000006fd403 in _zend_mm_free_int (heap=0xf43290, p=0x7ffff6141d30) at /home/arjen/php/php-5.4/php-src/Zend/zend_alloc.c:2106 | |
mm_block = 0x7ffff6139d60 | |
next_block = 0x7ffff6146178 | |
size = 205536 | |
#2 0x000000000071813c in destroy_op_array (op_array=0x7ffff7fc9aa8) at /home/arjen/php/php-5.4/php-src/Zend/zend_opcode.c:381 | |
literal = 0x7ffff6146178 | |
end = 0x7ffff6146178 | |
i = <optimized out> | |
#3 0x000000000072e778 in zend_hash_destroy (ht=0x7ffff7fc1690) at /home/arjen/php/php-5.4/php-src/Zend/zend_hash.c:560 | |
p = 0x7ffff7fc9920 | |
q = 0x7ffff7fc91b8 | |
#4 0x0000000000717ee5 in destroy_zend_class (pce=<optimized out>) at /home/arjen/php/php-5.4/php-src/Zend/zend_opcode.c:296 | |
ce = 0x7ffff7fc1668 | |
#5 0x000000000072d11b in zend_hash_apply_deleter (ht=ht@entry=0xf43bf0, p=p@entry=0xfa9940) at /home/arjen/php/php-5.4/php-src/Zend/zend_hash.c:650 | |
retval = <optimized out> | |
#6 0x000000000072ec69 in zend_hash_reverse_apply (ht=0xf43bf0, apply_func=apply_func@entry=0x712fa0 <clean_non_persistent_class>) | |
at /home/arjen/php/php-5.4/php-src/Zend/zend_hash.c:804 | |
result = 1 | |
p = 0x10ef940 | |
q = 0xfa9940 | |
#7 0x0000000000713609 in shutdown_executor () at /home/arjen/php/php-5.4/php-src/Zend/zend_execute_API.c:303 | |
__orig_bailout = 0x7fffffffe5b0 | |
__bailout = {{__jmpbuf = {15998512, -2946347727049205886, 0, 140737488349847, 0, 0, 2946346250059110274, -2946346671174985854}, | |
__mask_was_saved = 0, __saved_mask = {__val = {0, 0, 0, 140737353793640, 12750417304, 128, 140737353870744, 0, 140737488349847, | |
140737353870696, 17769168, 15976928, 17769168, 15998512, 15998512, 0}}}} | |
#8 0x0000000000721776 in zend_deactivate () at /home/arjen/php/php-5.4/php-src/Zend/zend.c:938 | |
No locals. | |
#9 0x00000000006c5100 in php_request_shutdown (dummy=dummy@entry=0x0) at /home/arjen/php/php-5.4/php-src/main/main.c:1808 | |
report_memleaks = 1 '\001' | |
#10 0x00000000007c6994 in do_cli (argc=3, argv=0x7fffffffe798) at /home/arjen/php/php-5.4/php-src/sapi/cli/php_cli.c:1172 | |
c = <optimized out> | |
file_handle = {type = ZEND_HANDLE_MAPPED, filename = 0x7fffffffea97 "/mnt/serve-a-lot_arjen/public_html/php/bug-ob-start-closure/test2.php", | |
opened_path = 0x0, handle = {fd = -134478856, fp = 0x7ffff7fc03f8, stream = {handle = 0x7ffff7fc03f8, isatty = 0, mmap = {len = 16117, | |
pos = 0, map = 0x7ffff7fec000, buf = 0x7ffff7fec000 <Address 0x7ffff7fec000 out of bounds>, old_handle = 0x10f1df0, | |
old_closer = 0x736710 <zend_stream_stdio_closer>}, reader = 0x736730 <zend_stream_stdio_reader>, | |
fsizer = 0x7366b0 <zend_stream_stdio_fsizer>, closer = 0x736630 <zend_stream_mmap_closer>}}, free_filename = 0 '\000'} | |
behavior = <optimized out> | |
reflection_what = <optimized out> | |
request_started = 1 | |
exit_status = 0 | |
php_optarg = 0x0 | |
php_optind = 3 | |
exec_direct = <optimized out> | |
exec_run = <optimized out> | |
exec_begin = <optimized out> | |
exec_end = <optimized out> | |
arg_free = <optimized out> | |
arg_excp = <optimized out> | |
script_file = <optimized out> | |
translated_path = 0x10f22d0 "/mnt/serve-a-lot_arjen/public_html/php/bug-ob-start-closure/test2.php" | |
interactive = <optimized out> | |
lineno = 1 | |
param_error = <optimized out> | |
hide_argv = <optimized out> | |
#11 0x0000000000428cf8 in main (argc=3, argv=0x7fffffffe798) at /home/arjen/php/php-5.4/php-src/sapi/cli/php_cli.c:1365 | |
---Type <return> to continue, or q <return> to quit--- | |
__orig_bailout = 0x0 | |
__bailout = {{__jmpbuf = {16003568, -2946346248848550014, 1, 0, 15884512, 0, 2946346249700497282, -2946346777465727102}, | |
__mask_was_saved = 0, __saved_mask = {__val = {140737325995136, 140737328163744, 140737354125312, 0, 140737354130568, 140737488348752, | |
140737488348736, 4131212846, 4270962, 4294967295, 140737488349112, 140737328251304, 140737353943456, 140737354129712, 0, 1}}}} | |
c = <optimized out> | |
exit_status = 0 | |
module_started = 1 | |
sapi_started = 1 | |
php_optarg = 0x0 | |
php_optind = 2 | |
use_extended_info = 1 | |
ini_path_override = 0x0 | |
ini_entries = 0xf431f0 "html_errors=0\nregister_argc_argv=1\nimplicit_flush=1\noutput_buffering=0\nmax_execution_time=0\nmax_input_time=-1\n" | |
ini_entries_len = <optimized out> | |
ini_ignore = 0 | |
sapi_module = <optimized out> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
function ciao() | |
{ | |
$out = '<pre>'; | |
$args = func_get_args(); | |
if(!empty($args)) | |
{ | |
// var_export() causes fatal errors on recursion... | |
ob_start(); | |
ini_set('xdebug.var_display_max_depth', 4); | |
var_dump($args); | |
$out .= ob_get_contents()."\n\n"; | |
ob_end_clean(); | |
} | |
$out .= get_backtrace(1); | |
die($out); | |
} | |
class A { | |
function B() | |
{ | |
while (ob_get_level() > 1) | |
ob_end_flush(); | |
// store possible trailing content | |
$content = ob_get_clean(); | |
// start an output buffer which cannot be flushed (3rd parameter is false) | |
// callback function get all output and corrects Content-Length header | |
ob_start(function($buffer) { | |
ciao($buffer); | |
}, 0, false); | |
} | |
} | |
$a = new A; | |
$a->B(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
class FirePHP { | |
/** | |
* Gets singleton instance of FirePHP | |
* | |
* @param boolean $AutoCreate | |
* @return FirePHP | |
*/ | |
public static function getInstance($AutoCreate=false) { | |
if($AutoCreate===true && !self::$instance) { | |
self::init(); | |
} | |
return self::$instance; | |
} | |
/** | |
* Creates FirePHP object and stores it for singleton access | |
* | |
* @return FirePHP | |
*/ | |
public static function init() { | |
return self::$instance = new self(); | |
} | |
/** | |
* Enable and disable logging to Firebug | |
* | |
* @param boolean $Enabled TRUE to enable, FALSE to disable | |
* @return void | |
*/ | |
public function setEnabled($Enabled) { | |
$this->enabled = $Enabled; | |
} | |
/** | |
* Check if logging is enabled | |
* | |
* @return boolean TRUE if enabled | |
*/ | |
public function getEnabled() { | |
return $this->enabled; | |
} | |
/** | |
* Specify a filter to be used when encoding an object | |
* | |
* Filters are used to exclude object members. | |
* | |
* @param string $Class The class name of the object | |
* @param array $Filter An array or members to exclude | |
* @return void | |
*/ | |
public function setObjectFilter($Class, $Filter) { | |
$this->objectFilters[$Class] = $Filter; | |
} | |
/** | |
* Register FirePHP as your error handler | |
* | |
* Will throw exceptions for each php error. | |
*/ | |
public function registerErrorHandler() | |
{ | |
//NOTE: The following errors will not be caught by this error handler: | |
// E_ERROR, E_PARSE, E_CORE_ERROR, | |
// E_CORE_WARNING, E_COMPILE_ERROR, | |
// E_COMPILE_WARNING, E_STRICT | |
set_error_handler(array($this,'errorHandler')); | |
} | |
/** | |
* FirePHP's error handler | |
* | |
* Throws exception for each php error that will occur. | |
* | |
* @param int $errno | |
* @param string $errstr | |
* @param string $errfile | |
* @param int $errline | |
* @param array $errcontext | |
*/ | |
public function errorHandler($errno, $errstr, $errfile, $errline, $errcontext) | |
{ | |
// Don't throw exception if error reporting is switched off | |
if (error_reporting() == 0) { | |
return; | |
} | |
// Only throw exceptions for errors we are asking for | |
if (error_reporting() & $errno) { | |
throw new ErrorException($errstr, 0, $errno, $errfile, $errline); | |
} | |
} | |
/** | |
* Register FirePHP as your exception handler | |
*/ | |
public function registerExceptionHandler() | |
{ | |
set_exception_handler(array($this,'exceptionHandler')); | |
} | |
/** | |
* FirePHP's exception handler | |
* | |
* Logs all exceptions to your firebug console and then stops the script. | |
* | |
* @param Exception $Exception | |
* @throws Exception | |
*/ | |
function exceptionHandler($Exception) { | |
$this->fb($Exception); | |
} | |
/** | |
* Set custom processor url for FirePHP | |
* | |
* @param string $URL | |
*/ | |
public function setProcessorUrl($URL) | |
{ | |
$this->setHeader('X-FirePHP-ProcessorURL', $URL); | |
} | |
/** | |
* Set custom renderer url for FirePHP | |
* | |
* @param string $URL | |
*/ | |
public function setRendererUrl($URL) | |
{ | |
$this->setHeader('X-FirePHP-RendererURL', $URL); | |
} | |
/** | |
* Start a group for following messages | |
* | |
* @param string $Name | |
* @return true | |
* @throws Exception | |
*/ | |
public function group($Name) { | |
return $this->fb(null, $Name, FirePHP::GROUP_START); | |
} | |
/** | |
* Ends a group you have started before | |
* | |
* @return true | |
* @throws Exception | |
*/ | |
public function groupEnd() { | |
return $this->fb(null, null, FirePHP::GROUP_END); | |
} | |
/** | |
* Log object with label to firebug console | |
* | |
* @see FirePHP::LOG | |
* @param mixes $Object | |
* @param string $Label | |
* @return true | |
* @throws Exception | |
*/ | |
public function log($Object, $Label=null) { | |
return $this->fb($Object, $Label, FirePHP::LOG); | |
} | |
/** | |
* Log object with label to firebug console | |
* | |
* @see FirePHP::INFO | |
* @param mixes $Object | |
* @param string $Label | |
* @return true | |
* @throws Exception | |
*/ | |
public function info($Object, $Label=null) { | |
return $this->fb($Object, $Label, FirePHP::INFO); | |
} | |
/** | |
* Log object with label to firebug console | |
* | |
* @see FirePHP::WARN | |
* @param mixes $Object | |
* @param string $Label | |
* @return true | |
* @throws Exception | |
*/ | |
public function warn($Object, $Label=null) { | |
return $this->fb($Object, $Label, FirePHP::WARN); | |
} | |
/** | |
* Log object with label to firebug console | |
* | |
* @see FirePHP::ERROR | |
* @param mixes $Object | |
* @param string $Label | |
* @return true | |
* @throws Exception | |
*/ | |
public function error($Object, $Label=null) { | |
return $this->fb($Object, $Label, FirePHP::ERROR); | |
} | |
/** | |
* Dumps key and variable to firebug server panel | |
* | |
* @see FirePHP::DUMP | |
* @param string $Key | |
* @param mixed $Variable | |
* @return true | |
* @throws Exception | |
*/ | |
public function dump($Key, $Variable) { | |
return $this->fb($Variable, $Key, FirePHP::DUMP); | |
} | |
/** | |
* Log a trace in the firebug console | |
* | |
* @see FirePHP::TRACE | |
* @param string $Label | |
* @return true | |
* @throws Exception | |
*/ | |
public function trace($Label) { | |
return $this->fb($Label, FirePHP::TRACE); | |
} | |
public function table($Label, $Table) { | |
return $this->fb($Table, $Label, FirePHP::TABLE); | |
} | |
public function detectClientExtension() { | |
/* Check if FirePHP is installed on client */ | |
if(!@preg_match_all('/\sFirePHP\/([\.|\d]*)\s?/si',$this->getUserAgent(),$m) || | |
!version_compare($m[1][0],'0.0.6','>=')) { | |
return false; | |
} | |
return true; | |
} | |
public function fb($Object) { | |
if(!$this->enabled) { | |
return false; | |
} | |
if (headers_sent($filename, $linenum)) { | |
throw $this->newException('Headers already sent in '.$filename.' on line '.$linenum.'. Cannot send log data to FirePHP. You must have Output Buffering enabled via ob_start() or output_buffering ini directive.'); | |
} | |
$Type = null; | |
$Label = null; | |
if(func_num_args()==1) { | |
} else | |
if(func_num_args()==2) { | |
switch(func_get_arg(1)) { | |
case self::LOG: | |
case self::INFO: | |
case self::WARN: | |
case self::ERROR: | |
case self::DUMP: | |
case self::TRACE: | |
case self::EXCEPTION: | |
case self::TABLE: | |
case self::GROUP_START: | |
case self::GROUP_END: | |
$Type = func_get_arg(1); | |
break; | |
default: | |
$Label = func_get_arg(1); | |
break; | |
} | |
} else | |
if(func_num_args()==3) { | |
$Type = func_get_arg(2); | |
$Label = func_get_arg(1); | |
} else { | |
throw $this->newException('Wrong number of arguments to fb() function!'); | |
} | |
if(!$this->detectClientExtension()) { | |
return false; | |
} | |
$meta = array(); | |
$skipFinalObjectEncode = false; | |
if($Object instanceof Exception) { | |
$meta['file'] = $this->_escapeTraceFile($Object->getFile()); | |
$meta['line'] = $Object->getLine(); | |
$trace = $Object->getTrace(); | |
if($Object instanceof ErrorException | |
&& isset($trace[0]['function']) | |
&& $trace[0]['function']=='errorHandler' | |
&& isset($trace[0]['class']) | |
&& $trace[0]['class']=='FirePHP') { | |
$severity = false; | |
switch($Object->getSeverity()) { | |
case E_WARNING: $severity = 'E_WARNING'; break; | |
case E_NOTICE: $severity = 'E_NOTICE'; break; | |
case E_USER_ERROR: $severity = 'E_USER_ERROR'; break; | |
case E_USER_WARNING: $severity = 'E_USER_WARNING'; break; | |
case E_USER_NOTICE: $severity = 'E_USER_NOTICE'; break; | |
case E_STRICT: $severity = 'E_STRICT'; break; | |
case E_RECOVERABLE_ERROR: $severity = 'E_RECOVERABLE_ERROR'; break; | |
case E_DEPRECATED: $severity = 'E_DEPRECATED'; break; | |
case E_USER_DEPRECATED: $severity = 'E_USER_DEPRECATED'; break; | |
} | |
$Object = array('Class'=>get_class($Object), | |
'Message'=>$severity.': '.$Object->getMessage(), | |
'File'=>$this->_escapeTraceFile($Object->getFile()), | |
'Line'=>$Object->getLine(), | |
'Type'=>'trigger', | |
'Trace'=>$this->_escapeTrace(array_splice($trace,2))); | |
$skipFinalObjectEncode = true; | |
} else { | |
$Object = array('Class'=>get_class($Object), | |
'Message'=>$Object->getMessage(), | |
'File'=>$this->_escapeTraceFile($Object->getFile()), | |
'Line'=>$Object->getLine(), | |
'Type'=>'throw', | |
'Trace'=>$this->_escapeTrace($trace)); | |
$skipFinalObjectEncode = true; | |
} | |
$Type = self::EXCEPTION; | |
} else | |
if($Type==self::TRACE) { | |
$trace = debug_backtrace(); | |
if(!$trace) return false; | |
for( $i=0 ; $i<sizeof($trace) ; $i++ ) { | |
if(isset($trace[$i]['class']) | |
&& isset($trace[$i]['file']) | |
&& ($trace[$i]['class']=='FirePHP' | |
|| $trace[$i]['class']=='FB') | |
&& (substr($this->_standardizePath($trace[$i]['file']),-18,18)=='FirePHPCore/fb.php' | |
|| substr($this->_standardizePath($trace[$i]['file']),-29,29)=='FirePHPCore/FirePHP.class.php')) { | |
/* Skip - FB::trace(), FB::send(), $firephp->trace(), $firephp->fb() */ | |
} else | |
if(isset($trace[$i]['class']) | |
&& isset($trace[$i+1]['file']) | |
&& $trace[$i]['class']=='FirePHP' | |
&& substr($this->_standardizePath($trace[$i+1]['file']),-18,18)=='FirePHPCore/fb.php') { | |
/* Skip fb() */ | |
} else | |
if($trace[$i]['function']=='fb' | |
|| $trace[$i]['function']=='trace' | |
|| $trace[$i]['function']=='send') { | |
$Object = array('Class'=>isset($trace[$i]['class'])?$trace[$i]['class']:'', | |
'Type'=>isset($trace[$i]['type'])?$trace[$i]['type']:'', | |
'Function'=>isset($trace[$i]['function'])?$trace[$i]['function']:'', | |
'Message'=>$trace[$i]['args'][0], | |
'File'=>isset($trace[$i]['file'])?$this->_escapeTraceFile($trace[$i]['file']):'', | |
'Line'=>isset($trace[$i]['line'])?$trace[$i]['line']:'', | |
'Args'=>isset($trace[$i]['args'])?$this->encodeObject($trace[$i]['args']):'', | |
'Trace'=>$this->_escapeTrace(array_splice($trace,$i+1))); | |
$skipFinalObjectEncode = true; | |
$meta['file'] = isset($trace[$i]['file'])?$this->_escapeTraceFile($trace[$i]['file']):''; | |
$meta['line'] = isset($trace[$i]['line'])?$trace[$i]['line']:''; | |
break; | |
} | |
} | |
} else | |
if($Type==self::TABLE) { | |
if(isset($Object[0]) && is_string($Object[0])) { | |
$Object[1] = $this->encodeTable($Object[1]); | |
} else { | |
$Object = $this->encodeTable($Object); | |
} | |
$skipFinalObjectEncode = true; | |
} else { | |
if($Type===null) { | |
$Type = self::LOG; | |
} | |
} | |
if($this->options['includeLineNumbers']) { | |
if(!isset($meta['file']) || !isset($meta['line'])) { | |
$trace = debug_backtrace(); | |
for( $i=0 ; $trace && $i<sizeof($trace) ; $i++ ) { | |
if(isset($trace[$i]['class']) | |
&& isset($trace[$i]['file']) | |
&& ($trace[$i]['class']=='FirePHP' | |
|| $trace[$i]['class']=='FB') | |
&& (substr($this->_standardizePath($trace[$i]['file']),-18,18)=='FirePHPCore/fb.php' | |
|| substr($this->_standardizePath($trace[$i]['file']),-29,29)=='FirePHPCore/FirePHP.class.php')) { | |
/* Skip - FB::trace(), FB::send(), $firephp->trace(), $firephp->fb() */ | |
} else | |
if(isset($trace[$i]['class']) | |
&& isset($trace[$i+1]['file']) | |
&& $trace[$i]['class']=='FirePHP' | |
&& substr($this->_standardizePath($trace[$i+1]['file']),-18,18)=='FirePHPCore/fb.php') { | |
/* Skip fb() */ | |
} else | |
if(isset($trace[$i]['file']) | |
&& substr($this->_standardizePath($trace[$i]['file']),-18,18)=='FirePHPCore/fb.php') { | |
/* Skip FB::fb() */ | |
} else { | |
$meta['file'] = isset($trace[$i]['file'])?$this->_escapeTraceFile($trace[$i]['file']):''; | |
$meta['line'] = isset($trace[$i]['line'])?$trace[$i]['line']:''; | |
break; | |
} | |
} | |
} | |
} else { | |
unset($meta['file']); | |
unset($meta['line']); | |
} | |
$this->setHeader('X-Wf-Protocol-1','http://meta.wildfirehq.org/Protocol/JsonStream/0.2'); | |
$this->setHeader('X-Wf-1-Plugin-1','http://meta.firephp.org/Wildfire/Plugin/FirePHP/Library-FirePHPCore/'.self::VERSION); | |
$structure_index = 1; | |
if($Type==self::DUMP) { | |
$structure_index = 2; | |
$this->setHeader('X-Wf-1-Structure-2','http://meta.firephp.org/Wildfire/Structure/FirePHP/Dump/0.1'); | |
} else { | |
$this->setHeader('X-Wf-1-Structure-1','http://meta.firephp.org/Wildfire/Structure/FirePHP/FirebugConsole/0.1'); | |
} | |
if($Type==self::DUMP) { | |
$msg = '{"'.$Label.'":'.$this->jsonEncode($Object, $skipFinalObjectEncode).'}'; | |
} else { | |
$msg_meta = array('Type'=>$Type); | |
if($Label!==null) { | |
$msg_meta['Label'] = $Label; | |
} | |
if(isset($meta['file'])) { | |
$msg_meta['File'] = $meta['file']; | |
} | |
if(isset($meta['line'])) { | |
$msg_meta['Line'] = $meta['line']; | |
} | |
$msg = '['.$this->jsonEncode($msg_meta).','.$this->jsonEncode($Object, $skipFinalObjectEncode).']'; | |
} | |
$parts = explode("\n",chunk_split($msg, 5000, "\n")); | |
for( $i=0 ; $i<count($parts) ; $i++) { | |
$part = $parts[$i]; | |
if ($part) { | |
if(count($parts)>2) { | |
// Message needs to be split into multiple parts | |
$this->setHeader('X-Wf-1-'.$structure_index.'-'.'1-'.$this->messageIndex, | |
(($i==0)?strlen($msg):'') | |
. '|' . $part . '|' | |
. (($i<count($parts)-2)?'\\':'')); | |
} else { | |
$this->setHeader('X-Wf-1-'.$structure_index.'-'.'1-'.$this->messageIndex, | |
strlen($part) . '|' . $part . '|'); | |
} | |
$this->messageIndex++; | |
if ($this->messageIndex > 99999) { | |
throw new Exception('Maximum number (99,999) of messages reached!'); | |
} | |
} | |
} | |
$this->setHeader('X-Wf-1-Index',$this->messageIndex-1); | |
return true; | |
} | |
protected function _standardizePath($Path) { | |
} | |
protected function _escapeTrace($Trace) { | |
if(!$Trace) return $Trace; | |
for( $i=0 ; $i<sizeof($Trace) ; $i++ ) { | |
if(isset($Trace[$i]['file'])) { | |
$Trace[$i]['file'] = $this->_escapeTraceFile($Trace[$i]['file']); | |
} | |
if(isset($Trace[$i]['args'])) { | |
$Trace[$i]['args'] = $this->encodeObject($Trace[$i]['args']); | |
} | |
} | |
return $Trace; | |
} | |
protected function _escapeTraceFile($File) { | |
/* Check if we have a windows filepath */ | |
if(strpos($File,'\\')) { | |
/* First strip down to single \ */ | |
$file = preg_replace('/\\\\+/','\\',$File); | |
return $file; | |
} | |
return $File; | |
} | |
protected function setHeader($Name, $Value) { | |
return header($Name.': '.$Value); | |
} | |
protected function getUserAgent() { | |
if(!isset($_SERVER['HTTP_USER_AGENT'])) return false; | |
return $_SERVER['HTTP_USER_AGENT']; | |
} | |
} | |
function ciao() | |
{ | |
$out = '<pre>'; | |
$args = func_get_args(); | |
if(!empty($args)) | |
{ | |
// var_export() causes fatal errors on recursion... | |
ob_start(); | |
ini_set('xdebug.var_display_max_depth', 4); | |
var_dump($args); | |
$out .= ob_get_contents()."\n\n"; | |
ob_end_clean(); | |
} | |
$out .= get_backtrace(1); | |
die($out); | |
} | |
class A { | |
function B() | |
{ | |
while (ob_get_level() > 1) | |
ob_end_flush(); | |
// store possible trailing content | |
$content = ob_get_clean(); | |
// start an output buffer which cannot be flushed (3rd parameter is false) | |
// callback function get all output and corrects Content-Length header | |
ob_start(function($buffer) { | |
ciao($buffer); | |
}, 0, false); | |
} | |
} | |
$a = new A; | |
$a->B(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment