/** * 创建一个文件,多服务器可以自动同步 * * @param string $file * @param $data * @param $flags * @param $context * @param string $storage 物理存储组,不传则为默认 * @return boolean */ public static function create_file($file, $data, $flags = null, $context = null, $storage = 'default') { $info = File::check_and_get_path($file); # 系统禁用了写入功能 if (Core::is_file_write_disabled()) { return false; } if (File::can_do_run($storage)) { # 系统内部运行时或小于等于1台服时执行 $dir = substr($file, 0, (int) strrpos(str_replace('\\', '/', $file), '/')); if ($dir && !is_dir($dir)) { # 没有文件夹先则创建 File::create_dir($dir); } if (false !== @file_put_contents($file, $data, $flags, $context)) { @chmod($file, 0666); return true; } else { if (IS_DEBUG) { Core::debug()->error('create file error:' . Core::debug_path($file)); } return false; } } else { return File::call_http_host($storage, 'file/create_file', $info[0], $info[1], $data, $flags, $context); } }
/** * 创建一个文件,多服务器可以自动同步 * * @param string $file * @param $data * @param $flags * @param $context * @param string $storage 物理存储组,不传则为默认 * @return boolean */ public static function create_file($file, $data, $flags = null, $context = null, $storage = 'default') { $info = static::check_and_get_path($file); if (static::can_do_run($storage)) { # 系统内部运行时或小于等于1台服时执行 $dir = \substr($file, 0, (int) \strrpos(\str_replace('\\', '/', $file), '/')); if ($dir && !\is_dir($dir)) { # 没有文件夹先则创建 static::create_dir($dir); } if (@\file_put_contents($file, $data, $flags, $context)) { @\chmod($file, 0666); return true; } else { if (\IS_DEBUG) { \Core::debug()->error('create file error:' . Core::debug_path($file)); } return false; } } else { return static::call_http_host($storage, 'file/create_file', $info[0], $info[1], $data, $flags, $context); } }
/** * Helper for Kohana::dump(), handles recursion in arrays and objects. * * @param mixed variable to dump * @param integer maximum length of strings * @param integer recursion level (internal) * @return string */ protected static function _dump(&$var, $length = 128, $level = 0) { if ($var === NULL) { return '<small>NULL</small>'; } elseif (is_bool($var)) { return '<small>bool</small> ' . ($var ? 'TRUE' : 'FALSE'); } elseif (is_float($var)) { return '<small>float</small> ' . $var; } elseif (is_resource($var)) { if (($type = get_resource_type($var)) === 'stream' and $meta = stream_get_meta_data($var)) { $meta = stream_get_meta_data($var); if (isset($meta['uri'])) { $file = $meta['uri']; if (function_exists('stream_is_local')) { // Only exists on PHP >= 5.2.4 if (stream_is_local($file)) { $file = Core::debug_path($file); } } return '<small>resource</small><span>(' . $type . ')</span> ' . htmlspecialchars($file, ENT_NOQUOTES, Core::$charset); } } else { return '<small>resource</small><span>(' . $type . ')</span>'; } } elseif (is_string($var)) { // Clean invalid multibyte characters. iconv is only invoked // if there are non ASCII characters in the string, so this // isn't too much of a hit. $var = UTF8::clean($var); if (UTF8::strlen($var) > $length) { // Encode the truncated string $str = htmlspecialchars(UTF8::substr($var, 0, $length), ENT_NOQUOTES, Core::$charset) . ' …'; } else { // Encode the string $str = htmlspecialchars($var, ENT_NOQUOTES, Core::$charset); } return '<small>string</small><span>(' . strlen($var) . ')</span> "' . $str . '"'; } elseif (is_array($var)) { $output = array(); // Indentation for this variable $space = str_repeat($s = ' ', $level); static $marker = null; if ($marker === null) { // Make a unique marker $marker = uniqid(""); } if (empty($var)) { // Do nothing } elseif (isset($var[$marker])) { $output[] = "(\n{$space}{$s}*RECURSION*\n{$space})"; } elseif ($level < 5) { $output[] = "<span>("; $var[$marker] = TRUE; foreach ($var as $key => &$val) { if ($key === $marker) { continue; } if (!is_int($key)) { $key = '"' . htmlspecialchars($key, ENT_NOQUOTES, Core::$charset) . '"'; } $output[] = "{$space}{$s}{$key} => " . Docs::_dump($val, $length, $level + 1); } unset($var[$marker]); $output[] = "{$space})</span>"; } else { // Depth too great $output[] = "(\n{$space}{$s}...\n{$space})"; } return '<small>array</small><span>(' . count($var) . ')</span> ' . implode("\n", $output); } elseif (is_object($var)) { // Copy the object as an array $array = (array) $var; $output = array(); // Indentation for this variable $space = str_repeat($s = ' ', $level); $hash = spl_object_hash($var); // Objects that are being dumped static $objects = array(); if (empty($var)) { // Do nothing } elseif (isset($objects[$hash])) { $output[] = "{\n{$space}{$s}*RECURSION*\n{$space}}"; } elseif ($level < 10) { $output[] = "<code>{"; $objects[$hash] = TRUE; foreach ($array as $key => &$val) { if ($key[0] === "") { // Determine if the access is protected or protected $access = '<small>' . ($key[1] === '*' ? 'protected' : 'private') . '</small>'; // Remove the access level from the variable name $key = substr($key, strrpos($key, "") + 1); } else { $access = '<small>public</small>'; } $output[] = "{$space}{$s}{$access} {$key} => " . Docs::_dump($val, $length, $level + 1); } unset($objects[$hash]); $output[] = "{$space}}</code>"; } else { // Depth too great $output[] = "{\n{$space}{$s}...\n{$space}}"; } return '<small>object</small> <span>' . get_class($var) . '(' . count($array) . ')</span> ' . implode("\n", $output); } else { return '<small>' . gettype($var) . '</small> ' . htmlspecialchars(print_r($var, TRUE), ENT_NOQUOTES, Core::$charset); } }
/** * 获取链接唯一hash * * @param string $file * @return string */ protected function _get_connection_hash($file) { $hash = sha1(get_class($this) . $file); Database_Driver::$_hash_to_hostname[$hash] = Core::debug_path($file); return $hash; }
?> <li> <p> <span class="file"> <?php if ($step['file']) { $source_id = $error_id . 'source' . $i; ?> <a href="#<?php echo $source_id; ?> " onclick="return expc_hw('<?php echo $source_id; ?> ')"><?php echo Core::debug_path($step['file']); ?> [ <?php echo $step['line']; ?> ]</a> <?php } else { ?> {PHP internal call} <?php } ?> </span> » <?php
public static function shutdown_handler() { $error = error_get_last(); if ($error) { static $run = null; if ($run === true) { return; } $run = true; if (((E_ERROR | E_PARSE | E_CORE_ERROR | E_COMPILE_ERROR | E_USER_ERROR | E_RECOVERABLE_ERROR) & $error['type']) !== 0) { $error['file'] = Core::debug_path($error['file']); Core::show_500(var_export($error, true)); exit; } } }
/** * 导入指定类库 * 支持多个,当一次导入多个时,从数组最后一个开始导入 * * 导入的格式必须是类似 com.a.b 的形式,否则会抛出异常,例如: `com.myqee.test` * * Bootstrap::import_library('com.myqee.test'); * Bootstrap::import_library(array('com.myqee.test','com.myqee.cms')); * * @param string|array $library_name 指定类库 支持多个 * @return num 返回新加载的类库总数 */ public static function import_library($library_name) { if (!$library_name) { return false; } $library_name = (array) $library_name; # 反向排序,从最后一个开始导入 $library_name = array_reverse($library_name); $config_files = array(); $load_num = 0; foreach ($library_name as $lib) { $set = self::_add_include_path_lib($lib); if (true === $set[2]) { # 已加载过 continue; } $config_file = $set[1] . 'config' . EXT; if (is_file($config_file)) { $config_files[] = $config_file; } if (self::$core_config['runtime_config']) { $config_file = $set[1] . 'config' . self::$core_config['runtime_config'] . '.runtime' . EXT; if (is_file($config_file)) { $config_files[] = $config_file; } } $load_num++; if (IS_DEBUG && class_exists('Core', false) && class_exists('Debug', false)) { Core::debug()->info('import a new library: ' . Core::debug_path($lib)); } } if ($config_files) { __include_config_file(self::$config, $config_files); } return $load_num; }
public function __construct($class, $method) { if (is_object($class)) { $this->class = $class; $class_name = $class->name; } else { $this->class = new ReflectionClass($class); $class_name = $class; } $this->method = new ReflectionMethod($class_name, $method); $this->data['name'] = $method; $this->data['class_name'] = $this->method->class; $this->class = $parent = $this->method->getDeclaringClass(); if ($modifiers = $this->method->getModifiers()) { $this->data['modifiers'] = implode(' ', Reflection::getModifierNames($modifiers)); } do { if ($parent->hasMethod($method) && ($comment = $parent->getMethod($method)->getDocComment())) { // Found a description for this method break; } } while ($parent = $parent->getParentClass()); list($description, $tags) = self::parse($comment); $this->data['title'] = $description[0]; $this->data['description'] = trim(implode("\n", $description)); // if ($file = $this->class->getFileName()) // { // $this->data['source'] = self::source($file, $this->method->getStartLine(), $this->method->getEndLine()); // } if (isset($tags['param'])) { $params = array(); foreach ($this->method->getParameters() as $i => $param) { $param = new _Docs_Method_Param(array($this->method->class, $this->method->name), $i); if (isset($tags['param'][$i])) { preg_match('/^(\\S+)(?:\\s*(?:\\$' . $param->data['name'] . '\\s*)?(.+))?$/', $tags['param'][$i], $matches); $param->data['type'] = $matches[1]; if (isset($matches[2])) { $param->data['description'] = $matches[2]; } } $param->data['html'] = $param->get_html(); $param->data['text'] = $param->get_text(); $params[] = $param->getArrayCopy(); } $this->data['params'] = $params; unset($tags['param']); } if (isset($tags['return'])) { foreach ($tags['return'] as $return) { if (preg_match('/^(\\S*)(?:\\s*(.+?))?$/', $return, $matches)) { $this->data['return'][] = array($matches[1], isset($matches[2]) ? $matches[2] : ''); } } unset($tags['return']); } $this->data['tags'] = $tags; $this->data['is_php_class'] = $this->method->getStartLine() ? 0 : 1; $this->data['start_line'] = $this->method->getStartLine(); $this->data['end_line'] = $this->method->getEndLine(); $this->data['file_name'] = $this->class->getFileName(); $this->data['debug_file'] = $this->data['file_name'] ? Core::debug_path($this->data['file_name']) : false; $this->data['is_static'] = $this->method->isStatic(); $this->data['is_public'] = $this->method->isPublic(); if ($this->data['params']) { $this->data['params_short'] = $this->params_short(); $this->data['params_text'] = $this->params_text(); } }
?> ')">Loaded extensions</a> (<?php echo count($included); ?> )</h3> <div id="<?php echo $env_id; ?> " class="collapsed"> <table cellspacing="0"> <?php foreach ($included as $file) { ?> <tr> <td><code><?php echo Core::debug_path($file, '#a00'); ?> </code></td> </tr> <?php } ?> </table> </div> <?php foreach (array('_SESSION', '_GET', '_POST', '_FILES', '_COOKIE', '_SERVER') as $var) { ?> <?php if (empty($GLOBALS[$var]) or !is_array($GLOBALS[$var])) { continue; }
<div id="<?php echo $env_id; ?> " class="collapsed"> <table> <?php $i = 0; foreach ($included as $file) { ?> <tr> <td width="50" class="lefttd"><?php echo ++$i; ?> </td> <td><code><?php echo Core::debug_path($file); ?> </code></td> </tr> <?php } ?> </table> </div> <?php foreach (array('_SESSION', '_GET', '_POST', '_FILES', '_COOKIE', '_SERVER') as $var) { ?> <?php if (empty($GLOBALS[$var]) || !is_array($GLOBALS[$var])) { continue; }
</tbody> </table> <h3>目录权限检查</h3> <table class="mainTable"> <tbody align="center"> <tr> <th>目录文件</th> <th>所需状态</th> <th>当前状态</th> </tr> <?php $all_dir = array(DIR_DATA => 1, DIR_DATA . Core::$project . '/install.lock' => 0, DIR_PROJECT . Core::$project . '/config/database.config' . EXT => 2); foreach ($all_dir as $dir => $type) { echo '<tr>'; echo '<td>' . Core::debug_path($dir) . '</td>'; echo '<td>'; if ($type == 1) { echo '可写'; } elseif ($type == 0) { echo '不存在,且可写'; } elseif ($type == 2) { echo '可写或手动修改'; } echo '</td>'; echo '<td>'; if (is_dir($dir) || is_file($dir)) { if (is_writable($dir)) { echo '<font color="#5fd300"><strong>√</strong></font>可写'; } else { echo '<font color="red"><strong>×</strong></font>不可写';
public function before() { # 记录访问日志 if (HttpIO::METHOD == 'POST') { Database::instance(Model_Admin::DATABASE)->insert(Core::config('admin/log.tablename'), array('uri' => $_SERVER["REQUEST_URI"], 'type' => 'log', 'ip' => HttpIO::IP, 'referer' => $_SERVER["HTTP_REFERER"], 'post' => serialize($_POST), 'admin_id' => $this->session()->member()->id)); } if (!is_file(DIR_DATA . Core::$project . '/install.lock') && ($install_file = Core::find_file('controllers', 'install'))) { self::message('为保证系统安全请在data目录下创建安装锁文件:' . Core::$project . '/install.lock<br><br>或删除后台安装文件:' . Core::debug_path($install_file) . '<br><br>设置完毕后方可进入后台', -1); } # 不允许非超管跨项目访问 if ($this->session()->member()->project != Core::$project && !$this->session()->member()->is_super_admin) { self::message('通道受限,您不具备此项目的操作权限,请联系管理员', -1); } ob_start(); }
/** * 处理解析LESS文件 * * @throws Exception */ protected function prease_css($out_file, $type, &$content) { # 通过recess处理less文件 $tmpfile = DIR_TEMP . 'tmpless_' . md5($this->file) . $type; if (!function_exists('exec')) { throw new Exception(__('The system does not allow you to execute exec function, you can not call the node processing less file')); } try { file_put_contents($tmpfile, $content); } catch (Exception $e) { if (strpos($e->getMessage(), 'Permission denied') !== false) { Core::show_500(__('Permission denied : :file', array(':file' => Core::debug_path($tmpfile)))); } throw $e; } list($node_file, $node_modules_path) = $this->get_node_set(); static $assets_path = null; if (null === $assets_path) { $include_path = Core::include_path(); $include_path = array_reverse($include_path); # assets目录,经过 escapeshellarg 处理,用于sass,less处理时增加包含目录参数 $assets_path = array(); $tmp_dir = dirname($this->file); if ($tmp_dir && $tmp_dir != '.') { $tmp_dir .= '/'; } else { $tmp_dir = ''; } # 循环include path foreach ($include_path as $path) { $dir = $path . "assets/" . $tmp_dir; if (is_dir($dir)) { $assets_path[] = escapeshellarg($dir); } } } if ($type == 'less') { if ($assets_path) { $path_str = ' --includePath=' . implode(' --includePath=', $assets_path); } $cmd = 'cd ' . escapeshellcmd($node_modules_path) . ' && ' . escapeshellcmd($node_file) . ' ' . escapeshellarg('./node_modules/recess/bin/recess') . ' --compile' . $path_str . ' ' . escapeshellarg($tmpfile); } else { if ($assets_path) { $path_str = ' --load-path=' . implode(' --load-path=', $assets_path); } $cmd = 'sass -t expanded' . $path_str . ' ' . escapeshellarg($tmpfile); } if (IS_DEBUG) { Core::debug()->info($cmd, 'exec'); } # 执行 exec($cmd, $output, $r); # 删除临时文件 @unlink($tmpfile); if (0 === $r) { if ($output) { # 更新content $content = implode("\r\n", $output); } } else { if (127 === $r) { throw new Exception(__('Systems perform less processing failed, please check the implementation of the recess command')); } else { if (1 === $r) { throw new Exception(__('Systems perform less processing failed, please check the file. cmd: %c, output: %s', array('%c' => $cmd, '%s' => implode("\n", $output)))); } else { $err = array(1 => __('Please check no recess module installed or not set node_modules path')); throw new Exception(__('Systems perform less handling failed,RsCode:%s', array('%s' => $r . '.' . (isset($err[$r]) ? $err[$r] : '')))); } } } }
/** * 寻找控制器 * * @return array */ private function find_controller($uri) { $uri = strtolower('/' . trim($uri, ' /')); if (self::$config['core']['url_suffix'] && substr($uri, -strlen(self::$config['core']['url_suffix'])) == self::$config['core']['url_suffix']) { $uri = substr($uri, 0, -strlen(self::$config['core']['url_suffix'])); } if ($uri != '/') { $uri_arr = explode('/', $uri); } else { $uri_arr = array(''); } if (IS_DEBUG) { Core::debug()->log($uri, 'find controller uri'); } $include_path = self::$include_path; if (self::$project || self::$app) { # 如果是某个项目或是app模式,则不在application里寻找控制器 unset($include_path['\\']); } # log $find_log = $find_path_log = array(); # 控制器目录 $controller_dir = 'controllers'; # 首先找到存在的目录 $found_path = array(); foreach ($include_path as $ns => $path) { $tmp_str = $real_path = $real_class = ''; $tmp_path = $path . self::$dir_setting['controller'][0]; $ids = array(); foreach ($uri_arr as $uri_path) { if (is_numeric($uri_path)) { $real_uri_path = '_id'; $ids[] = $uri_path; } elseif ($uri_path == '_id') { # 不允许直接在URL中使用_id break; } elseif (preg_match('#[^a-z0-9_]#i', $uri_path)) { # 不允许非a-z0-9_的字符在控制中 break; } else { $real_uri_path = $uri_path; } $tmpdir = $tmp_path . $real_path . $real_uri_path . DS; if (IS_DEBUG) { $find_path_log[] = Core::debug_path($tmpdir); } $real_path .= $real_uri_path . DS; $real_class .= $real_uri_path . '__'; $tmp_str .= $uri_path . DS; if (is_dir($tmpdir)) { $found_path[$tmp_str][] = array($ns, $tmpdir, ltrim($real_class, '_'), $ids); } else { break; } } } unset($ids); $found = null; # 寻找可能的文件 if ($found_path) { # 调整优先级 krsort($found_path); foreach ($found_path as $path => $all_path) { $tmp_p = substr($uri, strlen($path)); if ($tmp_p) { $args = explode('/', substr($uri, strlen($path))); } else { $args = array(); } $the_id = array(); $tmp_class = array_shift($args); if (0 === strlen($tmp_class)) { $tmp_class = 'index'; } elseif (is_numeric($tmp_class)) { $the_id = array($tmp_class); $tmp_class = '_id'; } elseif ($tmp_class == '_id') { continue; } $real_class = $tmp_class; foreach ($all_path as $tmp_arr) { list($ns, $tmp_path, $real_path, $ids) = $tmp_arr; $path_str = $real_path; $tmpfile = $tmp_path . $tmp_class . self::$dir_setting['controller'][1] . EXT; if (IS_DEBUG) { $find_log[] = Core::debug_path($tmpfile); } if (is_file($tmpfile)) { if ($the_id) { $ids = array_merge($ids, $the_id); } $found = array('file' => $tmpfile, 'namespace' => $ns, 'class' => 'Controller_' . $path_str . $real_class, 'args' => $args, 'ids' => $ids); break 2; } } } } if (IS_DEBUG) { Core::debug()->group('find controller path'); foreach ($find_path_log as $value) { Core::debug()->log($value); } Core::debug()->groupEnd(); Core::debug()->group('find controller file'); foreach ($find_log as $value) { Core::debug()->log($value); } Core::debug()->groupEnd(); if ($found) { $found2 = $found; $found2['file'] = Core::debug_path($found2['file']); Core::debug()->log($found2, 'found contoller'); } else { Core::debug()->log($uri, 'not found contoller'); } } return $found; }
/** * 设置项目 * 可重新设置新项目已实现程序内项目切换,但需谨慎使用 * @param string $project */ public static function set_project($project) { if (self::$project == $project) { return true; } static $core_config = null; if (null === $core_config) { # 记录原始Core配置 $core_config = self::$config['core']; } if (!isset($core_config['projects'][$project])) { self::_throw_sys_error_msg(__('not found the project: :project.', array(':project' => $project))); } if (!$core_config['projects'][$project]['isuse']) { self::_throw_sys_error_msg(__('the project: :project is not open.', array(':project' => '$project'))); } # 获取core里项目配置 $project_config = $core_config['projects'][$project]; # 项目路径 $project_dir = realpath(DIR_PROJECT . $project_config['dir']); if (!$project_dir || !is_dir($project_dir)) { self::_throw_sys_error_msg(__('the project dir :dir is not exist.', array(':dir' => $project_config['dir']))); } $project_dir .= DS; self::$project_dir = $project_dir; # 记录所有项目设置,当切换回项目时,使用此设置还原 static $all_prjects_setting = array(); if (self::$project) { # 记录上一个项目设置 $all_prjects_setting[self::$project] = array('config' => self::$config, 'project_config' => self::$project_config, 'include_path' => self::$include_path, 'file_list' => self::$file_list); } # 设为当前项目 self::$project = $project; # 记录debug信息 if (class_exists('Core', false)) { Core::debug()->info('程序已切换到了新项目:' . $project); } if (isset($all_prjects_setting[$project])) { # 还原配置 self::$config = $all_prjects_setting[$project]['config']; self::$project_config = $all_prjects_setting[$project]['project_config']; self::$include_path = $all_prjects_setting[$project]['include_path']; self::$file_list = $all_prjects_setting[$project]['file_list']; } else { # 合并配置 $config = $core_config['projects'][$project] + self::$config['core']; # 读取项目配置 if (is_file($project_dir . 'config' . EXT)) { self::_include_config_file($config, $project_dir . 'config' . EXT); } # 读取DEBUG配置 if (isset(self::$config['core']['debug_config']) && self::$config['core']['debug_config'] && is_file($project_dir . 'debug.config' . EXT)) { self::_include_config_file($config, $project_dir . 'debug.config' . EXT); } # 清理项目配置 self::$project_config = $config; self::$config = array('core' => &self::$project_config); unset($config); # Builder构建,处理 self::$file_list if (self::$project_config['use_bulider'] === 'auto') { if (IS_DEBUG) { $usebulider = false; } else { $usebulider = true; } } else { $usebulider = (bool) self::$project_config['use_bulider']; } $project_filelist = DIR_BULIDER . self::$project . DS . 'project_all_files_list' . EXT; if (true === $usebulider && !IS_CLI && is_file($project_filelist)) { # 读取文件列表 self::_include_config_file(self::$file_list, $project_filelist); } # 设置包含目录 self::$include_path = self::get_project_include_path($project); } if (isset(self::$project_config['error_reporting'])) { error_reporting(self::$project_config['error_reporting']); } # 时区设置 if (isset(self::$project_config['timezone'])) { date_default_timezone_set(self::$project_config['timezone']); } if (class_exists('Core', false)) { # 输出调试信息 if (IS_DEBUG) { Core::debug()->group('当前加载目录'); foreach (self::$include_path as $value) { Core::debug()->log(Core::debug_path($value)); } Core::debug()->groupEnd(); } Core::ini_library(); } }
</th> </tr> <?php foreach ($filelist as $i => $value) { ?> <tr class="final profiler_mark profiler_memory"> <td class="profiler_average" style="width:4%;text-align:center;"><?php echo $i + 1; ?> </td> <td style="width:8%"><?php echo Profiler::bytes(filesize($value)); ?> </td> <td style="width:88%"><?php echo Core::debug_path($value); ?> </td> </tr> <?php } ?> </table><?php } ?> <table class="profiler"> <?php $stats = Profiler::application(); ?> <tr class="final profiler_mark profiler_time"> <th class="profiler_name" rowspan="2" style="float:none;"><?php
<?php echo $doc->description; ?> <?php if ($doc->tags) { View::factory('docs/api/tags')->set('tags', $doc->tags)->render(true); } ?> <p class="note"> <?php if ($path = $doc->class->getFilename()) { ?> Class declared in <tt><?php echo Core::debug_path($path); ?> </tt> on line <?php echo $doc->class->getStartLine(); ?> . <?php } else { ?> Class is not declared in a file, it is probably an internal <?php echo HTML::anchor('http://php.net/manual/class.' . strtolower($doc->class->name) . '.php', 'PHP class'); ?> . <?php } ?>
/** * Helper for Kohana::dump(), handles recursion in arrays and objects. * * @param mixed variable to dump * @param integer maximum length of strings * @param integer recursion level (internal) * @return string */ private static function _dump(&$var, $length = 128, $level = 0) { if ($var === null) { return '<small>null</small>'; } elseif (is_bool($var)) { return '<small>bool</small> ' . ($var ? 'TRUE' : 'FALSE'); } elseif (is_float($var)) { return '<small>float</small> ' . $var; } elseif (\is_resource($var)) { if (($type = \get_resource_type($var)) === 'stream' && ($meta = \stream_get_meta_data($var))) { $meta = \stream_get_meta_data($var); if (isset($meta['uri'])) { $file = $meta['uri']; if (function_exists('stream_is_local')) { // Only exists on PHP >= 5.2.4 if (\stream_is_local($file)) { $file = \Core::debug_path($file); } } return '<small>resource</small><span>(' . $type . ')</span> ' . \htmlspecialchars($file, \ENT_NOQUOTES, \Core::$charset); } } else { return '<small>resource</small><span>(' . $type . ')</span>'; } } elseif (\is_string($var)) { if (\strlen($var) > $length) { // Encode the truncated string $str = \htmlspecialchars(\substr($var, 0, $length), \ENT_NOQUOTES, \Core::$charset) . ' …'; } else { // Encode the string $str = @\htmlspecialchars($var, \ENT_NOQUOTES, \Core::$charset); } return '<small>string</small><span>(' . \strlen($var) . ')</span> "' . $str . '"'; } elseif (\is_array($var)) { $output = array(); // Indentation for this variable $space = \str_repeat($s = ' ', $level); static $marker = null; if ($marker === null) { // Make a unique marker $marker = \uniqid(""); } if (empty($var)) { // Do nothing } elseif (isset($var[$marker])) { $output[] = "(\n{$space}{$s}*RECURSION*\n{$space})"; } elseif ($level < 5) { $output[] = "<span>("; $var[$marker] = true; foreach ($var as $key => &$val) { if ($key === $marker) { continue; } if (!\is_int($key)) { $key = '"' . $key . '"'; } $output[] = "{$space}{$s}{$key} => " . static::_dump($val, $length, $level + 1); } unset($var[$marker]); $output[] = "{$space})</span>"; } else { // Depth too great $output[] = "(\n{$space}{$s}...\n{$space})"; } return '<small>array</small><span>(' . \count($var) . ')</span> ' . \implode("\n", $output); } elseif (\is_object($var)) { // Copy the object as an array $array = (array) $var; $output = array(); // Indentation for this variable $space = \str_repeat($s = ' ', $level); $hash = \spl_object_hash($var); // Objects that are being dumped static $objects = array(); if (empty($var)) { // Do nothing } elseif (isset($objects[$hash])) { $output[] = "{\n{$space}{$s}*RECURSION*\n{$space}}"; } elseif ($level < 5) { $output[] = "<code>{"; $objects[$hash] = true; foreach ($array as $key => &$val) { if ($key[0] === "") { // Determine if the access is private or protected $access = '<small>' . ($key[1] === '*' ? 'protected' : 'private') . '</small>'; // Remove the access level from the variable name $key = \substr($key, \strrpos($key, "") + 1); } else { $access = '<small>public</small>'; } $output[] = "{$space}{$s}{$access} {$key} => " . static::_dump($val, $length, $level + 1); } unset($objects[$hash]); $output[] = "{$space}}</code>"; } else { // Depth too great $output[] = "{\n{$space}{$s}...\n{$space}}"; } return '<small>object</small> <span>' . \get_class($var) . '(' . \count($array) . ')</span> ' . \implode("\n", $output); } else { return '<small>' . \gettype($var) . '</small> ' . \htmlspecialchars(\print_r($var, true), \ENT_NOQUOTES, \Core::$charset); } }