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