Dumper   A
last analyzed

Complexity

Total Complexity 36

Size/Duplication

Total Lines 167
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 0

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
dl 0
loc 167
ccs 89
cts 89
cp 1
rs 9.52
c 0
b 0
f 0
wmc 36
lcom 1
cbo 0

3 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 6 1
A dump() 0 4 1
F dumpVarData() 0 124 34
1
<?php
2
3
namespace PhpConsole;
4
5
/**
6
 * Convert any type of var to string or array with different kind of limits
7
 *
8
 * @package PhpConsole
9
 * @version 3.1
10
 * @link http://consle.com
11
 * @author Sergey Barbushin http://linkedin.com/in/barbushin
12
 * @copyright © Sergey Barbushin, 2011-2013. All rights reserved.
13
 * @license http://www.opensource.org/licenses/BSD-3-Clause "The BSD 3-Clause License"
14
 */
15
class Dumper {
16
17
	/** @var int Maximum array or object nested dump level */
18
	public $levelLimit;
19
	/** @var  int Maximum same level array items or object properties number */
20
	public $itemsCountLimit;
21
	/** @var  int Maximum length of any string or array item */
22
	public $itemSizeLimit;
23
	/** @var int|null Maximum approximate size of dump result formatted in JSON */
24
	public $dumpSizeLimit;
25
	/** @var bool Convert callback items to (callback SomeClass::someMethod) strings */
26
	public $detectCallbacks = true;
27
28
	/**
29
	 * @param int $levelLimit Maximum array or object nested dump level
30
	 * @param int $itemsCountLimit Maximum same level array items or object properties number
31
	 * @param int $itemSizeLimit Maximum length of any string or array item
32
	 * @param int $dumpSizeLimit Maximum approximate size of dump result formatted in JSON. Default is $itemsCountLimit * $itemSizeLimit
33
	 */
34 84
	public function __construct($levelLimit = 5, $itemsCountLimit = 100, $itemSizeLimit = 50000, $dumpSizeLimit = 500000) {
35 84
		$this->levelLimit = $levelLimit;
36 84
		$this->itemsCountLimit = $itemsCountLimit;
37 84
		$this->itemSizeLimit = $itemSizeLimit;
38 84
		$this->dumpSizeLimit = $dumpSizeLimit;
39 84
	}
40
41
	/**
42
	 * Convert any type of var to string or array applying all actual limits & transformations
43
	 * @param mixed $var
44
	 * @return string|array
45
	 */
46 58
	public function dump($var) {
47 58
		$this->dumpVarData($var, $this->levelLimit);
48 58
		return $var;
49
	}
50
51
	/**
52
	 * Recursively convert any type of var to string or array applying all actual limits & transformations
53
	 * @param $data
54
	 * @param $levelLimit
55
	 * @param bool $rootCall
56
	 */
57 58
	protected function dumpVarData(&$data, $levelLimit, $rootCall = true) {
58 58
		static $sizeLeft,
59 58
		$objectsHashes = array(),
60 58
		$origQueue = array(),
61 58
		$refQueue = array(),
62 58
		$levelsQueue = array();
63
64 58
		if($rootCall) {
65 58
			$sizeLeft = $this->dumpSizeLimit ? : 999999999;
66
		}
67
68 58
		if(is_object($data)) {
69 6
			if($data instanceof \Closure) {
70 1
				$data = '(callback function)';
71 1
				return;
72
			}
73 5
			if($rootCall) {
74 5
				$data = array('' => $data);
75 5
				return $this->dumpVarData($data, $levelLimit + 1);
76
			}
77 5
			$objectsHashes[] = spl_object_hash($data);
78 5
			$dataArray = array();
79 5
			foreach((array)$data as $key => $value) {
80 5
				$nullPos = strrpos($key, chr(0));
81 5
				if($nullPos) {
82 2
					$dataArray[substr($key, $nullPos + 1)] = $value;
83
				}
84
				else {
85 5
					$dataArray[$key] = $value;
86
				}
87
			}
88 5
			$data = $dataArray;
89
		}
90
91 58
		if(is_array($data)) {
92
93 11
			if($this->detectCallbacks && count($data) == 2 && is_callable($data)) {
94 1
				list($class, $method) = $data;
95 1
				$data = '(callback ' . (is_object($class) ? get_class($class) : $class) . '::' . $method . ')';
96 1
				$sizeLeft -= strlen($data) + 4;
97 1
				return;
98
			}
99
100 11
			$i = 0;
101 11
			$dataArray = array();
102 11
			foreach($data as $k => &$v) {
103 11
				if(($this->itemsCountLimit && $i >= $this->itemsCountLimit) || $sizeLeft <= 0) {
104 3
					break;
105
				}
106 11
				if(is_array($v) || is_object($v)) {
107 10
					if($levelLimit > 1) {
108 10
						$origQueue[] = $v;
109 10
						$refQueue[] =& $v;
110 10
						$levelsQueue[] = $levelLimit;
111
					}
112 10
					if(is_object($v) && !$v instanceof \Closure) {
113 5
						$k .= ':' . get_class($v);
114 5
						$hash = spl_object_hash($v);
115 5
						if(in_array($hash, $objectsHashes)) {
116 2
							$v = '*RECURSION*';
117
						}
118
						else {
119 5
							$v = '(object)';
120 5
							$objectsHashes[] = $hash;
121
						}
122
					}
123
					else {
124 7
						$v = '(array)';
125
					}
126 10
					$sizeLeft -= strlen($k) + strlen($v) + 8;
127
				}
128
				else {
129 8
					$sizeLeft -= strlen($k) + 4;
130 8
					$this->dumpVarData($v, $levelLimit - 1, false);
131
				}
132 11
				$dataArray[$k] =& $v;
133 11
				$i++;
134
			}
135
136 11
			if($i != count($data)) {
137 3
				$dataArray['...'] = '(displayed ' . $i . ' of ' . count($data) . ')';
138
			}
139 11
			$data = $dataArray;
140
141 11
			if(!$rootCall) {
142 8
				return;
143
			}
144
145
			do {
146 11
				$origData = array_shift($origQueue);
147 11
				$level = array_shift($levelsQueue);
148 11
				$refData =& $refQueue[0];
149 11
				array_shift($refQueue);
150 11
				$sizeLeft += strlen($refData);
151 11
				if($refData !== '*RECURSION*') {
152 11
					$this->dumpVarData($origData, $level - 1, false);
153 11
					$refData = $origData;
154
				}
155
			}
156 11
			while(count($origQueue) && $sizeLeft >= 0);
157
158 11
			if($rootCall) {
159 11
				$levelsQueue = $origQueue = $refQueue = $objectsHashes = array();
160
			}
161
		}
162
		// scalar or resource
163
		else {
164 55
			if(!is_scalar($data) && $data !== null) {
165 1
				if(is_resource($data)) {
166 1
					$data = '(' . strtolower((string)$data) . ' ' . get_resource_type($data) . ')';
167 1
					$sizeLeft -= strlen($data);
168 1
					return;
169
				}
170 1
				$data = var_export($data, true);
171
			}
172 55
			if(strlen($data) > $this->itemSizeLimit) {
173 8
				$data = substr($data, 0, $this->itemSizeLimit - 3) . '...';
174
			}
175 55
			if(strlen($data) > $sizeLeft) {
176 1
				$data = substr($data, 0, $sizeLeft - 3) . '...';
177
			}
178 55
			$sizeLeft -= strlen($data);
179
		}
180 58
	}
181
}
182