class_mcPerformance.inc.php 7.96 KB
<?php
/** 
 * @copyright (c) 2014, netz.coop eG
 */
class mcPerformance {

	private static $StaticCalls = array();

	private static function prepareStaticCalls($param_ClassName, $param_FncName, array $param_toDiffParams=array()) {
		if(!array_key_exists($param_ClassName, mcPerformance::$StaticCalls)) {
			mcPerformance::$StaticCalls[$param_ClassName] = array();
		}
		if(!array_key_exists($param_FncName, mcPerformance::$StaticCalls[$param_ClassName])) {
			mcPerformance::$StaticCalls[$param_ClassName][$param_FncName] = array( );
		}

		global $__mcPerformance_backtrace;
		if($__mcPerformance_backtrace) {
			$string_backtrace = D::getBacktrace($param_htmltags=false, $param_start=2, $param_end=2);
		} else {
			$string_backtrace = '__mcPerformance_backtrace = false';
		}

		
		$toDiffParams = serialize($param_toDiffParams);

		$obj_key = null;
		$count_objects = count(mcPerformance::$StaticCalls[$param_ClassName][$param_FncName]);
		for($i=0; $i<$count_objects; $i++ ) {
			if(mcPerformance::$StaticCalls[$param_ClassName][$param_FncName][$i]['param'] === $toDiffParams) {
				$obj_key = $i;
			}
		}
		if(is_null($obj_key)) {
			mcPerformance::$StaticCalls[$param_ClassName][$param_FncName][]  = array('count'=>1, 'param' => $toDiffParams, 'backtraceStrings' => array($string_backtrace));
		} else {
			mcPerformance::$StaticCalls[$param_ClassName][$param_FncName][$obj_key]['count']++;
			mcPerformance::$StaticCalls[$param_ClassName][$param_FncName][$obj_key]['backtraceStrings'][] = $string_backtrace;
		}
	}

	private static $ObjectCalls = array();

	private static function prepareObjectCalls($param_ClassName, $param_FncName, &$param_Object, array $param_toDiffParams=array()) {
		if(!array_key_exists($param_ClassName, mcPerformance::$ObjectCalls)) {
			mcPerformance::$ObjectCalls[$param_ClassName] = array();
		}
		if(!array_key_exists($param_FncName, mcPerformance::$ObjectCalls[$param_ClassName])) {
			mcPerformance::$ObjectCalls[$param_ClassName][$param_FncName] = array( );
		}

		global $__mcPerformance_backtrace;
		if($__mcPerformance_backtrace) {
			$string_backtrace = D::getBacktrace($param_htmltags=false, $param_start=2, $param_end=2);
		} else {
			$string_backtrace ='__mcPerformance_backtrace = false';
		}
		

		if(array_search('getID', get_class_methods($param_ClassName))) {
			$getIDFnc = true;
			if(!array_key_exists($param_Object->getID(), mcPerformance::$ObjectCalls[$param_ClassName][$param_FncName])) {
				mcPerformance::$ObjectCalls[$param_ClassName][$param_FncName][$param_Object->getID()] = array( );
			}
			$ObjArray = &mcPerformance::$ObjectCalls[$param_ClassName][$param_FncName][$param_Object->getID()];
		} else {
			$getIDFnc = false;
			$ObjArray = &mcPerformance::$ObjectCalls[$param_ClassName][$param_FncName];
		}

		$toDiffParams = serialize($param_toDiffParams);

		$obj_key = null;
		$count_objects = count($ObjArray);
		for($i=0; $i<$count_objects; $i++ ) {
			if($param_Object === $ObjArray[$i]['object'] && $ObjArray[$i]['param'] === $toDiffParams) {
				$obj_key = $i;
			}
		}
		if(is_null($obj_key)) {
			$ObjArray[]  = array('count'=>1, 'object' => &$param_Object, 'param' => $toDiffParams, 'backtraceStrings' => array($string_backtrace));
		} else {
			$ObjArray[$obj_key]['count']++;
			$ObjArray[$obj_key]['backtraceStrings'][] = $string_backtrace;
		}
	}

	/**
	 *	erstellt eine kleine Statistik über die Funktion in der checkMultipleCalls() aufgerufen wird
	 *		Statistik kann über mcPerformance::showStats() angezeigt werden
	 *
	 * @param array $param_toDiffParams default array() --- wenn gesetzt, unterscheidet fnc auch nach Parametern
	 */
	public static function checkMultipleCalls(array $param_toDiffParams=array()) {
		global $_LOSP_DEV;
		if($_LOSP_DEV) {
			$array_backtrace = debug_backtrace();

			/**
			 * static class function call
			 */
			if($array_backtrace[1]['type'] == '::') {
				mcPerformance::prepareStaticCalls($array_backtrace[1]['class'], $array_backtrace[1]['function'], $param_toDiffParams);
			/**
			 * object function call
			 */
			} else if($array_backtrace[1]['type'] == '->') {
				mcPerformance::prepareObjectCalls($array_backtrace[1]['class'], $array_backtrace[1]['function'], $array_backtrace[1]['object'], $param_toDiffParams);

			} else {
				D::li('type ('.$array_backtrace[1]['type'].') not implemantated');
			}
		}
	}

	public static function showStats($param_print=true, $param_force=false) {
		global $_LOSP_DEV;
		if($_LOSP_DEV) {
			D::h2('static calls', $param_print, $param_force);
			foreach(mcPerformance::$StaticCalls as $classname => $fnc) {
				D::ulli('<b>'.$classname.'</b>', $param_print, $param_force);
				foreach($fnc as $fncname => $FncCalls) {
					$count_diff_FncCalls = count($FncCalls);
					D::ulli('<b>'.$fncname.' with '.$count_diff_FncCalls.' different fnc calls </b>', $param_print, $param_force);
					$allFncCalls = 0;
					foreach($FncCalls as $FncCall) {
						$backtraceString = '';
						foreach($FncCall['backtraceStrings'] as $index => $string_backtrace) {
							if($index==0) {
								$backtraceString .= '<i title="'.$string_backtrace.'">'.$index.'</i> ';
							} else {
								$backtraceString .= '- <b><i title="'.$string_backtrace.'">'.$index.'</i></b> ';
							}
						}

						$string_param = str_replace('"', '', $FncCall['param']);
						if(strlen($string_param) < 32) {
							$string4param = " ".$string_param." ";
						} else {
							$string4param = ' <u title="'.$string_param.'">'.md5($FncCall['param'])."</u> ";
						}


						D::ulli('<i>'.$fncname.'('.$string4param.') wurde '.$FncCall['count'].' aufgerufen</i>'.' backtrace '.$backtraceString, $param_print, $param_force);
						$allFncCalls += $FncCall['count'];
					}
					D::ulli('<b>'.$fncname.' general:  '.$allFncCalls.' (zu '.$count_diff_FncCalls.') </b>', $param_print, $param_force);
				}
			}

			D::h2('object calls');
			foreach(mcPerformance::$ObjectCalls as $classname => $fnc) {
				if(array_search('getID', get_class_methods($classname))) {
					$getIDFnc = true;
				} else {
					$getIDFnc = false;
				}

				D::ulli('<b>'.$classname.'</b>', $param_print, $param_force);
				foreach($fnc as $fncname => $objects) {

					if($getIDFnc) {
						D::ulli('<b>'.$fncname.' mit '.count($objects).' unterschiedlichen objects </b>', $param_print, $param_force);
						foreach($objects as $objID => $objIDArray) {
							D::ulli('<b><i>'.$objID.'  =>  wurde '.count($objIDArray).' geladen</i></b>', $param_print, $param_force);
							foreach($objIDArray as $obj) {
								if(strlen($obj['param']) < 32) {
									$string4param = "\t Param(".$obj['param'].")";
								} else {
									$string4param = "\t Param_md5(".md5($obj['param']).")";
								}
								$backtraceString = '';
								foreach($obj['backtraceStrings'] as $index => $string_backtrace) {
									if($index==0) {
										$backtraceString .= '<i title="'.$string_backtrace.'">'.$index.'</i> ';
									} else {
										$backtraceString .= '- <b><i title="'.$string_backtrace.'">'.$index.'</i></b> ';
									}
								}

								D::ulli($obj['object'].'  =>  '.$obj['count'].' x '.$fncname. $string4param.' backtrace '.$backtraceString, $param_print, $param_force);
							}
						}
					} else {
						D::ulli('<b>'.$fncname.' mit '.count($objects).' objects</b>', $param_print, $param_force);
						foreach($objects as $obj) {
							$string_param = str_replace('"', '', $obj['param']);
							if(strlen($string_param) < 32) {
								$string4param = "\t Param(".$string_param.")";
							} else {
								$string4param = '	<i title="'.$string_param.'">Param_md5('.md5($obj['param']).")</i>";
							}
							$backtraceString = '';
							foreach($obj['backtraceStrings'] as $index => $string_backtrace) {
								if($index==0) {
									$backtraceString .= '<i title="'.$string_backtrace.'">'.$index.'</i> ';
								} else {
									$backtraceString .= '- <b><i title="'.$string_backtrace.'">'.$index.'</i></b> ';
								}
							}
							D::ulli($obj['object'].'  =>  '.$obj['count'].' x '.$fncname. $string4param.' backtrace '.$backtraceString, $param_print, $param_force);
						}
					}
				}
			}
		}
	}
}

?>