/** * アプリケーションログを記録 * * <pre> * アプリケーションログを記録します。 * このログは画面上で確認できる一時的なスクリーンログです。 * </pre> * * @param string $logKey ログキー * @param mixed $logValue 値 * * @return void */ public function log($logKey, $logValue = null) { if ($this->_config['debug'] !== true) { return; } $this->_logs[][$logKey] = $logValue; $showFirePHP = isset($_GET['_firelog']) || array_search($logKey, $this->_fbKeys) !== false; if (class_exists('FB', false) && $showFirePHP) { $color = $logValue ? 'black' : 'grey'; FB::group($logKey, array('Collapsed' => true, 'Color' => $color)); FB::log($logValue); FB::groupEnd(); } if (!is_scalar($logValue)) { $logValue = print_r($logValue, true); $logValue = str_replace("\n", '', $logValue); $logValue = preg_replace("/\\s+/s", " ", $logValue); } }
/** * onAfterInitialise handler * * Register FirePHP libraries and set options according to paramters * * @access public * @return null */ public function onAfterInitialise() { require_once 'jfirephp' . DS . 'firephpcore' . DS . 'fb.php'; // JFirePHP is installed and loaed define('JFIREPHP', 1); // Before doing any checks lets disable logging FB::setEnabled(false); // Check if the integration is set to enabled $enable = (bool) $this->params->get('enable', 0); // Only turn on if enabled if ($enable) { // if limited to debug mode, check JDEBUG $limittodebug = (bool) $this->params->get('limittodebug', 1); if ($limittodebug == false || JDEBUG) { // We are enabled and either in Debug mode, or it does not matter FB::setEnabled(true); $verbose = (bool) $this->params->get('verbose', 0); if ($verbose) { FB::group('JFirePHP Startup', array('Collapsed' => true, 'Color' => '#FF4000')); FB::log('JFirePHP enabled! - Verbose Output Mode: ON'); } $options = array('maxObjectDepth' => intval($this->params->get('maxObjectDepth', 10)), 'maxArrayDepth' => intval($this->params->get('maxArrayDepth', 20)), 'useNativeJsonEncode' => intval($this->params->get('useNativeJsonEncode', 1)), 'includeLineNumbers' => intval($this->params->get('includeLineNumbers', 1))); FB::setOptions($options); if ($verbose) { FB::log('JFirePHP: Options Set - maxObjectDepth:' . $options['maxObjectDepth'] . ' maxArrayDepth:' . $options['maxArrayDepth'] . ' useNativeJsonEncode:' . $options['useNativeJsonEncode'] . ' includeLineNumbers:' . $options['includeLineNumbers']); } $redirectphp = (bool) $this->params->get('redirectphp', 0); if ($redirectphp) { // Convert E_WARNING, E_NOTICE, E_USER_ERROR, E_USER_WARNING, E_USER_NOTICE and // E_RECOVERABLE_ERROR errors to ErrorExceptions and send all Exceptions to Firebug automatically FB::registerErrorHandler(true); FB::registerExceptionHandler(); FB::registerAssertionHandler(true, false); if ($verbose) { FB::log('JFirePHP: E_WARNING, E_NOTICE, E_USER_ERROR, E_USER_WARNING, E_USER_NOTICE and E_RECOVERABLE_ERROR redirected.'); } } if ($verbose) { FB::groupEnd(); } } } }
public static function OutputDatabaseProfile(QDatabaseBase $objDb = null) { if ($objDb == null) { $objDb = QApplication::$Database[1]; } if ($objDb->EnableProfiling) { $objProfileArray = $objDb->Profile; $intCount = count($objProfileArray) / 2; if ($intCount == 0) { parent::log(QApplication::Translate('No queries were performed.')); } else { if ($intCount == 1) { parent::log(QApplication::Translate('1 query was performed.')); } else { $log = sprintf(QApplication::Translate('%s queries were performed.'), $intCount); parent::log($log); } } for ($intIndex = 0; $intIndex < count($objProfileArray); $intIndex++) { $objDebugBacktrace = $objProfileArray[$intIndex]['objBacktrace']; $strQuery = $objProfileArray[$intIndex]['strQuery']; $dblTimeInfo = $objProfileArray[$intIndex]['dblTimeInfo']; $objArgs = array_key_exists('args', $objDebugBacktrace) ? $objDebugBacktrace['args'] : array(); $strClass = array_key_exists('class', $objDebugBacktrace) ? $objDebugBacktrace['class'] : null; $strType = array_key_exists('type', $objDebugBacktrace) ? $objDebugBacktrace['type'] : null; $strFunction = array_key_exists('function', $objDebugBacktrace) ? $objDebugBacktrace['function'] : null; $strFile = array_key_exists('file', $objDebugBacktrace) ? $objDebugBacktrace['file'] : null; $strLine = array_key_exists('line', $objDebugBacktrace) ? $objDebugBacktrace['line'] : null; $called = QApplication::Translate('Called by') . ' ' . $strClass . $strType . $strFunction . '(' . implode(', ', $objArgs) . ')'; parent::group($called); $file = $strFile . ' ' . QApplication::Translate('Line') . ': ' . $strLine; parent::log($file, QApplication::Translate('File')); parent::log($strQuery, QApplication::Translate('Query')); parent::log($dblTimeInfo, QApplication::Translate('Time Info')); parent::groupEnd(); } } else { parent::log(QApplication::Translate('Profiling was not enabled for this database connection. To enable, ensure that ENABLE_PROFILING is set to TRUE.')); } }
/** * (non-PHPdoc) * @see debugObject::msg() */ public function msg($msg, $level = DEBUG_LOG) { if (!empty($msg) && $this->_level & $level) { if (DEBUG_INFO & $level) { if (is_array($msg)) { FB::group(current($msg), array('Collapsed' => true)); FB::info($msg); FB::groupEnd(); } else { FB::info($msg); } } elseif (DEBUG_ERROR & $level || DEBUG_STRICT & $level) { if (is_array($msg)) { FB::group(current($msg), array('Collapsed' => true, 'Color' => '#FF0000')); FB::error($msg); FB::groupEnd(); } else { FB::error($msg); } } elseif (DEBUG_WARNING & $level) { if (is_array($msg)) { FB::group(current($msg), array('Collapsed' => true, 'Color' => '#FF0000')); FB::warn($msg); FB::groupEnd(); } else { FB::warn($msg); } } else { if (is_array($msg)) { FB::group(current($msg), array('Collapsed' => true)); FB::log($msg); FB::groupEnd(); } else { FB::log($msg); } } } }
/** * Loads the class variable with * * @return void * @access public */ public function getImages() { FB::group("Image Loading Data"); FB::send($this->dir, "Directory"); if (($cache = Utilities::check_cache($this->dir)) !== FALSE) { $this->_imageArray = $cache; } else { if (is_dir($this->dir)) { // Open the directory for reading if ($folder = opendir($this->dir)) { // Loop through the files in the directory while (($file = readdir($folder)) !== FALSE) { /* * Verifies that the current value of $file * refers to an existing file and that the * file is big enough not to throw an error. */ if (is_file($this->dir . $file) && is_readable($this->dir . $file) && filesize($this->dir . $file) > 11) { // Verify that the file is an image //XXX Add EXIF check and fallback if (exif_imagetype($this->dir . $file) !== FALSE) { FB::send("The file is an image. Added to array."); // Adds the image to the array $this->_imageArray[] = $file; } } } // Sort the images according using natural sorting natsort($this->_imageArray); FB::send($this->_imageArray, "Image Array"); Utilities::save_cache($this->dir, $this->_imageArray); } } } FB::groupEnd(); }
/** * Debug print 'v' for CLI * * @param mixed $values $values1, $values2 ... * * @return void */ function v($values = null) { static $paramNum = 0; // be recursive $args = func_get_args(); if (count($args) > 1) { foreach ($args as $arg) { p($arg); } } $trace = debug_backtrace(); $i = $trace[0]['file'] === __FILE__ ? 1 : 0; $file = $trace[$i]['file']; $line = $trace[$i]['line']; $includePath = explode(":", get_include_path()); // remove if include_path exists foreach ($includePath as $var) { if ($var != '.') { $file = str_replace("{$var}/", '', $file); } } $method = isset($trace[1]['class']) ? " ({$trace[1]['class']}" . '::' . "{$trace[1]['function']})" : ''; $fileArray = file($file, FILE_USE_INCLUDE_PATH); $p = trim($fileArray[$line - 1]); unset($fileArray); $funcName = __FUNCTION__; preg_match("/{$funcName}\\((.+)[\\s,\\)]/is", $p, $matches); $varName = isset($matches[1]) ? $matches[1] : ''; // for mulitple arg names $varNameArray = explode(',', $varName); if (count($varNameArray) === 1) { $paramNum = 0; $varName = $varNameArray[0]; } else { $varName = $varNameArray[$paramNum]; if ($paramNum === count($varNameArray) - 1) { var_dump($_ENV); $paramNum = 0; } else { $paramNum++; } } $label = "{$varName} in {$file} on line {$line}{$method}"; if (strlen(serialize($values)) > 1000000) { $ouputMode = 'dump'; } $label = is_object($values) ? ucwords(get_class($values)) . " {$label}" : $label; // if CLI if (PHP_SAPI === 'cli') { $colorOpenReverse = "[7;32m"; $colorOpenBold = "[1;32m"; $colorOpenPlain = "[0;32m"; $colorClose = "[0m"; echo $colorOpenReverse . "{$varName}" . $colorClose . " = "; var_dump($values); echo $colorOpenPlain . "in {$colorOpenBold}{$file}{$colorClose}{$colorOpenPlain} on line {$line}{$method}" . $colorClose . "\n"; return; } $labelField = '<fieldset style="color:#4F5155; border:1px solid black;padding:2px;width:10px;">'; $labelField .= '<legend style="color:black;font-size:9pt;font-weight:bold;font-family:Verdana,'; $labelField .= 'Arial,,SunSans-Regular,sans-serif;">' . $label . '</legend>'; if (class_exists('FB', false)) { $label = 'p() in ' . $trace[0]['file'] . ' on line ' . $trace[0]['line']; FB::group($label); FB::error($values); FB::groupEnd(); return; } $pre = "<pre style=\"text-align: left;margin: 0px 0px 10px 0px; display: block; background: white; color: black; "; $pre .= "border: 1px solid #cccccc; padding: 5px; font-size: 12px; \">"; if ($varName != FALSE) { $pre .= "<span style='color: #660000;'>" . $varName . '</span>'; } $pre .= "<span style='color: #660000;'>" . htmlspecialchars($varName) . "</span>"; $post = ' ' . "in <span style=\"color:gray\">{$file}</span> on line {$line}{$method}"; echo $pre; var_dump($values); echo $post; }
/** * 最後のエラーを取得 * * <pre> * _errorクエリーで最後のエラーを表示させます。 * エラー表示がうまく行かない時に使用します。 * </pre> * * <code> * ?_error エラー表示 * ?_error=koriyama@bear-project.net エラーメール送信 * ?_error=/tmp/error.log エラーログファイルを書き込み * </code> * * @return void */ public static function onShutdownDebug() { if (function_exists('FB')) { $errors = Panda::getOuterPathErrors(); FB::group('errors', array('Collapsed' => true, 'Color' => 'gray')); foreach ($errors as $code => $error) { switch (true) { case $code == E_WARNING || $code == E_USER_WARNING: $fireLevel = FirePHP::WARN; break; case $code == E_NOTICE || $code == E_USER_NOTICE: $fireLevel = FirePHP::INFO; break; case $code == E_STRICT || $code == E_DEPRECATED: $fireLevel = FirePHP::LOG; break; default: $fireLevel = FirePHP::ERROR; break; } FB::send($error, '', $fireLevel); } FB::groupEnd(); } $lastError = error_get_last(); $err = print_r($lastError, true); if (isset($_GET['_error'])) { $errorTo = $_GET['_error']; if ($errorTo == '') { $errorCode = Panda::$phpError[$lastError['type']]; Panda::error("{$errorCode} (Last Error)", "{$lastError['message']}", '', (array) $lastError); return; } elseif (strpos($errorTo, '@')) { error_log($err, 1, $errorTo); } elseif (is_writable(dirname($errorTo))) { error_log("{$err}\n\n", 3, $errorTo); } else { echo "<p style=\"color:red\">Error: Invalid destination for _error [{$errorTo}]</p>"; } } }
public function OnGroupEnter($label) { $this->grouptime[] = microtime(true); \FB::group($label); }
<?php FB::group('Test Group'); FB::send('Hello World'); FB::groupEnd(); FB::log('Log Message'); FB::info('Info Message'); FB::warn('Info Message'); FB::error('Info Message'); FB::trace('Trace to here'); FB::send('Trace to here', FirePHP::TRACE); FB::table('2 SQL queries took 0.06 seconds', array(array('SQL Statement', 'Time', 'Result'), array('SELECT * FROM Foo', '0.02', array('row1', 'row2')), array('SELECT * FROM Bar', '0.04', array('row1', 'row2')))); FB::dump('PHP Version', phpversion());
/** * Output for FirePHP * @uses http://www.firephp.org * * @return void */ public static function firePHP() { echo "<pre>"; // 页面汇总信息 $table = array(); $table[] = array('Total Time: ' . round(microtime(true) - $GLOBALS['_START_TIME'], 3)); $table[] = array('Total Memory: ' . self::_size(round(memory_get_usage() - $GLOBALS['_START_MEM'], 3))); $table[] = array('Timezone: ' . date_default_timezone_get()); isset($_SERVER['SERVER_ADDR']) && ($table[] = array('Server IP: ' . $_SERVER['SERVER_ADDR'])); isset($_SERVER['HTTP_HOST']) && ($table[] = array('Server Host: ' . $_SERVER['HTTP_HOST'])); FB::table('Debug Info', $table); // SQL if (isset($GLOBALS['_SQLs']) && !empty($GLOBALS['_SQLs'])) { // SQL Info $table = array(); $table[] = array('Elapse', 'Host', 'Database', 'SQL', 'Params', 'RealSQL'); foreach ($GLOBALS['_SQLs'] as $v) { $elapsed = round($v['time'] * 1000, 3); // SQL 耗时 if ($v['params']) { $table[] = array($elapsed . 'ms', $v['host'], $v['dbName'], $v['sql'], $v['params'], $v['realSql']); } else { $table[] = array($elapsed . 'ms', $v['host'], $v['dbName'], $v['sql']); } } FB::table('SQL Info (' . count($GLOBALS['_SQLs']) . ' SQLs)', $table); // SQL Explain if (DEBUG_EXPLAIN_SQL) { $titles = array('id', 'select_type', 'table', 'type', 'possible_keys', 'key', 'key_len', 'ref', 'rows', 'Extra', 'sql'); $table = array($titles); foreach ($GLOBALS['_SQLs'] as $v) { if ($v['explain']) { $line = array(); foreach ($titles as $title) { $line[] = isset($v['explain'][$title]) ? $v['explain'][$title] : '-'; } $table[] = $line; } } FB::table('SQL Explain', $table); } } // 引入文件 /* if ($files = get_included_files()) { $table = array(); foreach ($files as $file) { $table[] = array($file); } FB::table('Included Files (' . count($files) . ' PHP files)', $table); } */ print_r($table); // 全局变量、预定义变量 FB::group('Predefined Variables', array('Collapsed' => true)); FB::info($_COOKIE, '_COOKIE'); FB::info($_ENV, '_ENV'); FB::info($_FILES, '_FILES'); FB::info($_GET, '_GET'); FB::info($_POST, '_POST'); FB::info($_REQUEST, '_REQUEST'); FB::info($_SERVER, '_SERVER'); isset($_SESSION) && FB::info($_SESSION, '_SESSION'); FB::groupEnd(); }
private static function sendToFirebug() { $num_errors = count(self::$instance->errors); if ($num_errors == 1) { $msg = 'A PHP error have occured @ ' . date('g:i:s a'); } else { $msg = $num_errors . ' PHP errors have occured @ ' . date('g:i:s a'); } FB::group($msg, array('Collapsed' => self::$firebug_collapsed)); foreach (self::$instance->errors as $err) { // some processing needs to be done to the errmsg because it can // at times contain html, which we don't want in firebug. if ($err['exception'] === false) { FB::error(self::$error_lookup[$err['number']] . ': ' . strip_tags(html_entity_decode($err['message'], ENT_QUOTES)) . ': ' . $err['file'] . ' on line: ' . $err['line']); } else { FB::error('Uncaught Exception: ' . $err['exception'] . '[' . $err['number'] . ']: ' . strip_tags(html_entity_decode($err['message'], ENT_QUOTES)) . ': ' . $err['file'] . ' on line: ' . $err['line']); } if (count($err['trace']) > 0) { FB::log("Trace:"); foreach ($err['trace'] as $i => $t) { FB::log($t['class'] . $t['type'] . $t['function'] . '(' . implode(', ', $t['args']) . ') in file ' . $t['file'] . ' on line: ' . $t['line'], $i + 1); } } FB::log(""); } FB::groupEnd(); }
/** * リソースのデバック表示 * * firePHPコンソールにリソースを表示します。 * * @param BEAR_Ro $ro リソースオブジェクト * * @return void */ public function debugShowResource(BEAR_Ro $ro) { $config = $ro->getConfig(); if (!isset($config['method'])) { return; } $labelUri = "[resource] {$config['method']} {$config['uri']}"; $labelUri .= $config['values'] ? '?' . http_build_query($config['values']) : ""; $body = $ro->getBody(); if (is_array($body) && isset($body[0]) && is_array($body[0])) { // bodyが表構造と仮定 $table = array(); $table[] = array_values(array_keys($body[0])); foreach ((array) $body as $key => $val) { $table[] = array_values((array) $val); } FB::table($labelUri, $table); } else { FB::group("{$labelUri}", array('Collapsed' => true)); FB::log($body); FB::groupEnd(); } }
/** * Debug output * * <code> * Panda_Debug::p * 出力モードを指定して変数を出力します * </code> * * @param mixed $values any values * @param string $ouputMode 'var' | 'export' | 'syslog' | 'fire' dafult is 'print_a' * @param array $options options * * @return void */ public static function p($values = '', $ouputMode = null, array $options = array()) { if (!self::$enable) { return; } if (isset($options['return']) && $options['return'] === true) { ob_start(); } // Roならarrayに if (class_exists('BEAR_Ro', false) && $values instanceof BEAR_Ro) { $values = array('code' => $values->getCode(), 'headers' => $values->header, 'body' => $values->body, 'links' => $values->links); } if ($ouputMode === null && is_scalar($values)) { $ouputMode = 'dump'; } $trace = isset($options['trace']) ? $options['trace'] : debug_backtrace(); $file = $trace[0]['file']; $line = $trace[0]['line']; $includePath = explode(":", get_include_path()); $method = isset($trace[1]['class']) ? " ({$trace[1]['class']}" . '::' . "{$trace[1]['function']})" : ''; $fileArray = file($file, FILE_USE_INCLUDE_PATH); $p = trim($fileArray[$line - 1]); unset($fileArray); preg_match("/p\\((.+)[\\s,\\)]/is", $p, $matches); $varName = isset($matches[1]) ? $matches[1] : ''; $label = isset($options['label']) ? $options['label'] : "{$varName} in {$file} on line {$line}{$method}"; if (strlen(serialize($values)) > 1000000) { $ouputMode = 'dump'; } $label = is_object($values) ? ucwords(get_class($values)) . " {$label}" : $label; // if CLI if (PHP_SAPI === 'cli') { $colorOpenReverse = "[7;32m"; $colorOpenBold = "[1;32m"; $colorOpenPlain = "[0;32m"; $colorClose = "[0m"; echo $colorOpenReverse . "{$varName}" . $colorClose . " = "; var_dump($values); echo $colorOpenPlain . "in {$colorOpenBold}{$file}{$colorClose}{$colorOpenPlain} on line {$line}{$method}" . $colorClose . "\n"; return; } if (Panda::isCliOutput()) { if (class_exists('FB', false)) { $ouputMode = 'fire'; } else { $ouputMode = 'syslog'; } } $labelField = '<fieldset style="color:#4F5155; border:1px solid black;padding:2px;width:10px;">'; $labelField .= '<legend style="color:black;font-size:9pt;font-weight:bold;font-family:Verdana,'; $labelField .= 'Arial,,SunSans-Regular,sans-serif;">' . $label . '</legend>'; switch ($ouputMode) { case 'v': case 'var': if (class_exists('Var_Dump', false)) { Var_Dump::displayInit(array('display_mode' => 'HTML4_Text')); print $labelField; Var_Dump::display($values); } else { ob_start(); var_export($values); $var = ob_get_clean(); print $labelField; echo "<pre>" . $var . '</pre>'; } print "</fieldset>"; break; case 'd': case 'dump': $file = "<a style=\"color:gray; text-decoration:none;\" target=\"_blank\" href=/__panda/edit/?file={$file}&line={$line}>{$file}</a>"; $dumpLabel = isset($options['label']) ? $options['label'] : "in <span style=\"color:gray\">{$file}</span> on line {$line}{$method}"; echo self::dump($values, null, array('label' => $dumpLabel, 'var_name' => $varName)); break; case 'e': case 'export': echo "{$labelField}<pre>" . var_export($values, true); echo '</fieldset></pre>'; break; case 'h': case 'header': header("x-panda-{$label}", print_r($values, true)); break; case 's': case 'syslog': syslog(LOG_DEBUG, "label:{$label}" . print_r($values, true)); break; case 'f': case 'fire': if (class_exists('FB', false)) { $label = isset($options['label']) ? $options['label'] : 'p() in ' . $trace[0]['file'] . ' on line ' . $trace[0]['line']; FB::group($label); FB::error($values); FB::groupEnd(); } break; case null: case 'printa': case 'print_a': default: $options = "max_y:100;pickle:1;label:{$label}"; print_a($values, $options); } if (isset($options['return']) && $options['return'] === true) { return ob_get_clean(); } }
public function save_comment() { // For debugging FB::group("Saving Comment"); $comment = $this->_validate_comment_data(); if ($comment === FALSE) { // Debugging info FB::send("Comment failed validation."); FB::groupEnd(); $loc = array_shift(explode('?', $_SERVER['HTTP_REFERER'])); if (!strpos($loc, '#add-comment')) { $loc .= '#add-comment'; } header('Location: ' . $loc); exit; } // Create a new comment entry, or update one if a comment_id is supplied $sql = "INSERT INTO `" . DB_NAME . "`.`" . DB_PREFIX . "comments`\n (\n `comment_id`, `entry_id`, `name`, `email`, `url`,\n `remote_address`, `comment`, `subscribed`, `thread_id`,\n `created`\n )\n VALUES\n (\n :comment_id, :entry_id, :name, :email, :url,\n :remote_address, :comment, :subscribed, :thread_id, :created\n )\n ON DUPLICATE KEY UPDATE\n `name`=:name, `email`=:email, `url`=:url,\n `comment`=:comment;"; try { // Create a prepared statement $stmt = $this->db->prepare($sql); // Bind the query parameters $stmt->bindParam(":comment_id", $comment->comment_id, PDO::PARAM_INT); $stmt->bindParam(":entry_id", $comment->entry_id, PDO::PARAM_INT); $stmt->bindParam(":name", $comment->name, PDO::PARAM_STR); $stmt->bindParam(":email", $comment->email, PDO::PARAM_STR); $stmt->bindParam(":url", $comment->url, PDO::PARAM_STR); $stmt->bindParam(":remote_address", $comment->remote_address, PDO::PARAM_STR); $stmt->bindParam(":comment", $comment->comment, PDO::PARAM_STR); $stmt->bindParam(":subscribed", $comment->subscribed, PDO::PARAM_INT); $stmt->bindParam(":thread_id", $comment->thread_id, PDO::PARAM_INT); $stmt->bindParam(":created", $comment->created, PDO::PARAM_INT); // Execute the statement and free the resources $stmt->execute(); if ($stmt->errorCode() !== '00000') { $err = $stmt->errorInfo(); ECMS_Error::log_exception(new Exception($err[2])); } else { $stmt->closeCursor(); if ((int) $comment->comment_id === 0) { $comment->comment_id = $this->db->lastInsertId(); } // Send a comment notification to all subscribers $this->_send_comment_notification($comment); unset($this->_sdata->temp); $this->_suspend_commenter(15); $this->_sdata->verified = 1; $loc = array_shift(explode('?', array_shift(explode('#', $_SERVER['HTTP_REFERER'])))); header('Location: ' . $loc . '#comment-' . $comment->comment_id); exit; } } catch (Exception $e) { ECMS_Error::log_exception($e); } }
private function initClassPathCache() { $dir = $this->getDirectoryList(); $count = 0; $max = 100; if ($this->debug) { FB::group(__METHOD__, array('Collapsed' => true)); } if ($this->debug) { fb("Walk the itereator: keys are full paths!", "WARN"); } foreach ($dir as $key => $fileInfo) { if ($this->debug) { fb($fileInfo->getRealPath(), "key = {$key}"); } $this->cache[$key] = $fileInfo->getRealPath(); } if ($this->debug) { FB::groupEnd(); } }
/** * Logs to a group * * @author Anthony Short * @param $group * @return void */ private static function _group($group, $message, $level = 3) { FB::group($group); self::_log($message, $level); FB::groupEnd(); }
/** * Sets the initial variables, checks if we need to process the css * and then sends whichever file to the browser. * * @return void * @author Anthony Short **/ public static function run($get, $config = array(), $path = array()) { static $run; # This function can only be run once if ($run === TRUE) { return; } # If we want to debug (turn on errors and FirePHP) if ($config['debug']) { # Set the error reporting level. error_reporting(E_ALL & ~E_STRICT); # Set error handler set_error_handler(array('CSScaffold', 'exception_handler')); # Set exception handler set_exception_handler(array('CSScaffold', 'exception_handler')); # Turn on FirePHP FB::setEnabled(true); } else { # Turn off errors error_reporting(0); FB::setEnabled(false); } # The default options $default_config = array('debug' => false, 'in_production' => false, 'force_recache' => false, 'show_header' => true, 'auto_include_mixins' => true, 'override_import' => false, 'absolute_urls' => false, 'use_css_constants' => false, 'minify_css' => true, 'constants' => array(), 'disabled_plugins' => array()); # Merge them with our set options $config = array_merge($default_config, $config); # The default paths $default_paths = array('document_root' => $_SERVER['DOCUMENT_ROOT'], 'css' => '../', 'system' => 'system', 'cache' => 'cache'); # Merge them with our set options $path = array_merge($default_paths, $path); # Set the options and paths in the config self::config_set('core', $config); # Set the paths in the config self::config_set('core.path.docroot', fix_path($path['document_root'])); self::config_set('core.path.system', fix_path($path['system'])); self::config_set('core.path.cache', fix_path($path['cache'])); self::config_set('core.path.css', fix_path($path['css'])); self::config_set('core.url.css', str_replace(self::config('core.path.docroot'), '/', self::config('core.path.css'))); self::config_set('core.url.system', str_replace(self::config('core.path.docroot'), '/', SYSPATH)); # Load the include paths self::include_paths(TRUE); # Change into the system directory chdir(SYSPATH); # Set the output if (isset($get['output'])) { self::config_set('core.output', $get['output']); } # Parse the $_GET['request'] and set it in the config self::config_set('core.request', self::parse_request($get['request'])); # Get the modified time of the CSS file self::config_set('core.request.mod_time', filemtime(self::config('core.request.path'))); # Tell CSScaffold where to cache and tell if we want to recache self::cache_set(self::config('core.path.cache')); # Set it back to false if it's locked if ($config['in_production'] and file_exists(self::$cached_file)) { $recache = false; } elseif ($config['force_recache'] or isset($get['recache']) or self::config('core.cache.mod_time') <= self::config('core.request.mod_time')) { $recache = true; self::cache_clear(); } # Load the modules self::load_modules($config['disabled_plugins']); # Work in the same directory as the requested CSS file chdir(dirname(self::config('core.request.path'))); # Create a new CSS object CSS::load(self::config('core.request.path')); # Parse it if ($recache) { self::parse_css(); } # Log to Firebug FB::group('CSScaffold Settings'); FB::log(self::config('core')); FB::groupEnd(); # Output it self::output(CSS::$css); # Setup is complete, prevent it from being run again $run = TRUE; }
define('FIREPHP_INFO', false); define('FIREPHP_WARN', false); define('FIREPHP_ERROR', false); define('FIREPHP_TRACE', true); require_once '../../Grace/FirePHPCore/fb.php'; FB::log('Hello World !'); // 常规记录 \FB::group('Test Group A', ['Collapsed' => true]); // 记录分组 // 以下为按照不同类别或者类型进行信息记录 FB::log('Plain Message'); FB::info('Info Message'); FB::warn('Warn Message'); FB::error('Error Message'); FB::log('Message', 'Optional Label'); FB::info([1, 2, 3, 5, 56], "All Turtles"); FB::groupEnd(); FB::group('Test Group B'); FB::log('Hello World B'); FB::log('Plain Message'); FB::info('Info Message'); FB::warn('Warn Message'); FB::error('Error Message'); FB::log('Message', 'Optional Label'); FB::groupEnd(); $table[] = array('Col 1 Heading', 'Col 2 Heading', 'Col 2 Heading'); $table[] = array('Row 1 Col 1', 'Row 1 Col 2', 'Row 1 Col 2'); $table[] = array('Row 2 Col 1', 'Row 2 Col 2'); $table[] = array('Row 3 Col 1', 'Row 3 Col 2'); FB::table('Table Label', $table); FB::trace('123', [1, 23, 4]);
<?php require_once 'FirePHP/fb.php'; FB::setLogToInsightConsole('Firebug'); fb('Log message'); FB::log('Log message'); FB::log('Log message', 'Label'); FB::info('Info message'); FB::warn('Warn message'); FB::error('Error message'); FB::dump('key', 'value'); FB::trace('Trace to here'); try { throw new Exception('Test exception'); } catch (Exception $e) { FB::error($e); } FB::table('2 SQL queries took 0.06 seconds', array(array('SQL Statement', 'Time', 'Result'), array('SELECT * FROM Foo', '0.02', array('row1', 'row2')), array('SELECT * FROM Bar', '0.04', array('row1', 'row2')))); FB::group('Group 1'); FB::log('Test message 1'); FB::group('Group 2'); FB::log('Test message 2'); FB::groupEnd(); FB::log('Test message 3'); FB::groupEnd();
/** * Display Error Message in debug mode. * * <pre> * * @param string $heading Headding * @param string $subheading Sub headding * @param mixed $info error info * @param array $options options * * $options key: * * string $options['file'] file name * int $options['line'] line * array $options['trace'] backtrace * bool $options['return'] return string(no echo) * </pre> * * @return void */ public static function error($heading, $subheading = "", $info = "", array $options = array()) { // return if live if (self::$_config[self::CONFIG_DEBUG] !== true) { return; } if (isset($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH'] === 'XMLHttpRequest') { if (class_exists('FB', false)) { $in = isset($options['file']) ? "- in {$options['file']} on line {$options['line']}" : ''; $msg = "{$heading} - {$subheading} {$in}"; if ($info) { FB::group($msg); FB::error($info); FB::groupEnd(); return; } } } static $num = 1; //div id number $heading = is_numeric($heading) ? self::$packageName[$heading] : $heading; // Application error callback if (is_callable(self::$_config[self::CONFIG_ON_ERROR_FIRED])) { call_user_func(self::$_config[self::CONFIG_ON_ERROR_FIRED], $heading, $subheading, $info, $options); } $fileInfoString = isset($options['file']) ? "in {$options['file']} on line {$options['line']}" : 'in unknown file'; if (self::$_config[self::CONFIG_ENABLE_FIREPHP] && isset($options['severity'])) { $fireLevel = FirePHP::ERROR; switch (true) { case $options['severity'] == E_WARNING || $options['severity'] == E_USER_WARNING: $fireLevel = FirePHP::WARN; break; case $options['severity'] == E_NOTICE || $options['severity'] == E_USER_NOTICE: $fireLevel = FirePHP::INFO; break; case $options['severity'] == E_STRICT: $fireLevel = FirePHP::LOG; break; default: $fireLevel = FirePHP::ERROR; break; } FB::send("{$subheading} - {$fileInfoString}", $heading, $fireLevel); } self::GrowlNotify($heading, $subheading . "\n{$fileInfoString}"); $defaultOptions = array('file' => null, 'line' => null, 'trace' => array(), 'return' => false, 'no_screen' => false); $options = array_merge($defaultOptions, $options); if ($options['no_screen']) { return ''; } $output = self::_getDebugCss(); if ($options['trace']) { $traceId = uniqid(); $traceFile = self::getTempDir() . '/trace-' . $traceId . '.log'; $refData = self::__addReflectInfo($options['trace']); file_put_contents($traceFile, serialize($options['trace'])); file_put_contents("{$traceFile}.ref.log", serialize($refData)); } if (PHP_SAPI == 'cli' || call_user_func(self::$_config[self::CONFIG_IS_API_CHECK])) { $output .= $heading . PHP_EOL; $output .= $subheading . PHP_EOL; $output .= $info . PHP_EOL; return $output; } else { if (is_array($info) || is_object($info)) { if (isset($options['package']) && $options['package'] === self::PACKAGE_PHP) { $info = self::_getContextString($info, '$'); } else { $info = self::_getContextString($info); } } header('Content-Type: text/html; charset=utf-8'); $output .= '<div id="panda-' . $num . '"class="panda">'; $output .= '<div class="panda-header">'; $output .= '<h1>' . $heading . '</h1>'; $output .= isset($options['file']) ? '<p class="panda-file">' . self::getEditorLink($options['file'], $options['line'], 0) . '</p>' : ''; $output .= '<h2>' . $subheading . '</h2>'; $output .= '<p class="panda-cmd">'; if ($options['trace']) { $output .= '<a target="_panda_trace_' . $traceId . '" href="' . "http://{$_SERVER['SERVER_NAME']}" . self::$_config[self::CONFIG_PANDA_PATH] . '__panda/trace/?id=' . $traceId . '">trace</a> | '; } $output .= '<a href=# onclick="var t = document.getElementById(\'panda-'; $output .= $num . '\'); t.parentNode.removeChild(t);return false;">close</a>'; $output .= '</p>'; $output .= '</div>'; $output .= '<div class="panda-body">'; $output .= $info ? '<h3>Info</h3><p class="panda-info">' . $info . '</p>' : ''; // file summary if ($options['file']) { $output .= '<h3>Source</h3>'; $output .= '<a style="text-decoration:none;" href="/__panda/edit/?file=' . $options['file']; $output .= '&line=' . $options['line'] . '">'; $output .= self::_getFileSummary($options['file'], $options['line'], 6); $output .= '</a>'; if ($options['trace']) { // trace summary $output .= '<h3>Trace</h3>'; $output .= Panda_Debug::getTraceSummary($options['trace']); } } $output .= '</div></div>'; // /body-error-body /panda } $num++; if ($options['return'] === true) { return $output; } else { echo $output; } }
/** * debug print * * @param null $var * @param int $level */ public static function printR($trace, $var = null) { // contents $htmlErrors = ini_get('html_errors'); ini_set('html_errors', 'On'); $isCli = PHP_SAPI === 'cli'; if (extension_loaded('xdebug')) { if ($isCli) { ini_set('xdebug.xdebug.cli_color', true); } $level = static::$level; ini_set('xdebug.var_display_max_depth', $level); } $er = error_reporting(0); ob_start(); var_dump($var); // sometimes notice with reason unknown $varDump = ob_get_clean(); error_reporting($er); if ($isCli) { $varDump = strip_tags(html_entity_decode($varDump)); } ini_set('html_errors', $htmlErrors); // label $receiver = $trace[0]; $file = $receiver['file']; $line = $receiver['line']; $funcName = $receiver['function']; $method = isset($trace[1]['class']) ? " ({$trace[1]['class']}" . '::' . "{$trace[1]['function']})" : ''; $fileArray = file($file); $p = trim($fileArray[$line - 1]); unset($fileArray); preg_match("/{$funcName}\\((.+)[\\s,\\)]/is", $p, $matches); if (isset($matches[1])) { $varName = $matches[1]; } else { $varName = '(void)'; $varDump = '<br>'; } if (PHP_SAPI === 'cli') { $colorOpenReverse = "[7;32m"; $colorOpenBold = "[1;32m"; $colorOpenPlain = "[0;32m"; $colorClose = "[0m"; echo $colorOpenReverse . "{$varName}" . $colorClose . " = "; var_dump($var); echo $colorOpenPlain . "in {$colorOpenBold}{$file}{$colorClose}{$colorOpenPlain} on line {$line}{$method}" . $colorClose . "\n"; return; } else { $file = "<a href=\"/_dev/edit/index.php?file={$file}&line={$line}\">{$file}</a>"; } $varNameCss = <<<EOT background-color: green; color: white; border: 1px solid #E1E1E8; padding: 2px 4px; margin 20px 40px; EOT; $fileCss = <<<EOT background-color: #F7F7F9; color: #DD1144; border: 1px solid #E1E1E8; padding: 2px 4px; EOT; if (class_exists('FB', false)) { $label = __FUNCTION__ . '() in ' . $receiver['file'] . ' on line ' . $receiver['line']; /** @noinspection PhpUndefinedClassInspection */ /** @noinspection PhpUndefinedMethodInspection */ FB::group($label); /** @noinspection PhpUndefinedMethodInspection */ /** @noinspection PhpUndefinedClassInspection */ FB::error($var); /** @noinspection PhpUndefinedMethodInspection */ /** @noinspection PhpUndefinedClassInspection */ FB::groupEnd(); } $file = <<<EOT <span style="font-size:12px;color:gray"> in {$file} on line <b>{$line}</b> <code>{$method}</code></span> EOT; $label = <<<EOT <span style="{$varNameCss}">{$varName}</span><span style="{$fileCss}">{$file}</span> EOT; // output echo $label; echo "{$varDump}</div>"; }