对于变量$output为啥能取得栏目的值不理解
在后台中只要输入栏目,下面的代码就能循环出栏目来,逻辑顺序是这样的:
<?php if(!empty($output['navigation_list']) && is_array($output['navigation_list'])) {?>
<?php foreach($output['navigation_list'] as $value) {?>
<li class="link"><a href="<?php echo $value['navigation_link'];?>" <?php echo $value['navigation_open_type']=='1'?'target="_blank"':'';?>><?php echo $value['navigation_title'].'111111';?></a></li>
<?php } ?>
<?php } ?>
// output dir
$output = XSUtil::getOpt('o', 'output', true);
if ($output === null) {
$output = '.';
}
if (!is_dir($output)) {
echo "错误:输出目录 ($output) 不是一个有效的目录。\n";
exit(-1);
}
if (!is_writable($output)) {
echo "错误:输出目录 ($output) 不可写入,请注意检查权限。\n";
exit(-1);
}
/**
* 取得命令行参数
* 要求事先调用 parseOpt, 否则会自动以默认参数调用它。
* @param string $short 短参数名
* @param string $long 长参数名
* @param bool $extra 是否补用默认顺序的参数
* @return string 返回可用的参数值,若不存在则返回 null
* @see parseOpt
*/
public static function getOpt($short, $long = null, $extra = false)
{
if (self::$options === null) {
self::parseOpt();
} $value = null;
$options = self::$options;
if ($long !== null && isset($options[$long])) {
$value = $options[$long];
} elseif ($short !== null && isset($options[$short])) {
$value = $options[$short];
} elseif ($extra === true && isset($options['-'][self::$optind])) {
$value = $options['-'][self::$optind];
self::$optind++;
}
return $value;
}
在后台中只要输入栏目,下面的代码就能循环出栏目来,逻辑顺序是这样的:
<?php if(!empty($output['navigation_list']) && is_array($output['navigation_list'])) {?>
<?php foreach($output['navigation_list'] as $value) {?>
<li class="link"><a href="<?php echo $value['navigation_link'];?>" <?php echo $value['navigation_open_type']=='1'?'target="_blank"':'';?>><?php echo $value['navigation_title'].'111111';?></a></li>
<?php } ?>
<?php } ?>
// output dir
$output = XSUtil::getOpt('o', 'output', true);
if ($output === null) {
$output = '.';
}
if (!is_dir($output)) {
echo "错误:输出目录 ($output) 不是一个有效的目录。\n";
exit(-1);
}
if (!is_writable($output)) {
echo "错误:输出目录 ($output) 不可写入,请注意检查权限。\n";
exit(-1);
}
/**
* 取得命令行参数
* 要求事先调用 parseOpt, 否则会自动以默认参数调用它。
* @param string $short 短参数名
* @param string $long 长参数名
* @param bool $extra 是否补用默认顺序的参数
* @return string 返回可用的参数值,若不存在则返回 null
* @see parseOpt
*/
public static function getOpt($short, $long = null, $extra = false)
{
if (self::$options === null) {
self::parseOpt();
} $value = null;
$options = self::$options;
if ($long !== null && isset($options[$long])) {
$value = $options[$long];
} elseif ($short !== null && isset($options[$short])) {
$value = $options[$short];
} elseif ($extra === true && isset($options['-'][self::$optind])) {
$value = $options['-'][self::$optind];
self::$optind++;
}
return $value;
}
self::$options
self::parseOpt()
顺着这两个分支继续跟一下
$output = XSUtil::getOpt('o', 'output', true);
有值
<?php
/**
* XSUtil 类定义文件
*
* @author hightman
* @link http://www.xunsearch.com/
* @copyright Copyright © 2011 HangZhou YunSheng Network Technology Co., Ltd.
* @license http://www.xunsearch.com/license/
* @version $Id$
*//**
* XSUtil 工具程序通用代码
*
* @author hightman <[email protected]>
* @version 1.0.0
* @package XS.util
*/
class XSUtil
{
private static $optind, $options = null;
private static $charset = null; /**
* 修正字符串至固定宽度
* 其中一个全角符号、汉字的宽度为半角字符的 2 倍。
* @param string $text 要修正的字符串
* @param int $size 修正的目标宽度
* @param string $pad 用于填充补足的字符
* @return type
*/
public static function fixWidth($text, $size, $pad = ' ')
{
for ($i = $j = 0; $i < strlen($text) && $j < $size; $i++, $j++) {
if ((ord($text[$i]) & 0xe0) === 0xe0) {
if (($size - $j) == 1) {
break;
}
$j++;
$i += 2;
}
}
return substr($text, 0, $i) . str_repeat($pad, $size - $j);
} /**
* 设置输出、输入编码
* 默认输出的中文编码均为 UTF-8
* @param string $charset 期望得到的字符集
*/
public static function setCharset($charset)
{
if ($charset !== null && strcasecmp($charset, 'utf8') && strcasecmp($charset, 'utf-8')) {
self::$charset = $charset;
ob_start(array(__CLASS__, 'convertOut'));
}
} /**
* 把 UTF-8 字符串转换为用户编码
* @param string $buf 要转换字符串
* @return string 转换后的字符串
*/
public static function convertOut($buf)
{
if (self::$charset !== null) {
return XS::convert($buf, self::$charset, 'UTF-8');
}
return $buf;
} /**
* 把用户输入的字符串转换为 UTF-8 编码
* @param string $buf 要转换字符串
* @return string 转换后的字符串
*/
public static function convertIn($buf)
{
if (self::$charset !== null) {
return XS::convert($buf, 'UTF-8', self::$charset);
}
return $buf;
} /**
* 解析命令行参数
* @param array $valued 需要附加值的参数列表
* @return array 解析完的参数数组,未指定 - 开头的选项统一放入 '-' 的子数组
*/
public static function parseOpt($valued = array())
{
$result = array('-' => array());
$params = isset($_SERVER['argv']) ? $_SERVER['argv'] : array();
for ($i = 0; $i < count($params); $i++) {
if ($params[$i] === '--') {
for ($i = $i + 1; $i < count($params); $i++) {
$result['-'][] = $params[$i];
}
break;
} elseif ($params[$i][0] === '-') {
$value = true;
$pname = substr($params[$i], 1);
if ($pname[0] === '-') {
$pname = substr($pname, 1);
if (($pos = strpos($pname, '=')) !== false) {
$value = substr($pname, $pos + 1);
$pname = substr($pname, 0, $pos);
}
} elseif (strlen($pname) > 1) {
for ($j = 1; $j < strlen($params[$i]); $j++) {
$pname = substr($params[$i], $j, 1);
if (in_array($pname, $valued)) {
$value = substr($params[$i], $j + 1);
break;
} elseif (($j + 1) != strlen($params[$i])) {
$result[$pname] = true;
}
}
}
if ($value === true && in_array($pname, $valued) && isset($params[$i + 1])) {
$value = $params[$i + 1];
$i++;
}
$result[$pname] = $value;
} else {
$result['-'][] = $params[$i];
}
}
self::$options = $result;
self::$optind = 1;
return $result;
} /**
* 取得命令行参数
* 要求事先调用 parseOpt, 否则会自动以默认参数调用它。
* @param string $short 短参数名
* @param string $long 长参数名
* @param bool $extra 是否补用默认顺序的参数
* @return string 返回可用的参数值,若不存在则返回 null
* @see parseOpt
*/
public static function getOpt($short, $long = null, $extra = false)
{
if (self::$options === null) {
self::parseOpt();
} $value = null;
$options = self::$options;
if ($long !== null && isset($options[$long])) {
$value = $options[$long];
} elseif ($short !== null && isset($options[$short])) {
$value = $options[$short];
} elseif ($extra === true && isset($options['-'][self::$optind])) {
$value = $options['-'][self::$optind];
self::$optind++;
}
return $value;
} /**
* 刷新标准输出缓冲区
*/
public static function flush()
{
flush();
if (ob_get_level() > 0) {
ob_flush();
}
} /**
* 拷贝一个目录及其子目录文件
*/
public static function copyDir($src, $dst)
{
if (!($dir = @dir($src)) || (!is_dir($dst) && !@mkdir($dst, 0755, true))) {
return false;
}
while (($entry = $dir->read()) !== false) {
if ($entry === '.' || $entry === '..') {
continue;
}
$psrc = $src . DIRECTORY_SEPARATOR . $entry;
$pdst = $dst . DIRECTORY_SEPARATOR . $entry;
if (is_dir($pdst)) {
self::copyDir($psrc, $pdst);
} else {
@copy($psrc, $pdst);
}
}
$dir->close();
return true;
}
}
我之前的表述有误。并不是两个分支
而是
先检查是否有options,如果没有,则会执行parseopt()生成配置数组。
所以你应该跟踪parseOpt()的具体实现。
简单的打印log可以轻松跟踪代码的执行流程。
我之前的表述有误。并不是两个分支
而是
先检查是否有options,如果没有,则会执行parseopt()生成配置数组。
所以你应该跟踪parseOpt()的具体实现。
简单的打印log可以轻松跟踪代码的执行流程。
你说的self:arseOpt()是下面这一函数,这个如何打印跟踪呢?
/**
* 解析命令行参数
* @param array $valued 需要附加值的参数列表
* @return array 解析完的参数数组,未指定 - 开头的选项统一放入 '-' 的子数组
*/
public static function parseOpt($valued = array())
{
$result = array('-' => array());
$params = isset($_SERVER['argv']) ? $_SERVER['argv'] : array();
for ($i = 0; $i < count($params); $i++) {
if ($params[$i] === '--') {
for ($i = $i + 1; $i < count($params); $i++) {
$result['-'][] = $params[$i];
}
break;
} elseif ($params[$i][0] === '-') {
$value = true;
$pname = substr($params[$i], 1);
if ($pname[0] === '-') {
$pname = substr($pname, 1);
if (($pos = strpos($pname, '=')) !== false) {
$value = substr($pname, $pos + 1);
$pname = substr($pname, 0, $pos);
}
} elseif (strlen($pname) > 1) {
for ($j = 1; $j < strlen($params[$i]); $j++) {
$pname = substr($params[$i], $j, 1);
if (in_array($pname, $valued)) {
$value = substr($params[$i], $j + 1);
break;
} elseif (($j + 1) != strlen($params[$i])) {
$result[$pname] = true;
}
}
}
if ($value === true && in_array($pname, $valued) && isset($params[$i + 1])) {
$value = $params[$i + 1];
$i++;
}
$result[$pname] = $value;
} else {
$result['-'][] = $params[$i];
}
}
self::$options = $result;
self::$optind = 1;
return $result;
}
$output = XSUtil::getOpt('o', 'output', true);这里有值。
不过他的代码写的很怪。
这次查到了线索:下面是它的追踪路线
先调用这个函数
/**
* 获取导航
*/
Tpl::output('nav_list',($nav = F('nav'))? $nav :H('nav',true,'file'));
下面是这个函数的具体写法
/**
* 抛出变量
*
* @param mixed $output
* @param void
*/
public static function output($output,$input=''){
self::getInstance();
self::$output_value[$output] = $input;
}
上面函数的分支函数具体写法
/**
* 实例化
*
* @return obj
*/
public static function getInstance(){
if (self::$instance === null || !(self::$instance instanceof Tpl)){
self::$instance = new Tpl();
}
return self::$instance;
}
/**
* 输出模板内容的数组,其他的变量不允许从程序中直接输出到模板
*/
private static $output_value = array();
生成导航需要的函数
/**
* 文件数据读取和保存 字符串、数组
*
* @param string $name 文件名称(不含扩展名)
* @param mixed $value 待写入文件的内容
* @param string $path 写入cache的目录
* @param string $ext 文件扩展名
* @return mixed
*/
function F($name, $value = null, $path = 'cache', $ext = '.php') {
if (strtolower(substr($path,0,5)) == 'cache'){
$path = 'data/'.$path;
}
static $_cache = array();
if (isset($_cache[$name.$path])) return $_cache[$name.$path];
$filename = BASE_ROOT_PATH.'/'.$path.'/'.$name.$ext;
if (!is_null($value)) {
$dir = dirname($filename);
if (!is_dir($dir)) mkdir($dir);
return write_file($filename,$value);
} if (is_file($filename)) {
$_cache[$name.$path] = $value = include $filename;
} else {
$value = false;
}
return $value;
}
/**
* 读/写 缓存方法
*
* H('key') 取得缓存
* H('setting',true) 生成缓存并返回缓存结果
* H('key',null) 清空缓存
* H('setting',true,'file') 生成商城配置信息的文件缓存
* H('setting',true,'memcache') 生成商城配置信息到memcache
* @param string $key 缓存名称
* @param string $value 缓存内容
* @param string $type 缓存类型,允许值为 file,memcache,xcache,apc,eaccelerator,可以为空,默认为file缓存
* @param int/null $expire 缓存周期
* @param mixed $args 扩展参数
* @return mixed
*/
function H($key, $value='', $cache_type='', $expire=null, $args=null){
static $cache = array();
$cache_type = $cache_type ? $cache_type : 'file';
$obj_cache = Cache::getInstance($cache_type,$args);
if ($value !== '') {
if (is_null($value)) { // 删除缓存
$result = $obj_cache->rm($key);
if ($result)
unset($cache[$cache_type . '_' . $key]);
return $result;
}else { // 缓存数据
if ($value === true) $obj_cache->rm($key);
$list = Model('cache')->call($key);
$obj_cache->set($key, $list, null, $expire);
$cache[$cache_type . '_' . $key] = $list;
}
return $value === true ? $list : true;
}
if (isset($cache[$cache_type . '_' . $key]))
return $cache[$cache_type . '_' . $key]; $value = $obj_cache->get($key); // 取得缓存
$cache[$cache_type . '_' . $key] = $value;
return $value;
}就是上面这些了,不过就是知道这些,我也看不出来,为啥它用$output这个数组就能取出所有导航呢
<?php
/**
* 模板驱动
*
* 模板驱动,商城模板引擎
*
*
* @package tpl
* @copyright Copyright (c) 2007-2013 ShopNC Inc. (http://www.shopnc.net)
* @license http://www.shopnc.net
* @link http://www.shopnc.net
* @author ShopNC Team
* @since File available since Release v1.1
*/
defined('InShopNC') or exit('Access Invalid!');
class Tpl{
/**
* 单件对象
*/
private static $instance = null;
/**
* 输出模板内容的数组,其他的变量不允许从程序中直接输出到模板
*/
private static $output_value = array();
/**
* 模板路径设置
*/
private static $tpl_dir='';
/**
* 默认layout
*/
private static $layout_file = 'layout';
private function __construct(){}
/**
* 实例化
*
* @return obj
*/
public static function getInstance(){
if (self::$instance === null || !(self::$instance instanceof Tpl)){
self::$instance = new Tpl();
}
return self::$instance;
}
/**
* 设置模板目录
*
* @param string $dir
* @return bool
*/
public static function setDir($dir){
self::$tpl_dir = $dir;
return true;
}
/**
* 设置布局
*
* @param string $layout
* @return bool
*/
public static function setLayout($layout){
self::$layout_file = $layout;
return true;
}
/**
* 抛出变量
*
* @param mixed $output
* @param void
*/
public static function output($output,$input=''){
self::getInstance();
self::$output_value[$output] = $input;
}
/**
* 调用显示模板
*
* @param string $page_name
* @param string $layout
* @param int $time
*/
public static function showpage($page_name='',$layout='',$time=2000){
if (!defined('TPL_NAME')) define('TPL_NAME','default');
self::getInstance();
if (!empty(self::$tpl_dir)){
$tpl_dir = self::$tpl_dir.DS;
}
//默认是带有布局文件
if (empty($layout)){
$layout = 'layout'.DS.self::$layout_file.'.php';
}else {
$layout = 'layout'.DS.$layout.'.php';
}
$layout_file = BASE_PATH.'/templates/'.TPL_NAME.DS.$layout;
$tpl_file = BASE_PATH.'/templates/'.TPL_NAME.DS.$tpl_dir.$page_name.'.php';
if (file_exists($tpl_file)){
//对模板变量进行赋值
$output = self::$output_value;
//页头
$output['html_title'] = $output['html_title']!='' ? $output['html_title'] :$GLOBALS['setting_config']['site_name'];
$output['seo_keywords'] = $output['seo_keywords']!='' ? $output['seo_keywords'] :$GLOBALS['setting_config']['site_name'];
$output['seo_description'] = $output['seo_description']!='' ? $output['seo_description'] :$GLOBALS['setting_config']['site_name'];
$output['ref_url'] = getReferer(); Language::read('common');
$lang = Language::getLangContent(); @header("Content-type: text/html; charset=".CHARSET);
//判断是否使用布局方式输出模板,如果是,那么包含布局文件,并且在布局文件中包含模板文件
if ($layout != ''){
if (file_exists($layout_file)){
include_once($layout_file);
}else {
$error = 'Tpl ERROR:'.'templates'.DS.$layout.' is not exists';
throw_exception($error);
}
}else {
include_once($tpl_file);
}
}else {
$error = 'Tpl ERROR:'.'templates'.DS.$tpl_dir.$page_name.'.php'.' is not exists';
throw_exception($error);
}
}
/**
* 显示页面Trace信息
*
* @return array
*/
public static function showTrace(){
$trace = array();
//当前页面
$trace[Language::get('nc_debug_current_page')] = $_SERVER['REQUEST_URI'].'<br>';
//请求时间
$trace[Language::get('nc_debug_request_time')] = date('Y-m-d H:i:s',$_SERVER['REQUEST_TIME']).'<br>';
//系统运行时间
$query_time = number_format((microtime(true)-StartTime),3).'s';
$trace[Language::get('nc_debug_execution_time')] = $query_time.'<br>';
//内存
$trace[Language::get('nc_debug_memory_consumption')] = number_format(memory_get_usage()/1024/1024,2).'MB'.'<br>';
//请求方法
$trace[Language::get('nc_debug_request_method')] = $_SERVER['REQUEST_METHOD'].'<br>';
//通信协议
$trace[Language::get('nc_debug_communication_protocol')] = $_SERVER['SERVER_PROTOCOL'].'<br>';
//用户代理
$trace[Language::get('nc_debug_user_agent')] = $_SERVER['HTTP_USER_AGENT'].'<br>';
//会话ID
$trace[Language::get('nc_debug_session_id')] = session_id().'<br>';
//执行日志
$log = Log::read();
$trace[Language::get('nc_debug_logging')] = count($log)?count($log).Language::get('nc_debug_logging_1').'<br/>'.implode('<br/>',$log):Language::get('nc_debug_logging_2');
$trace[Language::get('nc_debug_logging')] = $trace[Language::get('nc_debug_logging')].'<br>';
//文件加载
$files = get_included_files();
$trace[Language::get('nc_debug_load_files')] = count($files).str_replace("\n",'<br/>',substr(substr(print_r($files,true),7),0,-2)).'<br>';
return $trace;
}
}
function H的
$list = Model('cache')->call($key);
Model('cache') 里面看看有没有调用db的语句。