1: <?php
2:
3: 4: 5: 6: 7: 8: 9: 10: 11:
12:
13:
14:
15: 16: 17: 18: 19: 20:
21: class PhpHelpers
22: {
23: const PHP_IDENT = '[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*';
24:
25:
26: 27: 28: 29:
30: public static function dump($var)
31: {
32: return self::_dump($var);
33: }
34:
35:
36: private static function _dump(& $var, $level = 0)
37: {
38: if ($var instanceof PhpLiteral) {
39: return $var->value;
40:
41: } elseif (is_float($var)) {
42: $var = var_export($var, TRUE);
43: return strpos($var, '.') === FALSE ? $var . '.0' : $var;
44:
45: } elseif (is_bool($var)) {
46: return $var ? 'TRUE' : 'FALSE';
47:
48: } elseif (is_string($var) && (preg_match('#[^\x09\x20-\x7E\xA0-\x{10FFFF}]#u', $var) || preg_last_error())) {
49: static $table;
50: if ($table === NULL) {
51: foreach (range("\x00", "\xFF") as $ch) {
52: $table[$ch] = ord($ch) < 32 || ord($ch) >= 127
53: ? '\\x' . str_pad(dechex(ord($ch)), 2, '0', STR_PAD_LEFT)
54: : $ch;
55: }
56: $table["\r"] = '\r';
57: $table["\n"] = '\n';
58: $table["\t"] = '\t';
59: $table['$'] = '\\$';
60: $table['\\'] = '\\\\';
61: $table['"'] = '\\"';
62: }
63: return '"' . strtr($var, $table) . '"';
64:
65: } elseif (is_array($var)) {
66: $s = '';
67: $space = str_repeat("\t", $level);
68:
69: static $marker;
70: if ($marker === NULL) {
71: $marker = uniqid("\x00", TRUE);
72: }
73: if (empty($var)) {
74:
75: } elseif ($level > 50 || isset($var[$marker])) {
76: throw new InvalidArgumentException('Nesting level too deep or recursive dependency.');
77:
78: } else {
79: $s .= "\n";
80: $var[$marker] = TRUE;
81: $counter = 0;
82: foreach ($var as $k => & $v) {
83: if ($k !== $marker) {
84: $s .= "$space\t" . ($k === $counter ? '' : self::_dump($k) . " => ") . self::_dump($v, $level + 1) . ",\n";
85: $counter = is_int($k) ? max($k + 1, $counter) : $counter;
86: }
87: }
88: unset($var[$marker]);
89: $s .= $space;
90: }
91: return "array($s)";
92:
93: } elseif (is_object($var)) {
94: $arr = (array) $var;
95: $s = '';
96: $space = str_repeat("\t", $level);
97:
98: static $list = array();
99: if (empty($arr)) {
100:
101: } elseif ($level > 50 || in_array($var, $list, TRUE)) {
102: throw new InvalidArgumentException('Nesting level too deep or recursive dependency.');
103:
104: } else {
105: $s .= "\n";
106: $list[] = $var;
107: foreach ($arr as $k => & $v) {
108: if ($k[0] === "\x00") {
109: $k = substr($k, strrpos($k, "\x00") + 1);
110: }
111: $s .= "$space\t" . self::_dump($k) . " => " . self::_dump($v, $level + 1) . ",\n";
112: }
113: array_pop($list);
114: $s .= $space;
115: }
116: return get_class($var) === 'stdClass'
117: ? "(object) array($s)"
118: : __CLASS__ . "::createObject('" . get_class($var) . "', array($s))";
119:
120: } else {
121: return var_export($var, TRUE);
122: }
123: }
124:
125:
126: 127: 128: 129:
130: public static function format($statement)
131: {
132: $args = func_get_args();
133: return self::formatArgs(array_shift($args), $args);
134: }
135:
136:
137: 138: 139: 140:
141: public static function formatArgs($statement, array $args)
142: {
143: $a = strpos($statement, '?');
144: while ($a !== FALSE) {
145: if (!$args) {
146: throw new InvalidArgumentException('Insufficient number of arguments.');
147: }
148: $arg = array_shift($args);
149: if (substr($statement, $a + 1, 1) === '*') {
150: if (!is_array($arg)) {
151: throw new InvalidArgumentException('Argument must be an array.');
152: }
153: $arg = implode(', ', array_map(array(__CLASS__, 'dump'), $arg));
154: $statement = substr_replace($statement, $arg, $a, 2);
155:
156: } else {
157: $arg = substr($statement, $a - 1, 1) === '$' || in_array(substr($statement, $a - 2, 2), array('->', '::'))
158: ? self::formatMember($arg) : self::_dump($arg);
159: $statement = substr_replace($statement, $arg, $a, 1);
160: }
161: $a = strpos($statement, '?', $a + strlen($arg));
162: }
163: return $statement;
164: }
165:
166:
167: 168: 169: 170:
171: public static function formatMember($name)
172: {
173: return $name instanceof PhpLiteral || !self::isIdentifier($name)
174: ? '{' . self::_dump($name) . '}'
175: : $name ;
176: }
177:
178:
179: 180: 181:
182: public static function isIdentifier($value)
183: {
184: return is_string($value) && preg_match('#^' . self::PHP_IDENT . '\z#', $value);
185: }
186:
187:
188: public static function createObject($class, array $props)
189: {
190: return unserialize('O' . substr(serialize((string) $class), 1, -1) . substr(serialize($props), 1));
191: }
192:
193: }
194: