Namespaces

  • Latte
    • Loaders
    • Macros
    • Runtime
  • Nette
    • Application
      • Responses
      • Routers
      • UI
    • Bridges
      • ApplicationDI
      • ApplicationLatte
      • ApplicationTracy
      • CacheDI
      • CacheLatte
      • DatabaseDI
      • DatabaseTracy
      • DITracy
      • FormsDI
      • FormsLatte
      • Framework
      • HttpDI
      • HttpTracy
      • MailDI
      • ReflectionDI
      • SecurityDI
      • SecurityTracy
    • Caching
      • Storages
    • ComponentModel
    • Database
      • Conventions
      • Drivers
      • Reflection
      • Table
    • DI
      • Config
        • Adapters
      • Extensions
    • Forms
      • Controls
      • Rendering
    • Http
    • Iterators
    • Loaders
    • Localization
    • Mail
    • Neon
    • PhpGenerator
    • Reflection
    • Security
    • Utils
  • none
  • Tracy
    • Bridges
      • Nette

Classes

  • ClassType
  • Helpers
  • Method
  • Parameter
  • PhpFile
  • PhpLiteral
  • PhpNamespace
  • Property
  • Overview
  • Namespace
  • Class
  • Tree
  • Deprecated
  • Other releases
  • Nette homepage
  1: <?php
  2: 
  3: /**
  4:  * This file is part of the Nette Framework (https://nette.org)
  5:  * Copyright (c) 2004 David Grudl (https://davidgrudl.com)
  6:  */
  7: 
  8: namespace Nette\PhpGenerator;
  9: 
 10: use Nette;
 11: 
 12: 
 13: /**
 14:  * PHP code generator utils.
 15:  */
 16: class Helpers
 17: {
 18:     const PHP_IDENT = '[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*';
 19:     const MAX_DEPTH = 50;
 20: 
 21: 
 22:     /**
 23:      * Returns a PHP representation of a variable.
 24:      * @return string
 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 PhpLiteral) {
 35:             return (string) $var;
 36: 
 37:         } elseif (is_float($var)) {
 38:             if (is_finite($var)) {
 39:                 $var = var_export($var, TRUE);
 40:                 return strpos($var, '.') === FALSE ? $var . '.0' : $var; // workaround for PHP < 7.0.2
 41:             }
 42:             return str_replace('.0', '', var_export($var, TRUE)); // workaround for PHP 7.0.2
 43: 
 44:         } elseif (is_bool($var)) {
 45:             return $var ? 'TRUE' : 'FALSE';
 46: 
 47:         } elseif (is_string($var) && (preg_match('#[^\x09\x20-\x7E\xA0-\x{10FFFF}]#u', $var) || preg_last_error())) {
 48:             static $table;
 49:             if ($table === NULL) {
 50:                 foreach (array_merge(range("\x00", "\x1F"), range("\x7F", "\xFF")) as $ch) {
 51:                     $table[$ch] = '\x' . str_pad(dechex(ord($ch)), 2, '0', STR_PAD_LEFT);
 52:                 }
 53:                 $table['\\'] = '\\\\';
 54:                 $table["\r"] = '\r';
 55:                 $table["\n"] = '\n';
 56:                 $table["\t"] = '\t';
 57:                 $table['$'] = '\$';
 58:                 $table['"'] = '\"';
 59:             }
 60:             return '"' . strtr($var, $table) . '"';
 61: 
 62:         } elseif (is_string($var)) {
 63:             return "'" . preg_replace('#\'|\\\\(?=[\'\\\\]|\z)#', '\\\\$0', $var) . "'";
 64: 
 65:         } elseif (is_array($var)) {
 66:             $space = str_repeat("\t", $level);
 67: 
 68:             static $marker;
 69:             if ($marker === NULL) {
 70:                 $marker = uniqid("\x00", TRUE);
 71:             }
 72:             if (empty($var)) {
 73:                 $out = '';
 74: 
 75:             } elseif ($level > self::MAX_DEPTH || isset($var[$marker])) {
 76:                 throw new Nette\InvalidArgumentException('Nesting level too deep or recursive dependency.');
 77: 
 78:             } else {
 79:                 $out = '';
 80:                 $outAlt = "\n$space";
 81:                 $var[$marker] = TRUE;
 82:                 $counter = 0;
 83:                 foreach ($var as $k => & $v) {
 84:                     if ($k !== $marker) {
 85:                         $item = ($k === $counter ? '' : self::_dump($k, $level + 1) . ' => ') . self::_dump($v, $level + 1);
 86:                         $counter = is_int($k) ? max($k + 1, $counter) : $counter;
 87:                         $out .= ($out === '' ? '' : ', ') . $item;
 88:                         $outAlt .= "\t$item,\n$space";
 89:                     }
 90:                 }
 91:                 unset($var[$marker]);
 92:             }
 93:             return 'array(' . (strpos($out, "\n") === FALSE && strlen($out) < 40 ? $out : $outAlt) . ')';
 94: 
 95:         } elseif ($var instanceof \Serializable) {
 96:             $var = serialize($var);
 97:             return 'unserialize(' . self::_dump($var, $level) . ')';
 98: 
 99:         } elseif ($var instanceof \Closure) {
100:             throw new Nette\InvalidArgumentException('Cannot dump closure.');
101: 
102:         } elseif (is_object($var)) {
103:             if (PHP_VERSION_ID >= 70000 && ($rc = new \ReflectionObject($var)) && $rc->isAnonymous()) {
104:                 throw new Nette\InvalidArgumentException('Cannot dump anonymous class.');
105:             }
106:             $arr = (array) $var;
107:             $space = str_repeat("\t", $level);
108:             $class = get_class($var);
109: 
110:             static $list = array();
111:             if ($level > self::MAX_DEPTH || in_array($var, $list, TRUE)) {
112:                 throw new Nette\InvalidArgumentException('Nesting level too deep or recursive dependency.');
113: 
114:             } else {
115:                 $out = "\n";
116:                 $list[] = $var;
117:                 if (method_exists($var, '__sleep')) {
118:                     foreach ($var->__sleep() as $v) {
119:                         $props[$v] = $props["\x00*\x00$v"] = $props["\x00$class\x00$v"] = TRUE;
120:                     }
121:                 }
122:                 foreach ($arr as $k => & $v) {
123:                     if (!isset($props) || isset($props[$k])) {
124:                         $out .= "$space\t" . self::_dump($k, $level + 1) . ' => ' . self::_dump($v, $level + 1) . ",\n";
125:                     }
126:                 }
127:                 array_pop($list);
128:                 $out .= $space;
129:             }
130:             return $class === 'stdClass'
131:                 ? "(object) array($out)"
132:                 : __CLASS__ . "::createObject('$class', array($out))";
133: 
134:         } elseif (is_resource($var)) {
135:             throw new Nette\InvalidArgumentException('Cannot dump resource.');
136: 
137:         } else {
138:             return var_export($var, TRUE);
139:         }
140:     }
141: 
142: 
143:     /**
144:      * Generates PHP statement.
145:      * @return string
146:      */
147:     public static function format($statement)
148:     {
149:         $args = func_get_args();
150:         return self::formatArgs(array_shift($args), $args);
151:     }
152: 
153: 
154:     /**
155:      * Generates PHP statement.
156:      * @return string
157:      */
158:     public static function formatArgs($statement, array $args)
159:     {
160:         $a = strpos($statement, '?');
161:         while ($a !== FALSE) {
162:             if (!$args) {
163:                 throw new Nette\InvalidArgumentException('Insufficient number of arguments.');
164:             }
165:             $arg = array_shift($args);
166:             if (substr($statement, $a + 1, 1) === '*') { // ?*
167:                 if (!is_array($arg)) {
168:                     throw new Nette\InvalidArgumentException('Argument must be an array.');
169:                 }
170:                 $s = substr($statement, 0, $a);
171:                 $sep = '';
172:                 foreach ($arg as $tmp) {
173:                     $s .= $sep . self::dump($tmp);
174:                     $sep = strlen($s) - strrpos($s, "\n") > 100 ? ",\n\t" : ', ';
175:                 }
176:                 $statement = $s . substr($statement, $a + 2);
177:                 $a = strlen($s);
178: 
179:             } else {
180:                 $arg = substr($statement, $a - 1, 1) === '$' || in_array(substr($statement, $a - 2, 2), array('->', '::'), TRUE)
181:                     ? self::formatMember($arg) : self::_dump($arg);
182:                 $statement = substr_replace($statement, $arg, $a, 1);
183:                 $a += strlen($arg);
184:             }
185:             $a = strpos($statement, '?', $a);
186:         }
187:         return $statement;
188:     }
189: 
190: 
191:     /**
192:      * Returns a PHP representation of a object member.
193:      * @return string
194:      */
195:     public static function formatMember($name)
196:     {
197:         return $name instanceof PhpLiteral || !self::isIdentifier($name)
198:             ? '{' . self::_dump($name) . '}'
199:             : $name;
200:     }
201: 
202: 
203:     /**
204:      * @return bool
205:      */
206:     public static function isIdentifier($value)
207:     {
208:         return is_string($value) && preg_match('#^' . self::PHP_IDENT . '\z#', $value);
209:     }
210: 
211: 
212:     /** @internal */
213:     public static function createObject($class, array $props)
214:     {
215:         return unserialize('O' . substr(serialize((string) $class), 1, -1) . substr(serialize($props), 1));
216:     }
217: 
218: 
219:     /**
220:      * @param  string
221:      * @return string
222:      */
223:     public static function extractNamespace($name)
224:     {
225:         return ($pos = strrpos($name, '\\')) ? substr($name, 0, $pos) : '';
226:     }
227: 
228: 
229:     /**
230:      * @param  string
231:      * @return string
232:      */
233:     public static function extractShortName($name)
234:     {
235:         return ($pos = strrpos($name, '\\')) === FALSE ? $name : substr($name, $pos + 1);
236:     }
237: 
238: }
239: 
Nette 2.3-20161221 API API documentation generated by ApiGen 2.8.0