| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611 | 
							- <?php
 
- // +----------------------------------------------------------------------
 
- // | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
 
- // +----------------------------------------------------------------------
 
- // | Copyright (c) 2006-2014 http://thinkphp.cn All rights reserved.
 
- // +----------------------------------------------------------------------
 
- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
 
- // +----------------------------------------------------------------------
 
- // | Author: luofei614 <weibo.com/luofei614>
 
- // +----------------------------------------------------------------------
 
- // $Id$
 
- /**
 
-  * 将Trace信息输出到chrome浏览器的控制器,从而不影响ajax效果和页面的布局。
 
-  * 使用前,你需要先安装 chrome log 这个插件: http://craig.is/writing/chrome-logger。
 
-  * 定义应用的tags.php文件 Application/Common/Conf/tags.php, 
 
-  * <code>
 
-  * <?php return array(
 
-  *   'app_end'=>array(
 
-  *       'Behavior\ChromeShowPageTrace'
 
-  *   )
 
-  * );
 
-  * </code>
 
-  * 如果trace信息没有正常输出,请查看您的日志。
 
-  * 这是通过http headers和chrome通信,所以要保证在输出trace信息之前不能有
 
-  * headers输出,你可以在入口文件第一行加入代码 ob_start(); 或者配置output_buffering
 
-  *
 
-  */
 
- namespace Behavior;
 
- use Think\Log;
 
- /**
 
-  * 系统行为扩展 页面Trace显示输出
 
-  */
 
- class ChromeShowPageTraceBehavior {
 
-     protected $tracePageTabs =  array('BASE'=>'基本','FILE'=>'文件','INFO'=>'流程','ERR|NOTIC'=>'错误','SQL'=>'SQL','DEBUG'=>'调试');
 
-     // 行为扩展的执行入口必须是run
 
-     public function run(&$params){
 
-         if(C('SHOW_PAGE_TRACE')) $this->showTrace();
 
-     }
 
-    
 
-     /**
 
-      * 显示页面Trace信息
 
-      * @access private
 
-      */
 
-     private function showTrace() {
 
-          // 系统默认显示信息
 
-         $files  =  get_included_files();
 
-         $info   =   array();
 
-         foreach ($files as $key=>$file){
 
-             $info[] = $file.' ( '.number_format(filesize($file)/1024,2).' KB )';
 
-         }
 
-         $trace  =   array();
 
-         $base   =   array(
 
-             '请求信息'  =>  date('Y-m-d H:i:s',$_SERVER['REQUEST_TIME']).' '.$_SERVER['SERVER_PROTOCOL'].' '.$_SERVER['REQUEST_METHOD'].' : '.__SELF__,
 
-             '运行时间'  =>  $this->showTime(),
 
- 			'吞吐率'	=>	number_format(1/G('beginTime','viewEndTime'),2).'req/s',
 
-             '内存开销'  =>  MEMORY_LIMIT_ON?number_format((memory_get_usage() - $GLOBALS['_startUseMems'])/1024,2).' kb':'不支持',
 
-             '查询信息'  =>  N('db_query').' queries '.N('db_write').' writes ',
 
-             '文件加载'  =>  count(get_included_files()),
 
-             '缓存信息'  =>  N('cache_read').' gets '.N('cache_write').' writes ',
 
-             '配置加载'  =>  count(c()),
 
-             '会话信息'  =>  'SESSION_ID='.session_id(),
 
-             );
 
-         // 读取应用定义的Trace文件
 
-         $traceFile  =   COMMON_PATH.'Conf/trace.php';
 
-         if(is_file($traceFile)) {
 
-             $base   =   array_merge($base,include $traceFile);
 
-         }
 
-         $debug  =   trace();
 
-         $tabs   =   C('TRACE_PAGE_TABS',null,$this->tracePageTabs);
 
-         foreach ($tabs as $name=>$title){
 
-             switch(strtoupper($name)) {
 
-                 case 'BASE':// 基本信息
 
-                     $trace[$title]  =   $base;
 
-                     break;
 
-                 case 'FILE': // 文件信息
 
-                     $trace[$title]  =   $info;
 
-                     break;
 
-                 default:// 调试信息
 
-                     $name       =   strtoupper($name);
 
-                     if(strpos($name,'|')) {// 多组信息
 
-                         $array  =   explode('|',$name);
 
-                         $result =   array();
 
-                         foreach($array as $name){
 
-                             $result   +=   isset($debug[$name])?$debug[$name]:array();
 
-                         }
 
-                         $trace[$title]  =   $result;
 
-                     }else{
 
-                         $trace[$title]  =   isset($debug[$name])?$debug[$name]:'';
 
-                     }
 
-             }
 
-         }
 
-       chrome_debug('TRACE信息:'.__SELF__,'group');
 
-         //输出日志
 
-         foreach($trace as $title=>$log){
 
-             '错误'==$title?chrome_debug($title,'group'):chrome_debug($title,'groupCollapsed');
 
-             foreach($log as $i=>$logstr){
 
-                 chrome_debug($i.'.'.$logstr,'log');
 
-             }
 
-             chrome_debug('','groupEnd');
 
-         }
 
-        chrome_debug('','groupEnd');
 
-         if($save = C('PAGE_TRACE_SAVE')) { // 保存页面Trace日志
 
-             if(is_array($save)) {// 选择选项卡保存
 
-                 $tabs   =   C('TRACE_PAGE_TABS',null,$this->tracePageTabs);
 
-                 $array  =   array();
 
-                 foreach ($save as $tab){
 
-                     $array[] =   $tabs[$tab];
 
-                 }
 
-             }
 
-             $content    =   date('[ c ]').' '.get_client_ip().' '.$_SERVER['REQUEST_URI']."\r\n";
 
-             foreach ($trace as $key=>$val){
 
-                 if(!isset($array) || in_array($key,$array)) {
 
-                     $content    .=  '[ '.$key." ]\r\n";
 
-                     if(is_array($val)) {
 
-                         foreach ($val as $k=>$v){
 
-                             $content .= (!is_numeric($k)?$k.':':'').print_r($v,true)."\r\n";
 
-                         }
 
-                     }else{
 
-                         $content .= print_r($val,true)."\r\n";
 
-                     }
 
-                     $content .= "\r\n";
 
-                 }
 
-             }
 
-             error_log(str_replace('<br/>',"\r\n",$content), 3,LOG_PATH.date('y_m_d').'_trace.log');
 
-         }
 
-         unset($files,$info,$base);
 
-     }
 
-     /**
 
-      * 获取运行时间
 
-      */
 
-     private function showTime() {
 
-         // 显示运行时间
 
-         G('beginTime',$GLOBALS['_beginTime']);
 
-         G('viewEndTime');
 
-         // 显示详细运行时间
 
-         return G('beginTime','viewEndTime').'s ( Load:'.G('beginTime','loadTime').'s Init:'.G('loadTime','initTime').'s Exec:'.G('initTime','viewStartTime').'s Template:'.G('viewStartTime','viewEndTime').'s )';
 
-     }
 
- }
 
- if(!function_exists('chrome_debug')){
 
- //ChromePhp 输出trace的函数
 
- function chrome_debug($msg,$type='trace',$trace_level=1){
 
-     if('trace'==$type){
 
-         ChromePhp::groupCollapsed($msg);
 
-         $traces=debug_backtrace(false);
 
-         $traces=array_reverse($traces);
 
-         $max=count($traces)-$trace_level;
 
-         for($i=0;$i<$max;$i++){
 
-             $trace=$traces[$i];
 
-             $fun=isset($trace['class'])?$trace['class'].'::'.$trace['function']:$trace['function'];
 
-             $file=isset($trace['file'])?$trace['file']:'unknown file';
 
-             $line=isset($trace['line'])?$trace['line']:'unknown line';
 
-             $trace_msg='#'.$i.'  '.$fun.' called at ['.$file.':'.$line.']';
 
-             if(!empty($trace['args'])){
 
-                 ChromePhp::groupCollapsed($trace_msg);
 
-                 ChromePhp::log($trace['args']);
 
-                 ChromePhp::groupEnd();
 
-             }else{
 
-                 ChromePhp::log($trace_msg);
 
-             }
 
-         }
 
-         ChromePhp::groupEnd();
 
-     }else{
 
-         if(method_exists('Behavior\ChromePhp',$type)){
 
-             //支持type trace,warn,log,error,group, groupCollapsed, groupEnd等
 
-             call_user_func(array('Behavior\ChromePhp',$type),$msg);
 
-         }else{
 
-             //如果type不为trace,warn,log等,则为log的标签
 
-             call_user_func_array(array('Behavior\ChromePhp','log'),func_get_args());
 
-         }
 
-     }
 
- }
 
-  
 
- /**
 
-  * Server Side Chrome PHP debugger class
 
-  *
 
-  * @package ChromePhp
 
-  * @author Craig Campbell <iamcraigcampbell@gmail.com>
 
-  */
 
- class ChromePhp{
 
-     /**
 
-      * @var string
 
-      */
 
-     const VERSION = '4.1.0';
 
-     /**
 
-      * @var string
 
-      */
 
-     const HEADER_NAME = 'X-ChromeLogger-Data';
 
-     /**
 
-      * @var string
 
-      */
 
-     const BACKTRACE_LEVEL = 'backtrace_level';
 
-     /**
 
-      * @var string
 
-      */
 
-     const LOG = 'log';
 
-     /**
 
-      * @var string
 
-      */
 
-     const WARN = 'warn';
 
-     /**
 
-      * @var string
 
-      */
 
-     const ERROR = 'error';
 
-     /**
 
-      * @var string
 
-      */
 
-     const GROUP = 'group';
 
-     /**
 
-      * @var string
 
-      */
 
-     const INFO = 'info';
 
-     /**
 
-      * @var string
 
-      */
 
-     const GROUP_END = 'groupEnd';
 
-     /**
 
-      * @var string
 
-      */
 
-     const GROUP_COLLAPSED = 'groupCollapsed';
 
-     /**
 
-      * @var string
 
-      */
 
-     const TABLE = 'table';
 
-     /**
 
-      * @var string
 
-      */
 
-     protected $_php_version;
 
-     /**
 
-      * @var int
 
-      */
 
-     protected $_timestamp;
 
-     /**
 
-      * @var array
 
-      */
 
-     protected $_json = array(
 
-         'version' => self::VERSION,
 
-         'columns' => array('log', 'backtrace', 'type'),
 
-         'rows' => array()
 
-     );
 
-     /**
 
-      * @var array
 
-      */
 
-     protected $_backtraces = array();
 
-     /**
 
-      * @var bool
 
-      */
 
-     protected $_error_triggered = false;
 
-     /**
 
-      * @var array
 
-      */
 
-     protected $_settings = array(
 
-         self::BACKTRACE_LEVEL => 1
 
-     );
 
-     /**
 
-      * @var ChromePhp
 
-      */
 
-     protected static $_instance;
 
-     /**
 
-      * Prevent recursion when working with objects referring to each other
 
-      *
 
-      * @var array
 
-      */
 
-     protected $_processed = array();
 
-     /**
 
-      * constructor
 
-      */
 
-     private function __construct()
 
-     {
 
-         $this->_php_version = phpversion();
 
-         $this->_timestamp = $this->_php_version >= 5.1 ? $_SERVER['REQUEST_TIME'] : time();
 
-         $this->_json['request_uri'] = $_SERVER['REQUEST_URI'];
 
-     }
 
-     /**
 
-      * gets instance of this class
 
-      *
 
-      * @return ChromePhp
 
-      */
 
-     public static function getInstance()
 
-     {
 
-         if (self::$_instance === null) {
 
-             self::$_instance = new self();
 
-         }
 
-         return self::$_instance;
 
-     }
 
-     /**
 
-      * logs a variable to the console
 
-      *
 
-      * @param mixed $data,... unlimited OPTIONAL number of additional logs [...]
 
-      * @return void
 
-      */
 
-     public static function log()
 
-     {
 
-         $args = func_get_args();
 
-         return self::_log('', $args);
 
-     }
 
-     /**
 
-      * logs a warning to the console
 
-      *
 
-      * @param mixed $data,... unlimited OPTIONAL number of additional logs [...]
 
-      * @return void
 
-      */
 
-     public static function warn()
 
-     {
 
-         $args = func_get_args();
 
-         return self::_log(self::WARN, $args);
 
-     }
 
-     /**
 
-      * logs an error to the console
 
-      *
 
-      * @param mixed $data,... unlimited OPTIONAL number of additional logs [...]
 
-      * @return void
 
-      */
 
-     public static function error()
 
-     {
 
-         $args = func_get_args();
 
-         return self::_log(self::ERROR, $args);
 
-     }
 
-     /**
 
-      * sends a group log
 
-      *
 
-      * @param string value
 
-      */
 
-     public static function group()
 
-     {
 
-         $args = func_get_args();
 
-         return self::_log(self::GROUP, $args);
 
-     }
 
-     /**
 
-      * sends an info log
 
-      *
 
-      * @param mixed $data,... unlimited OPTIONAL number of additional logs [...]
 
-      * @return void
 
-      */
 
-     public static function info()
 
-     {
 
-         $args = func_get_args();
 
-         return self::_log(self::INFO, $args);
 
-     }
 
-     /**
 
-      * sends a collapsed group log
 
-      *
 
-      * @param string value
 
-      */
 
-     public static function groupCollapsed()
 
-     {
 
-         $args = func_get_args();
 
-         return self::_log(self::GROUP_COLLAPSED, $args);
 
-     }
 
-     /**
 
-      * ends a group log
 
-      *
 
-      * @param string value
 
-      */
 
-     public static function groupEnd()
 
-     {
 
-         $args = func_get_args();
 
-         return self::_log(self::GROUP_END, $args);
 
-     }
 
-     /**
 
-      * sends a table log
 
-      *
 
-      * @param string value
 
-      */
 
-     public static function table()
 
-     {
 
-         $args = func_get_args();
 
-         return self::_log(self::TABLE, $args);
 
-     }
 
-     /**
 
-      * internal logging call
 
-      *
 
-      * @param string $type
 
-      * @return void
 
-      */
 
-     protected static function _log($type, array $args)
 
-     {
 
-         // nothing passed in, don't do anything
 
-         if (count($args) == 0 && $type != self::GROUP_END) {
 
-             return;
 
-         }
 
-         $logger = self::getInstance();
 
-         $logger->_processed = array();
 
-         $logs = array();
 
-         foreach ($args as $arg) {
 
-             $logs[] = $logger->_convert($arg);
 
-         }
 
-         $backtrace = debug_backtrace(false);
 
-         $level = $logger->getSetting(self::BACKTRACE_LEVEL);
 
-         $backtrace_message = 'unknown';
 
-         if (isset($backtrace[$level]['file']) && isset($backtrace[$level]['line'])) {
 
-             $backtrace_message = $backtrace[$level]['file'] . ' : ' . $backtrace[$level]['line'];
 
-         }
 
-         $logger->_addRow($logs, $backtrace_message, $type);
 
-     }
 
-     /**
 
-      * converts an object to a better format for logging
 
-      *
 
-      * @param Object
 
-      * @return array
 
-      */
 
-     protected function _convert($object)
 
-     {
 
-         // if this isn't an object then just return it
 
-         if (!is_object($object)) {
 
-             return $object;
 
-         }
 
-         //Mark this object as processed so we don't convert it twice and it
 
-         //Also avoid recursion when objects refer to each other
 
-         $this->_processed[] = $object;
 
-         $object_as_array = array();
 
-         // first add the class name
 
-         $object_as_array['___class_name'] = get_class($object);
 
-         // loop through object vars
 
-         $object_vars = get_object_vars($object);
 
-         foreach ($object_vars as $key => $value) {
 
-             // same instance as parent object
 
-             if ($value === $object || in_array($value, $this->_processed, true)) {
 
-                 $value = 'recursion - parent object [' . get_class($value) . ']';
 
-             }
 
-             $object_as_array[$key] = $this->_convert($value);
 
-         }
 
-         $reflection = new ReflectionClass($object);
 
-         // loop through the properties and add those
 
-         foreach ($reflection->getProperties() as $property) {
 
-             // if one of these properties was already added above then ignore it
 
-             if (array_key_exists($property->getName(), $object_vars)) {
 
-                 continue;
 
-             }
 
-             $type = $this->_getPropertyKey($property);
 
-             if ($this->_php_version >= 5.3) {
 
-                 $property->setAccessible(true);
 
-             }
 
-             try {
 
-                 $value = $property->getValue($object);
 
-             } catch (ReflectionException $e) {
 
-                 $value = 'only PHP 5.3 can access private/protected properties';
 
-             }
 
-             // same instance as parent object
 
-             if ($value === $object || in_array($value, $this->_processed, true)) {
 
-                 $value = 'recursion - parent object [' . get_class($value) . ']';
 
-             }
 
-             $object_as_array[$type] = $this->_convert($value);
 
-         }
 
-         return $object_as_array;
 
-     }
 
-     /**
 
-      * takes a reflection property and returns a nicely formatted key of the property name
 
-      *
 
-      * @param ReflectionProperty
 
-      * @return string
 
-      */
 
-     protected function _getPropertyKey(ReflectionProperty $property)
 
-     {
 
-         $static = $property->isStatic() ? ' static' : '';
 
-         if ($property->isPublic()) {
 
-             return 'public' . $static . ' ' . $property->getName();
 
-         }
 
-         if ($property->isProtected()) {
 
-             return 'protected' . $static . ' ' . $property->getName();
 
-         }
 
-         if ($property->isPrivate()) {
 
-             return 'private' . $static . ' ' . $property->getName();
 
-         }
 
-     }
 
-     /**
 
-      * adds a value to the data array
 
-      *
 
-      * @var mixed
 
-      * @return void
 
-      */
 
-     protected function _addRow(array $logs, $backtrace, $type)
 
-     {
 
-         // if this is logged on the same line for example in a loop, set it to null to save space
 
-         if (in_array($backtrace, $this->_backtraces)) {
 
-             $backtrace = null;
 
-         }
 
-         // for group, groupEnd, and groupCollapsed
 
-         // take out the backtrace since it is not useful
 
-         if ($type == self::GROUP || $type == self::GROUP_END || $type == self::GROUP_COLLAPSED) {
 
-             $backtrace = null;
 
-         }
 
-         if ($backtrace !== null) {
 
-             $this->_backtraces[] = $backtrace;
 
-         }
 
-         $row = array($logs, $backtrace, $type);
 
-         $this->_json['rows'][] = $row;
 
-         $this->_writeHeader($this->_json);
 
-     }
 
-     protected function _writeHeader($data)
 
-     {
 
-         header(self::HEADER_NAME . ': ' . $this->_encode($data));
 
-     }
 
-     /**
 
-      * encodes the data to be sent along with the request
 
-      *
 
-      * @param array $data
 
-      * @return string
 
-      */
 
-     protected function _encode($data)
 
-     {
 
-         return base64_encode(utf8_encode(json_encode($data)));
 
-     }
 
-     /**
 
-      * adds a setting
 
-      *
 
-      * @param string key
 
-      * @param mixed value
 
-      * @return void
 
-      */
 
-     public function addSetting($key, $value)
 
-     {
 
-         $this->_settings[$key] = $value;
 
-     }
 
-     /**
 
-      * add ability to set multiple settings in one call
 
-      *
 
-      * @param array $settings
 
-      * @return void
 
-      */
 
-     public function addSettings(array $settings)
 
-     {
 
-         foreach ($settings as $key => $value) {
 
-             $this->addSetting($key, $value);
 
-         }
 
-     }
 
-     /**
 
-      * gets a setting
 
-      *
 
-      * @param string key
 
-      * @return mixed
 
-      */
 
-     public function getSetting($key)
 
-     {
 
-         if (!isset($this->_settings[$key])) {
 
-             return null;
 
-         }
 
-         return $this->_settings[$key];
 
-     }
 
- }
 
- }
 
 
  |