Completed
Push — 3.5 ( 1a9180...1bec8a )
by Daniel
24s
created

Profiler   A

Complexity

Total Complexity 34

Size/Duplication

Total Lines 222
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 1

Importance

Changes 0
Metric Value
dl 0
loc 222
rs 9.2
c 0
b 0
f 0
wmc 34
lcom 1
cbo 1

4 Methods

Rating   Name   Duplication   Size   Complexity  
A init() 0 4 2
A mark() 0 7 4
A unmark() 0 7 4
A show() 0 11 3
1
<?php
2
/********************************************************************************\
3
 * Copyright (C) Carl Taylor ([email protected])                             *
4
 * Copyright (C) Torben Nehmer ([email protected]) for Code Cleanup             *
5
 * Licensed under the BSD license upon request                                  *
6
\********************************************************************************/
7
8
/// Enable multiple timers to aid profiling of performance over sections of code
9
10
/**
11
 * Execution time profiler.
12
 *
13
 * @deprecated 4.0 The Profiler class is deprecated, use third party tools like XHProf instead
14
 *
15
 * @package framework
16
 * @subpackage misc
17
 */
18
class Profiler {
19
	var $description;
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $description.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

To learn more about the PSR-2, please see the PHP-FIG site on the PSR-2.

Loading history...
20
	var $startTime;
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $startTime.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

To learn more about the PSR-2, please see the PHP-FIG site on the PSR-2.

Loading history...
21
	var $endTime;
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $endTime.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

To learn more about the PSR-2, please see the PHP-FIG site on the PSR-2.

Loading history...
22
	var $initTime;
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $initTime.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

To learn more about the PSR-2, please see the PHP-FIG site on the PSR-2.

Loading history...
23
	var $cur_timer;
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $cur_timer.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

To learn more about the PSR-2, please see the PHP-FIG site on the PSR-2.

Loading history...
24
	var $stack;
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $stack.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

To learn more about the PSR-2, please see the PHP-FIG site on the PSR-2.

Loading history...
25
	var $trail;
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $trail.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

To learn more about the PSR-2, please see the PHP-FIG site on the PSR-2.

Loading history...
26
	var $trace;
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $trace.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

To learn more about the PSR-2, please see the PHP-FIG site on the PSR-2.

Loading history...
27
	var $count;
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $count.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

To learn more about the PSR-2, please see the PHP-FIG site on the PSR-2.

Loading history...
28
	var $running;
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $running.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

To learn more about the PSR-2, please see the PHP-FIG site on the PSR-2.

Loading history...
29
30
	protected static $inst;
31
32
	/**
33
	* Initialise the timer. with the current micro time
34
	*/
35
	public function Profiler( $output_enabled=false, $trace_enabled=false)
0 ignored issues
show
Coding Style Best Practice introduced by
Please use __construct() instead of a PHP4-style constructor that is named after the class.
Loading history...
36
	{
37
		$this->description = array();
38
		$this->startTime = array();
39
		$this->endTime = array();
40
		$this->initTime = 0;
41
		$this->cur_timer = "";
42
		$this->stack = array();
43
		$this->trail = "";
44
		$this->trace = "";
45
		$this->count = array();
46
		$this->running = array();
47
		$this->initTime = $this->getMicroTime();
48
		$this->output_enabled = $output_enabled;
0 ignored issues
show
Bug introduced by
The property output_enabled does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
49
		$this->trace_enabled = $trace_enabled;
0 ignored issues
show
Bug introduced by
The property trace_enabled does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
50
		$this->startTimer('unprofiled');
51
	}
52
53
	// Public Methods
54
55
	public static function init() {
56
		Deprecation::notice('4.0', 'The Profiler class is deprecated, use third party tools like XHProf instead');
57
		if(!self::$inst) self::$inst = new Profiler(true,true);
0 ignored issues
show
Deprecated Code introduced by
The class Profiler has been deprecated with message: 4.0 The Profiler class is deprecated, use third party tools like XHProf instead

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the type will be removed from the class and what other constant to use instead.

Loading history...
58
	}
59
60
	public static function mark($name, $level2 = "", $desc = "") {
0 ignored issues
show
Coding Style introduced by
mark uses the super-global variable $_GET which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
61
		if($level2 && $_GET['debug_profile'] > 1) $name .= " $level2";
62
63
		if(!self::$inst) self::$inst = new Profiler(true,true);
0 ignored issues
show
Deprecated Code introduced by
The class Profiler has been deprecated with message: 4.0 The Profiler class is deprecated, use third party tools like XHProf instead

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the type will be removed from the class and what other constant to use instead.

Loading history...
64
65
		self::$inst->startTimer($name, $desc);
66
	}
67
	public static function unmark($name, $level2 = "", $desc = "") {
0 ignored issues
show
Coding Style introduced by
unmark uses the super-global variable $_GET which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
68
		if($level2 && $_GET['debug_profile'] > 1) $name .= " $level2";
69
70
		if(!self::$inst) self::$inst = new Profiler(true,true);
0 ignored issues
show
Deprecated Code introduced by
The class Profiler has been deprecated with message: 4.0 The Profiler class is deprecated, use third party tools like XHProf instead

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the type will be removed from the class and what other constant to use instead.

Loading history...
71
72
		self::$inst->stopTimer($name, $desc);
0 ignored issues
show
Unused Code introduced by
The call to Profiler::stopTimer() has too many arguments starting with $desc.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
73
	}
74
	public static function show($showTrace = false) {
75
		if(!self::$inst) self::$inst = new Profiler(true,true);
0 ignored issues
show
Deprecated Code introduced by
The class Profiler has been deprecated with message: 4.0 The Profiler class is deprecated, use third party tools like XHProf instead

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the type will be removed from the class and what other constant to use instead.

Loading history...
76
77
		echo "<div style=\"position: absolute; z-index: 100000; top: 20px; left: 20px; background-color: white;"
78
			. " padding: 20px; border: 1px #AAA solid; height: 80%; overflow: auto;\">";
79
		echo "<p><a href=\"#\" onclick=\"this.parentNode.parentNode.style.display = 'none'; return false;\">"
80
			. "(Click to close)</a></p>";
81
		self::$inst->printTimers();
82
		if($showTrace) self::$inst->printTrace();
83
		echo "</div>";
84
	}
85
86
	/**
87
	*   Start an individual timer
88
	*   This will pause the running timer and place it on a stack.
89
	*   @param string $name name of the timer
90
	*   @param string optional $desc description of the timer
91
	*/
92
	public function startTimer($name, $desc="" ){
93
		$this->trace.="start   $name\n";
94
		$n=array_push( $this->stack, $this->cur_timer );
95
		$this->__suspendTimer( $this->stack[$n-1] );
96
		$this->startTime[$name] = $this->getMicroTime();
97
		$this->cur_timer=$name;
98
		$this->description[$name] = $desc;
99
		if (!array_key_exists($name,$this->count))
100
			$this->count[$name] = 1;
101
		else
102
			$this->count[$name]++;
103
	}
104
105
	/**
106
	*   Stop an individual timer
107
	*   Restart the timer that was running before this one
108
	*   @param string $name name of the timer
109
	*/
110
	public function stopTimer($name){
111
		$this->trace.="stop    $name\n";
112
		$this->endTime[$name] = $this->getMicroTime();
113
		if (!array_key_exists($name, $this->running))
114
			$this->running[$name] = $this->elapsedTime($name);
115
		else
116
			$this->running[$name] += $this->elapsedTime($name);
117
		$this->cur_timer=array_pop($this->stack);
118
		$this->__resumeTimer($this->cur_timer);
119
	}
120
121
	/**
122
	*   measure the elapsed time of a timer without stoping the timer if
123
	*   it is still running
124
	*/
125
	public function elapsedTime($name){
126
		// This shouldn't happen, but it does once.
127
		if (!array_key_exists($name,$this->startTime))
128
			return 0;
129
130
		if(array_key_exists($name,$this->endTime)){
131
			return ($this->endTime[$name] - $this->startTime[$name]);
132
		} else {
133
			$now=$this->getMicroTime();
134
			return ($now - $this->startTime[$name]);
135
		}
136
	}//end start_time
137
138
	/**
139
	*   Measure the elapsed time since the profile class was initialised
140
	*
141
	*/
142
	public function elapsedOverall(){
143
		$oaTime = $this->getMicroTime() - $this->initTime;
144
		return($oaTime);
145
	}//end start_time
146
147
	/**
148
	*   print out a log of all the timers that were registered
149
	*
150
	*/
151
	public function printTimers($enabled=false)
152
	{
153
		if($this->output_enabled||$enabled){
154
			$TimedTotal = 0;
155
			$tot_perc = 0;
156
			ksort($this->description);
157
			print("<pre>\n");
158
			$oaTime = $this->getMicroTime() - $this->initTime;
159
			echo"============================================================================\n";
160
			echo "                              PROFILER OUTPUT\n";
161
			echo"============================================================================\n";
162
			print( "Calls                    Time  Routine\n");
163
			echo"-----------------------------------------------------------------------------\n";
164
			while (list ($key, $val) = each ($this->description)) {
0 ignored issues
show
Unused Code introduced by
The assignment to $val is unused. Consider omitting it like so list($first,,$third).

This checks looks for assignemnts to variables using the list(...) function, where not all assigned variables are subsequently used.

Consider the following code example.

<?php

function returnThreeValues() {
    return array('a', 'b', 'c');
}

list($a, $b, $c) = returnThreeValues();

print $a . " - " . $c;

Only the variables $a and $c are used. There was no need to assign $b.

Instead, the list call could have been.

list($a,, $c) = returnThreeValues();
Loading history...
165
				$t = $this->elapsedTime($key);
166
				$total = $this->running[$key];
167
				$count = $this->count[$key];
168
				$TimedTotal += $total;
169
				$perc = ($total/$oaTime)*100;
170
				$tot_perc+=$perc;
171
				// $perc=sprintf("%3.2f", $perc );
0 ignored issues
show
Unused Code Comprehensibility introduced by
59% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
172
				$lines[ sprintf( "%3d    %3.4f ms (%3.2f %%)  %s\n", $count, $total*1000, $perc, $key) ] = $total;
0 ignored issues
show
Coding Style Comprehensibility introduced by
$lines was never initialized. Although not strictly required by PHP, it is generally a good practice to add $lines = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
173
			}
174
			arsort($lines);
175
			foreach($lines as $line => $total) {
176
				echo $line;
177
			}
178
179
			echo "\n";
180
181
			$missed=$oaTime-$TimedTotal;
182
			$perc = ($missed/$oaTime)*100;
183
			$tot_perc+=$perc;
184
			// $perc=sprintf("%3.2f", $perc );
0 ignored issues
show
Unused Code Comprehensibility introduced by
59% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
185
			printf( "       %3.4f ms (%3.2f %%)  %s\n", $missed*1000,$perc, "Missed");
186
187
			echo"============================================================================\n";
188
189
			printf( "       %3.4f ms (%3.2f %%)  %s\n", $oaTime*1000,$tot_perc, "OVERALL TIME");
190
191
			echo"============================================================================\n";
192
193
			print("</pre>");
194
		}
195
	}
196
197
	public function printTrace( $enabled=false )
198
	{
199
		if($this->trace_enabled||$enabled){
200
			print("<pre>");
201
			print("Trace\n$this->trace\n\n");
202
			print("</pre>");
203
		}
204
	}
205
206
	/// Internal Use Only Functions
207
208
	/**
209
	* Get the current time as accuratly as possible
210
	*
211
	*/
212
	public function getMicroTime(){
213
		$tmp=explode(' ', microtime());
214
		$rt=$tmp[0]+$tmp[1];
215
		return $rt;
216
	}
217
218
	/**
219
	* resume  an individual timer
220
	*
221
	*/
222
	public function __resumeTimer($name){
223
		$this->trace.="resume  $name\n";
224
		$this->startTime[$name] = $this->getMicroTime();
225
	}
226
227
	/**
228
	*   suspend  an individual timer
229
	*
230
	*/
231
	public function __suspendTimer($name){
232
		$this->trace.="suspend $name\n";
233
		$this->endTime[$name] = $this->getMicroTime();
234
		if (!array_key_exists($name, $this->running))
235
			$this->running[$name] = $this->elapsedTime($name);
236
		else
237
			$this->running[$name] += $this->elapsedTime($name);
238
	}
239
}
240