Namespaces

  • Nette
    • Application
      • Diagnostics
      • Responses
      • Routers
      • UI
    • Caching
      • Storages
    • ComponentModel
    • Database
      • Diagnostics
      • Drivers
      • Reflection
      • Table
    • DI
      • Config
        • Adapters
      • Diagnostics
      • Extensions
    • Diagnostics
    • Forms
      • Controls
      • Rendering
    • Http
      • Diagnostics
    • Iterators
    • Latte
      • Macros
    • Loaders
    • Localization
    • Mail
    • PhpGenerator
    • Reflection
    • Security
      • Diagnostics
    • Templating
    • Utils
  • NetteModule
  • none

Classes

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