1+ <?php
2+ namespace Dumphper ;
3+ /**
4+ * Impored var_dump for PHP 5.2.3++
5+ * @author Dmitry "widowmaker" Khavilo
6+ * @email wm .dot. morgun .at. gmail .dot. com
7+ **/
8+
9+ // Fixed by S
10+
11+ define ('DPHP_USE_ACCESSIBLE ' , true );
12+
13+ class Dumphper
14+ {
15+ /** config **/
16+
17+ static $ encoding = 'UTF-8 ' ; /** Text encoding, needed to escape stings **/
18+ static $ escape_keys = false ; /** Should array keys be escaped (slow) **/
19+ static $ max_showw_depth = 8 ; /** Defines how many nested levels will be expanded by default **/
20+
21+ /** don't touch **/
22+ static $ objects = array ();
23+ static $ calls = 0 ;
24+ static $ depth = 0 ;
25+ static $ objectStorage ;
26+
27+ static function dump (&$ source )
28+ {
29+ if (class_exists ('SplObjectStorage ' )) {
30+ self ::$ objectStorage = new SplObjectStorage ();
31+ }
32+ self ::$ depth = 0 ;
33+ self ::drawStyles ();
34+ //$s = microtime(true);
35+ //self::$objects = array();
36+ self ::$ calls ++;
37+ echo '<div class="dumphper"> ' ;
38+ self ::_dump ($ source );
39+ echo '</div> ' ;
40+ //echo round(microtime(true) - $s,6)*1000 . 's';
41+ }
42+
43+ static function _dump (&$ source , &$ parents = array ())
44+ {
45+ self ::$ depth ++;
46+ switch (gettype ($ source ))
47+ {
48+ case 'array ' :
49+ self ::drawArray ($ source , $ parents );
50+ break ;
51+ case 'object ' :
52+ self ::drawObject ($ source , $ parents );
53+ break ;
54+ case 'NULL ' :
55+ self ::drawNULL ();
56+ break ;
57+ case 'boolean ' :
58+ self ::drawBoolean ($ source );
59+ break ;
60+ case 'resource ' :
61+ self ::drawResource ($ source );
62+ break ;
63+ default :
64+ self ::drawScalar ($ source );
65+ break ;
66+ }
67+ self ::$ depth --;
68+ }
69+
70+ static function escape (&$ source )
71+ {
72+ return ( is_string ($ source ) ? ( $ source ? htmlentities ($ source , ENT_QUOTES , self ::$ encoding ) : ' ' ) : $ source );
73+ }
74+
75+ static function drawScalar (&$ source , &$ escape = true )
76+ {
77+ if ($ source === '0 ' ) $ escape = False ;
78+ $ type = gettype ($ source );
79+ // $type = $type == 'string' ? $type.'('.mb_strlen($value).')' : $type;
80+ $ value = $ escape ? self ::escape ($ source ) : $ source ;
81+ $ value = $ type == 'string ' ? '<span class="strlen">( ' .mb_strlen ($ source ).')</span> ' .$ value : $ value ;
82+
83+ self ::drawValue ($ value , $ type );
84+ }
85+
86+ static function drawNULL ()
87+ {
88+ self ::drawValue ('NULL ' , 'null ' );
89+ }
90+
91+ static function drawResource (&$ source )
92+ {
93+ self ::drawValue (get_resource_type ($ source ) . ' ' . strtolower ((string )$ source ) , 'resource ' );
94+ }
95+
96+ static function drawBoolean (&$ source )
97+ {
98+ self ::drawValue ($ source ? 'true ' : 'false ' , 'boolean ' );
99+ }
100+
101+ static function drawArray (&$ source , &$ parents )
102+ {
103+ if (self ::isRecursiveArray ($ source , $ parents ))
104+ {
105+ self ::drawValue ('RECURSION ' , 'recursion ' );
106+ }
107+ else
108+ {
109+ $ c = count ($ source );
110+ echo '<div class="dumphper-container ' . (self ::$ depth <= self ::$ max_showw_depth ? '' : ' dumphper-closed ' ) . '"> ' ;
111+ self ::drawHeader ( $ c > 0 ? '<a class="dumphper-toggler" href="javascript:;" onclick="dumphper_toggle(this);">Array ( ' . $ c . ')</a> ' : 'empty Array ' , 'array ' );
112+ if ( $ c > 0 )
113+ {
114+ echo '<table class="dumphper-table" cellspacing="0" cellpadding="0"> ' ;
115+ foreach ($ source as $ key => &$ value )
116+ {
117+ echo '<tr><td class="dumphper-key-array"> ' ;
118+ self ::drawScalar ($ key , self ::$ escape_keys );
119+ echo '</td><td> ' ;
120+ self ::_dump ($ value , $ parents );
121+ echo '</td></tr> ' ;
122+ }
123+ echo '</table> ' ;
124+ }
125+ echo '</div> ' ;
126+ }
127+ }
128+
129+ static function getObjectId (&$ source )
130+ {
131+ $ class = get_class ($ source );
132+ if ( !isset (self ::$ objects [$ class ]) )
133+ self ::$ objects [$ class ] = array ();
134+ foreach (self ::$ objects [$ class ] as $ id => $ obj )
135+ if ( $ source === $ obj )
136+ return $ id ;
137+ self ::$ objects [$ class ][] = &$ source ;
138+ return count (self ::$ objects [$ class ])-1 ;
139+ }
140+
141+ static function drawObject (&$ source , &$ parents )
142+ {
143+ $ className = get_class ($ source );
144+ $ object_index = self ::getObjectId ($ source );
145+ $ object_id = 'dhph_ ' . $ className . '_ ' . self ::$ calls . '_ ' . $ object_index ;
146+
147+ if (self ::isRecursiveObject ($ source , $ parents ))
148+ {
149+ self ::drawValue ('<a href="# ' . $ object_id . '" onclick="dumphper_show(this);"> ' . $ className . ' # ' . $ object_index . '</a> ' , 'recursion ' );
150+ }
151+ else
152+ {
153+ $ sClass = new ReflectionObject ($ source );
154+ $ statics = null ;
155+ $ class = $ sClass ->getParentClass ();
156+ $ classArray = '' ;
157+ while ( is_object ($ class ) )
158+ {
159+ $ classArray = ' > ' . $ class ->getName () . $ classArray ;
160+ $ class = $ class ->getParentClass ();
161+ }
162+
163+ echo '<div class="dumphper-container ' . (self ::$ depth <= self ::$ max_showw_depth ? '' : ' dumphper-closed ' ) . '"> ' ;
164+ self ::drawHeader ( '<a id=" ' . $ object_id . '" name=" ' . $ object_id . '" class="dumphper-toggler" href="javascript:;" onclick="dumphper_toggle(this);"> ' . $ className . ' # ' . $ object_index .
165+ (count ($ classArray ) ? ' <span class="dumphper-class-def"> ' . $ classArray . '</span> ' : '' ).
166+ '</a> ' , 'object ' );
167+ echo '<table class="dumphper-table" cellspacing="0" cellpadding="0"> ' ;
168+
169+ if (!DPHP_USE_ACCESSIBLE )
170+ $ temp = (array )$ source ;
171+
172+ $ class = $ sClass ;
173+ while ( is_object ($ class ) )
174+ {
175+ $ properties = $ class ->getProperties ();
176+ if ($ class ->name != $ className && count ($ properties ))
177+ {
178+ echo '<tr><td colspan = "2"> ' ;
179+ self ::drawValue ('<code>inherited from </code> ' . $ class ->name . ': ' , 'inherited ' );
180+ echo '</td></tr> ' ;
181+ }
182+ foreach ($ properties as &$ value )
183+ {
184+ $ declaredClass = $ value ->getDeclaringClass ()->name ;
185+ if ($ class ->name == $ declaredClass )
186+ {
187+ echo '<tr><td class="dumphper-key-object"> ' ;
188+ self ::drawValue ($ value ->name /* . ' <span class="dumphper-class-def">' . $declaredClass . '</span>'*/ , join ('- ' ,Reflection::getModifierNames ($ value ->getModifiers ())));
189+ echo '</td><td> ' ;
190+ if ($ value ->isPublic ()) {
191+ $ tmp = $ value ->getValue ($ source );
192+ self ::_dump ($ tmp , $ parents );
193+ }
194+ /** in case of PHP 5.3+ **/
195+ elseif (DPHP_USE_ACCESSIBLE )
196+ {
197+ $ value ->setAccessible (true );
198+ $ tmp = $ value ->getValue ($ source );
199+ self ::_dump ($ tmp , $ parents );
200+ }
201+ /** in case of PHP 5.2.x+ **/
202+ elseif ($ value ->isStatic ())
203+ {
204+ if (!$ statics ) $ statics = $ class ->getStaticProperties ();
205+ self ::_dump ($ statics [$ value ->name ], $ parents );
206+ }
207+ else
208+ {
209+ $ scope = $ value ->isPrivate () ? $ value ->class : '* ' ;
210+ self ::_dump ($ temp ["\0{$ scope }\0{$ value ->name }" ], $ parents );
211+ }
212+ echo '</td></tr> ' ;
213+ }
214+ }
215+ $ class = $ class ->getParentClass ();
216+ }
217+ echo '</table> ' ;
218+ echo '</div> ' ;
219+ }
220+ }
221+
222+ static function isRecursiveArray (&$ source , &$ parents )
223+ {
224+ if ( count ($ parents ) > 0 )
225+ {
226+ $ uKey = uniqid ('array ' , true );
227+ $ source [$ uKey ] = true ;
228+ foreach ( $ parents as &$ parrent )
229+ {
230+ if ( is_array ($ parrent ) && isset ($ parrent [$ uKey ]) )
231+ {
232+ unset($ source [$ uKey ]);
233+ return true ;
234+ }
235+ }
236+ unset($ source [$ uKey ]);
237+ }
238+ $ parents [] = &$ source ;
239+ return false ;
240+ }
241+
242+ static function isRecursiveObject (&$ source , &$ parents )
243+ {
244+ if (self ::$ objectStorage ) {
245+ if (self ::$ objectStorage ->contains ($ source )) {
246+ return true ;
247+ }
248+ self ::$ objectStorage ->attach ($ source );
249+ } else {
250+ if ( in_array ($ source , $ parents , true ) ) {
251+ return true ;
252+ }
253+ $ parents [] = &$ source ;
254+ }
255+ return false ;
256+ }
257+
258+ static function drawValue ($ value , $ type )
259+ {
260+ echo '<span class="dumphper-value dumphper- ' . $ type . '" title=" ' . $ type . '"> ' . $ value . '</span> ' ;
261+ }
262+
263+ static function drawHeader ($ value , $ type )
264+ {
265+ echo '<div class="dumphper-head dumphper-head- ' . $ type . '" title=" ' . $ type . '"> ' . $ value .'</div> ' ;
266+ }
267+
268+ static function drawStyles ()
269+ {
270+ static $ displayed = false ;
271+ if ($ displayed ) return ; //Exit if already shown
272+ $ displayed = true ;
273+ ?> <style type="text/css">
274+ .dumphper { margin: 0 0 3px !important; /*max-width:500px !important;*/}
275+ .dumphper-container { display: inline-block !important; position: relative !important; }
276+ .dumphper-value { background-color: #e7e7e7 !important; border: 1px solid #888 !important; }
277+ .dumphper-table { border-left: 1px solid #888 !important; width: 100%; }
278+ .dumphper-table td { border-right: 1px solid #888 !important; border-bottom: 1px solid #888 !important; vertical-align: top !important;}
279+ .dumphper-table .dumphper-value { border-width: 0 0 0 0 !important;display: block;}
280+ .dumphper, .dumphper-value, .dumphper-key, .dumphper-head { font: normal 12px Arial !important; line-height: 15px !important;}
281+ .dumphper-value { padding: 0 3px 0 12px !important; background-repeat: no-repeat !important; cursor: default !important;max-height: 45px; overflow: auto;}
282+ .dumphper-key { padding: 0 3px !important; }
283+ .dumphper-head { color: #fff !important; background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAJCAYAAADzRkbkAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAACRJREFUeNpi+P//fw8TAwPDfxDxFUR8gROf4axvDEB10gABBgAvWg1pnyJeXQAAAABJRU5ErkJggg==) !important; background-repeat: repeat-x !important; padding: 1px 3px 2px !important; border: 1px solid #888 !important; font-weight: bold !important; }
284+ .dumphper-head-array { background-color: #260 !important;}
285+ .dumphper-key-array, .dumphper-key-array .dumphper-value { background-color: #dcffd0 !important;}
286+ .dumphper-key-array .dumphper-string { color: #030 !important; }
287+ .dumphper-key-array .dumphper-string, .dumphper-key-array .dumphper-integer { background-image: none !important; padding-left: 3px !important;}
288+ .dumphper-key-object { color: #004 !important;}
289+ .dumphper-head-object { background-color: #006 !important;}
290+ .dumphper-key-object, .dumphper-key-object .dumphper-value { background-color: #c8defe !important; }
291+ .dumphper-class-def { color: #666 !important; font: bold oblique 11px Arial !important;}
292+ .dumphper-head-object .dumphper-class-def { color: #bbb !important;}
293+ .dumphper-string { color: #a40 !important; background-image: url(data:image/gif;base64,R0lGODlhCgASAIAAAP/Qmv///yH5BAAAAAAALAAAAAAKABIAAAISjI+py+0MYkRzSQBlpvf5D34FADs=) !important; }
294+ .dumphper-string .strlen { display: inline-block; background: none; color: #000; font-size: 8px; margin-right: 3px; vertical-align: bottom;}
295+ .dumphper-integer { color: #00f !important; background-image: url(data:image/gif;base64,R0lGODlhCgASAIAAAKTC/////yH5BAAAAAAALAAAAAAKABIAAAIVjI+pqwDsGHRvRVtbThdRKoXiSC4FADs=) !important; }
296+ .dumphper-double { color: #f00 !important; background-image: url(data:image/gif;base64,R0lGODlhCgASAIAAAP+/v////yH5BAAAAAAALAAAAAAKABIAAAIWjI+pu+CQHJPxUXTrhI1j6zHiSJZiAQA7) !important; }
297+ .dumphper-resource { color: #660 !important; background-image: url(data:image/gif;base64,R0lGODlhCgASAIAAAP///8zMfyH5BAAAAAAALAAAAAAKABIAAAIVhI+py+0bYgAxSWon1Kpm6T3iSDYFADs=) !important; }
298+ .dumphper-null { color: #000 !important; background-image: url(data:image/gif;base64,R0lGODlhIgASAIAAAL+/v////yH5BAAAAAAALAAAAAAiABIAAAI+jI+py+0Po5wBWHAupswmzy1gtiEaeFWj+pXmhsLuyiqxcZOtKOO9/uL5hjUi8CVLpk4YZugJjUqn1KqVUQAAOw==) !important; padding-left: 37px !important; }
299+ .dumphper-boolean { color: #000 !important; background-image: url(data:image/gif;base64,R0lGODlhIgASAIAAAL+/v////yH5BAAAAAAALAAAAAAiABIAAAI+jI+py+0PYwRULlpVthpcz3VfsJEYgoFGeZzZC8Ktisb2epvzqPdyD6x5fkQVyzSkpYS2ZegJjUqn1KqVUwAAOw==) !important; padding-left: 37px !important; }
300+ .dumphper-inherited { color: #009 !important; background-color: #c8defe !important; /*background-image: url(data:image/gif;base64,R0lGODlhSgASAIABAH9/5f///yH5BAEAAAEALAAAAABKABIAAAJ2jI+py+0Po5y02ospAHDzbGyZt4jdB5ohGqmXCyLwA3uo7eIyGdj951vxfjnO7LdbHUxM4E3EKiaRyOFUSaU2g9lrF+fEJqTZpti7jKoVZva6HC6nS2/jTWklknj7rdDJBZb2JJUXc4iYqLjI2Oj4CBkpOblYAAA7) !important;*/ padding-left: /*7*/4px !important; font-weight: bold !important; }
301+ .dumphper-inherited code { font: 12px Arial; color: #66c !important; }
302+ .dumphper-recursion { color: #609 !important; background-image: url(data:image/gif;base64,R0lGODlhEAASAIAAAP/Uf////yH5BAAAAAAALAAAAAAQABIAAAIejI+py+0PIwMUmGoRvZXrHGzeIWIj2YWpxLbuC0sFADs=) !important; padding-left: 19px !important; font-weight: bold !important; }
303+ .dumphper-recursion a { color: #609 !important; text-decoration: underline !important; }
304+ .dumphper-private { background-image: url(data:image/gif;base64,R0lGODlhCwASAJEAAP///zMzM/8zMwAAACH5BAAAAAAALAAAAAALABIAAAIdhI+py30RWhCRzfrgpGhTwRnahnVhclmlw7auUwAAOw==) !important;}
305+ .dumphper-protected { background-image: url(data:image/gif;base64,R0lGODlhCwASAJEAAP/eADMzM////wAAACH5BAAAAAAALAAAAAALABIAAAIdlI+py30RWgCRzfrgpGhTwBnahnVhclmlw7auUwAAOw==) !important;}
306+ .dumphper-public { background-image: url(data:image/gif;base64,R0lGODlhCwASAJEAAADdADMzM////wAAACH5BAAAAAAALAAAAAALABIAAAIdlI+py30RWgCRzfrgpGhTwBnahnVhclmlw7auUwAAOw==) !important;}
307+ .dumphper-private-static { background-image: url(data:image/gif;base64,R0lGODlhCwASAJEAAP///zMzM/8zMwAAACH5BAAAAAAALAAAAAALABIAAAIdhI+pyw0BY0BBiHqpxfPI6CQfpF1byVFjyLbuUgAAOw==) !important;}
308+ .dumphper-protected-static { background-image: url(data:image/gif;base64,R0lGODlhCwASAJEAAP///zMzM//eAAAAACH5BAAAAAAALAAAAAALABIAAAIdhI+pyw0BY0BBiHqpxfPI6CQfpF1byVFjyLbuUgAAOw==) !important;}
309+ .dumphper-public-static { background-image: url(data:image/gif;base64,R0lGODlhCwASAJEAAP///zMzMwDdAAAAACH5BAAAAAAALAAAAAALABIAAAIdhI+pyw0BY0BBiHqpxfPI6CQfpF1byVFjyLbuUgAAOw==) !important;}
310+ .dumphper-toggler { color: #fff !important; display: block; background: url(data:image/gif;base64,R0lGODlhCgAKAJEAAOfn5zMzM////wAAACH5BAEAAAIALAAAAAAKAAoAAAISlI+pe+HvRAC0UmdtkPCxDyIFADs=) 1px 3px no-repeat !important; padding-left: 14px !important; text-decoration: none !important; cursor: pointer !important;}
311+ .dumphper-closed .dumphper-toggler { background-image: url(data:image/gif;base64,R0lGODlhCgAKAJEAAOfn5zMzM////wAAACH5BAEAAAIALAAAAAAKAAoAAAIZlBVxGwC6kIMmtZek2/PyiSQdpZEVGIVLAQA7) !important; }
312+ .dumphper-closed .dumphper-table, .dumphper-closed .dumphper-class-def { display: none !important; }
313+ </style>
314+ <script type="text/javascript">
315+ function dumphper_toggle(obj)
316+ {
317+ obj.parentNode.parentNode.className = (obj.parentNode.parentNode.className == 'dumphper-container' ? 'dumphper-container dumphper-closed' : 'dumphper-container');
318+ }
319+ function dumphper_show(source_obj)
320+ {
321+ obj = document.getElementById(source_obj.href.match(/[^#]+$/));
322+ while(obj = obj.parentNode)
323+ if (obj.className == 'dumphper-container dumphper-closed')
324+ obj.className = 'dumphper-container';
325+ }
326+ </script><?php
327+ }
328+ }
329+
330+ /** Comment if you don't need this **/
331+ //function dump(&$var) { Dumphper::dump($var); }
0 commit comments