转自:http://www.cnblogs.com/Braveliu/p/5100018.html

转在了解了《phpcms V9 URL访问解析》之后,我们已经知道首页最终执行的是content模块下index控制器的init方法。

下面, 我们逐步分析过程如下:

第一、首页默认执行的是index.php?m=content&c=index&a=init

如下代码(路径:phpcms\modules\content\index.php),先从init函数分析:

  1. 1 class index
  2. 2 {
  3. 3 private $db;
  4. 4 function __construct()
  5. 5 {
  6. 6 $this->db = pc_base::load_model('content_model');
  7. 7 $this->_userid = param::get_cookie('_userid');
  8. 8 $this->_username = param::get_cookie('_username');
  9. 9 $this->_groupid = param::get_cookie('_groupid');
  10. 10 }
  11. 11 //首页
  12. 12 public function init()
  13. 13 {
  14. 14 if(isset($_GET['siteid']))
  15. 15 {
  16. 16 $siteid = intval($_GET['siteid']); //当前站点id 函数intval作用变量转成整数类型
  17. 17 }
  18. 18 else
  19. 19 {
  20. 20 $siteid = 1;
  21. 21 }
  22. 22 $siteid = $GLOBALS['siteid'] = max($siteid,1);
  23. 23 define('SITEID', $siteid);
  24. 24 $_userid = $this->_userid;
  25. 25 $_username = $this->_username;
  26. 26 $_groupid = $this->_groupid;
  27. 27 //SEO 搜索引擎优化信息
  28. 28 $SEO = seo($siteid); //调用第二步,获取当前站点当前栏目下生成的SEO信息
  29. 29 $sitelist = getcache('sitelist','commons'); //缓存后台设置的所有站点配置信息
  30. 30 $default_style = $sitelist[$siteid]['default_style']; //当前站点默认模板风格配置
  31. 31 $CATEGORYS = getcache('category_content_'.$siteid,'commons'); //当前站点所有栏目详细配置信息
  32. 32 include template('content','index',$default_style); //调用第三步:模板调用
  33. 33 }

第二、获取SEO信息:phpcms/libs/functions/global.func.php

  1. 1 /**
  2. 2 * 生成SEO
  3. 3 * @param $siteid 站点ID
  4. 4 * @param $catid 栏目ID
  5. 5 * @param $title 标题
  6. 6 * @param $description 描述
  7. 7 * @param $keyword 关键词
  8. 8 */
  9. 9 function seo($siteid, $catid = '', $title = '', $description = '', $keyword = '')
  10. 10 {
  11. 11 if (!empty($title))
  12. 12 $title = strip_tags($title); //过滤title。 strip_tags() 函数剥去字符串中的 HTML、XML 以及 PHP 的标签。
  13. 13 if (!empty($description))
  14. 14 $description = strip_tags($description); //过滤description
  15. 15 if (!empty($keyword))
  16. 16 $keyword = str_replace(' ', ',', strip_tags($keyword)); //过滤keyword
  17. 17 $sites = getcache('sitelist', 'commons'); //获取所有站点详细配置信息
  18. 18 $site = $sites[$siteid]; //当前站点详细配置信息
  19. 19 $cat = array();
  20. 20 if (!empty($catid)) //栏目ID不为空
  21. 21 {
  22. 22 $siteids = getcache('category_content','commons'); //获取所有栏目对应的站点ID缓存文件,格式:栏目ID=>站点ID
  23. 23 $siteid = $siteids[$catid]; //当前栏目对应的站点ID
  24. 24 $categorys = getcache('category_content_'.$siteid,'commons'); //获取当前站点下所有栏目的详细配置信息
  25. 25 $cat = $categorys[$catid]; //当前站点下当前栏目的详细配置信息
  26. 26 $cat['setting'] = string2array($cat['setting']); //当前站点当前栏目详细配置信息的setting设置信息,转化为数组
  27. 27 }
  28. 28 //站点title
  29. 29 $seo['site_title'] =isset($site['site_title']) && !empty($site['site_title']) ? $site['site_title'] : $site['name'];
  30. 30 //关键字
  31. 31 $seo['keyword'] = !empty($keyword) ? $keyword : $site['keywords'];
  32. 32 //描述
  33. 33 $seo['description'] = isset($description) && !empty($description) ? $description : (isset($cat['setting']['meta_description']) && !empty($cat['setting']['meta_description']) ? $cat['setting']['meta_description'] : (isset($site['description']) && !empty($site['description']) ? $site['description'] : ''));
  34. 34 //标题
  35. 35 $seo['title'] = (isset($title) && !empty($title) ? $title.' - ' : '').(isset($cat['setting']['meta_title']) && !empty($cat['setting']['meta_title']) ? $cat['setting']['meta_title'].' - ' : (isset($cat['catname']) && !empty($cat['catname']) ? $cat['catname'].' - ' : ''));
  36. 36 foreach ($seo as $k=>$v)
  37. 37 {
  38. 38 $seo[$k] = str_replace(array("\n","\r"), '', $v); //将seo信息中\n和\r替换为空
  39. 39 }
  40. 40 return $seo; //返回seo数组信息
  41. 41 }

第三、模板调用:phpcms/libs/functions/global.func.php

  1. 1 /**
  2. 2 * 模板调用
  3. 3 *
  4. 4 * @param $module 默认为content
  5. 5 * @param $template 默认为index
  6. 6 * @param $istag
  7. 7 * @return unknown_type
  8. 8 */
  9. 9 function template($module = 'content', $template = 'index', $style = '')
  10. 10 {
  11. 11 if(strpos($module, 'plugin/')!== false)
  12. 12 { // 检测模块里面是否包含plugin字符,这里进行了对插件模板的判断,插件模板需要调用p_template过程解析
  13. 13 $plugin = str_replace('plugin/', '', $module);
  14. 14 return p_template($plugin, $template,$style);
  15. 15 }
  16. 16 $module = str_replace('/', DIRECTORY_SEPARATOR, $module);
  17. 17 if(!empty($style) && preg_match('/([a-z0-9\-_]+)/is',$style))
  18. 18 {
  19. 19 }
  20. 20 elseif (empty($style) && !defined('STYLE'))
  21. 21 {
  22. 22 if(defined('SITEID')) // 是否定义了SITEID常量
  23. 23 {
  24. 24 $siteid = SITEID;
  25. 25 }
  26. 26 else
  27. 27 {
  28. 28 $siteid = param::get_cookie('siteid');
  29. 29 }
  30. 30 if (!$siteid) $siteid = 1;
  31. 31 $sitelist = getcache('sitelist','commons'); //获取所有站点的详细配置信息
  32. 32 if(!empty($siteid))
  33. 33 {
  34. 34 $style = $sitelist[$siteid]['default_style']; //获取当前站点的默认模板风格
  35. 35 }
  36. 36 }
  37. 37 elseif (empty($style) && defined('STYLE'))
  38. 38 {
  39. 39 $style = STYLE;
  40. 40 }
  41. 41 else
  42. 42 {
  43. 43 $style = 'default';
  44. 44 }
  45. 45 if(!$style)
  46. 46 $style = 'default';
  47. 47 //模板解析类,文件路径:phpcms/libs/classes/template_cache.class.php
  48. 48 $template_cache = pc_base::load_sys_class('template_cache');
  49. 49 //编译文件缓存路径:根目录/caches/caches_template/default/content/index.php
  50. 50 $compiledtplfile = PHPCMS_PATH.'caches'.DIRECTORY_SEPARATOR.'caches_template'.DIRECTORY_SEPARATOR.$style.DIRECTORY_SEPARATOR.$module.DIRECTORY_SEPARATOR.$template.'.php';
  51. 51 //首页模板文件,如文件路径:phpcms/templates/dafault/content/index.html
  52. 52 if(file_exists(PC_PATH.'templates'.DIRECTORY_SEPARATOR.$style.DIRECTORY_SEPARATOR.$module.DIRECTORY_SEPARATOR.$template.'.html'))
  53. 53 {
  54. 54 //如果编译文件不存在或者说模板文件的创建时间大于编译文件的生成时间,则重新编译
  55. 55 if(!file_exists($compiledtplfile) || (@filemtime(PC_PATH.'templates'.DIRECTORY_SEPARATOR.$style.DIRECTORY_SEPARATOR.$module.DIRECTORY_SEPARATOR.$template.'.html') > @filemtime($compiledtplfile)))
  56. 56 {
  57. 57 $template_cache->template_compile($module, $template, $style); //调用第四步:适用模板风格不是default的情况
  58. 58 }
  59. 59 }
  60. 60 else
  61. 61 {
  62. 62 //编译文件缓存路径:根目录/caches/caches_template/default/content/index.php
  63. 63 $compiledtplfile = PHPCMS_PATH.'caches'.DIRECTORY_SEPARATOR.'caches_template'.DIRECTORY_SEPARATOR.'default'.DIRECTORY_SEPARATOR.$module.DIRECTORY_SEPARATOR.$template.'.php';
  64. 64 //如果编译文件不存在或者说前台公共的模板文件存在,并且前台公共模板文件的创建时间大于编译文件的生成时间
  65. 65 if(!file_exists($compiledtplfile) || (file_exists(PC_PATH.'templates'.DIRECTORY_SEPARATOR.'default'.DIRECTORY_SEPARATOR.$module.DIRECTORY_SEPARATOR.$template.'.html') && filemtime(PC_PATH.'templates'.DIRECTORY_SEPARATOR.'default'.DIRECTORY_SEPARATOR.$module.DIRECTORY_SEPARATOR.$template.'.html') > filemtime($compiledtplfile)))
  66. 66 {
  67. 67 //重新编译
  68. 68 $template_cache->template_compile($module, $template, 'default');
  69. 69 }
  70. 70 elseif (!file_exists(PC_PATH.'templates'.DIRECTORY_SEPARATOR.'default'.DIRECTORY_SEPARATOR.$module.DIRECTORY_SEPARATOR.$template.'.html'))
  71. 71 { //如果前台公共的模板文件不存在的话,则提示模板不存在
  72. 72 showmessage('Template does not exist.'.DIRECTORY_SEPARATOR.$style.DIRECTORY_SEPARATOR.$module.DIRECTORY_SEPARATOR.$template.'.html');
  73. 73 }
  74. 74 }
  75. 75 //返回编译文件
  76. 76 return $compiledtplfile;
  77. 77 }

第四、模板解析:phpcms/libs/classes/template_cache.class.php

  1. 1 /**
  2. 2 * 模板解析缓存
  3. 3 */
  4. 4 final class template_cache
  5. 5 {
  6. 6
  7. 7 /**
  8. 8 * 编译模板
  9. 9 *
  10. 10 * @param $module 模块名称
  11. 11 * @param $template 模板文件名
  12. 12 * @param $istag 是否为标签模板
  13. 13 * @return unknown
  14. 14 */
  15. 15
  16. 16 public function template_compile($module, $template, $style = 'default')
  17. 17 {
  18. 18 if(strpos($module, '/')=== false) // 如果“/”不存在
  19. 19 {
  20. 20 //路径:phpcms/templates/default/content/index.html 如:首页公共模板文件
  21. 21 $tplfile = $_tpl = PC_PATH.'templates'.DIRECTORY_SEPARATOR.$style.DIRECTORY_SEPARATOR.$module.DIRECTORY_SEPARATOR.$template.'.html';
  22. 22 }
  23. 23 elseif (strpos($module, 'yp/') !== false)
  24. 24 {
  25. 25 $module = str_replace('/', DIRECTORY_SEPARATOR, $module);
  26. 26 $tplfile = $_tpl = PC_PATH.'templates'.DIRECTORY_SEPARATOR.$style.DIRECTORY_SEPARATOR.$module.DIRECTORY_SEPARATOR.$template.'.html';
  27. 27 }
  28. 28 else
  29. 29 {
  30. 30 $plugin = str_replace('plugin/', '', $module);
  31. 31 $module = str_replace('/', DIRECTORY_SEPARATOR, $module);
  32. 32 $tplfile = $_tpl = PC_PATH.'plugin'.DIRECTORY_SEPARATOR.$plugin.DIRECTORY_SEPARATOR.'templates'.DIRECTORY_SEPARATOR.$template.'.html';
  33. 33 }
  34. 34 if ($style != 'default' && !file_exists ( $tplfile ))
  35. 35 {
  36. 36 $style = 'default';
  37. 37 $tplfile = PC_PATH.'templates'.DIRECTORY_SEPARATOR.'default'.DIRECTORY_SEPARATOR.$module.DIRECTORY_SEPARATOR.$template.'.html';
  38. 38 }
  39. 39 if (! file_exists ( $tplfile ))
  40. 40 {
  41. 41 //如果公共模板文件不存在,则提示模板文件不存在,如:/templates/default/content/index.html is not exists!
  42. 42 showmessage ( "templates".DIRECTORY_SEPARATOR.$style.DIRECTORY_SEPARATOR.$module.DIRECTORY_SEPARATOR.$template.".html is not exists!" );
  43. 43 }
  44. 44 //获取公共模板文件中的内容
  45. 45 $content = @file_get_contents ( $tplfile );
  46. 46 //要生成的编译文件所在目录
  47. 47 $filepath = CACHE_PATH.'caches_template'.DIRECTORY_SEPARATOR.$style.DIRECTORY_SEPARATOR.$module.DIRECTORY_SEPARATOR;
  48. 48 if(!is_dir($filepath))
  49. 49 {
  50. 50 //如果目录不存在,则层级创建所有目录
  51. 51 mkdir($filepath, 0777, true);
  52. 52 }
  53. 53 //编译文件的全路径
  54. 54 $compiledtplfile = $filepath.$template.'.php';
  55. 55 //解析公共模板文件中的内容及标签,并返回解析后的内容
  56. 56 $content = $this->template_parse($content); // 调用下一个过程
  57. 57 //将解析后的公共模板文件内容写入到要生成的编译文件中
  58. 58 $strlen = file_put_contents ( $compiledtplfile, $content );
  59. 59 //给生成的编译文件设置权限
  60. 60 chmod ( $compiledtplfile, 0777 );
  61. 61 //返回写入编译文件的字节数
  62. 62 return $strlen;
  63. 63 }
  64. 64
  65. 65 /**
  66. 66 * 解析模板
  67. 67 *
  68. 68 * @param $str 模板内容
  69. 69 * @return ture
  70. 70 */
  71. 71 public function template_parse($str) {
  72. 72 $str = preg_replace ( "/\{template\s+(.+)\}/", "<?php include template(\\1); ?>", $str );
  73. 73 $str = preg_replace ( "/\{include\s+(.+)\}/", "<?php include \\1; ?>", $str );
  74. 74 $str = preg_replace ( "/\{php\s+(.+)\}/", "<?php \\1?>", $str );
  75. 75 $str = preg_replace ( "/\{if\s+(.+?)\}/", "<?php if(\\1) { ?>", $str );
  76. 76 $str = preg_replace ( "/\{else\}/", "<?php } else { ?>", $str );
  77. 77 $str = preg_replace ( "/\{elseif\s+(.+?)\}/", "<?php } elseif (\\1) { ?>", $str );
  78. 78 $str = preg_replace ( "/\{\/if\}/", "<?php } ?>", $str );
  79. 79 //for 循环
  80. 80 $str = preg_replace("/\{for\s+(.+?)\}/","<?php for(\\1) { ?>",$str);
  81. 81 $str = preg_replace("/\{\/for\}/","<?php } ?>",$str);
  82. 82 //++ --
  83. 83 $str = preg_replace("/\{\+\+(.+?)\}/","<?php ++\\1; ?>",$str);
  84. 84 $str = preg_replace("/\{\-\-(.+?)\}/","<?php ++\\1; ?>",$str);
  85. 85 $str = preg_replace("/\{(.+?)\+\+\}/","<?php \\1++; ?>",$str);
  86. 86 $str = preg_replace("/\{(.+?)\-\-\}/","<?php \\1--; ?>",$str);
  87. 87 $str = preg_replace ( "/\{loop\s+(\S+)\s+(\S+)\}/", "<?php \$n=1;if(is_array(\\1)) foreach(\\1 AS \\2) { ?>", $str );
  88. 88 $str = preg_replace ( "/\{loop\s+(\S+)\s+(\S+)\s+(\S+)\}/", "<?php \$n=1; if(is_array(\\1)) foreach(\\1 AS \\2 => \\3) { ?>", $str );
  89. 89 $str = preg_replace ( "/\{\/loop\}/", "<?php \$n++;}unset(\$n); ?>", $str );
  90. 90 $str = preg_replace ( "/\{([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff:]*\(([^{}]*)\))\}/", "<?php echo \\1;?>", $str );
  91. 91 $str = preg_replace ( "/\{\\$([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff:]*\(([^{}]*)\))\}/", "<?php echo \\1;?>", $str );
  92. 92 $str = preg_replace ( "/\{(\\$[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)\}/", "<?php echo \\1;?>", $str );
  93. 93 $str = preg_replace("/\{(\\$[a-zA-Z0-9_\[\]\'\"\$\x7f-\xff]+)\}/es", "\$this->addquote('<?php echo \\1;?>')",$str);
  94. 94 $str = preg_replace ( "/\{([A-Z_\x7f-\xff][A-Z0-9_\x7f-\xff]*)\}/s", "<?php echo \\1;?>", $str );
  95. 95 $str = preg_replace("/\{pc:(\w+)\s+([^}]+)\}/ie", "self::pc_tag('$1','$2', '$0')", $str);
  96. 96 $str = preg_replace("/\{\/pc\}/ie", "self::end_pc_tag()", $str);
  97. 97 $str = "<?php defined('IN_PHPCMS') or exit('No permission resources.'); ?>" . $str;
  98. 98 return $str;
  99. 99 }

第五、PC标签的解析:phpcms/libs/classes/template_cache.class.php 文件

  1. 1 /**
  2. 2 * 解析PC标签
  3. 3 * @param string $op 操作方式
  4. 4 * @param string $data 参数
  5. 5 * @param string $html 匹配到的所有的HTML代码
  6. 6 */
  7. 7 public static function pc_tag($op, $data, $html)
  8. 8 {
  9. 9 preg_match_all("/([a-z]+)\=[\"]?([^\"]+)[\"]?/i", stripslashes($data), $matches, PREG_SET_ORDER);
  10. 10 $arr = array('action','num','cache','page', 'pagesize', 'urlrule', 'return', 'start');
  11. 11 $tools = array('json', 'xml', 'block', 'get');
  12. 12 $datas = array();
  13. 13 $tag_id = md5(stripslashes($html));
  14. 14 //可视化条件
  15. 15 $str_datas = 'op='.$op.'&tag_md5='.$tag_id;
  16. 16 foreach ($matches as $v)
  17. 17 {
  18. 18 $str_datas .= $str_datas ? "&$v[1]=".($op == 'block' && strpos($v[2], '$') === 0 ? $v[2] : urlencode($v[2])) : "$v[1]=".(strpos($v[2], '$') === 0 ? $v[2] : urlencode($v[2]));
  19. 19 if(in_array($v[1], $arr))
  20. 20 {
  21. 21 $$v[1] = $v[2];//如果pc标签中参数在默认参数数组$arr中存在,则将参数转换为变量,如:$page=value等
  22. 22 continue;
  23. 23 }
  24. 24 $datas[$v[1]] = $v[2];//如果pc标签中参数不在默认参数数组$arr中存在,则直接将其放置到$datas[参数名]=value中
  25. 25 }
  26. 26 $str = '';
  27. 27 $num = isset($num) && intval($num) ? intval($num) : 20;
  28. 28 $cache = isset($cache) && intval($cache) ? intval($cache) : 0;
  29. 29 $return = isset($return) && trim($return) ? trim($return) : 'data';
  30. 30 if (!isset($urlrule)) $urlrule = '';
  31. 31 if (!empty($cache) && !isset($page))
  32. 32 {
  33. 33 $str .= '$tag_cache_name = md5(implode(\'&\','.self::arr_to_html($datas).').\''.$tag_id.'\');if(!$'.$return.' = tpl_cache($tag_cache_name,'.$cache.')){';
  34. 34 }
  35. 35 if (in_array($op,$tools))
  36. 36 { //pc标签分两大类:工具类和模块类。工具类执行如下代码
  37. 37 switch ($op)
  38. 38 {
  39. 39 case 'json':
  40. 40 if (isset($datas['url']) && !empty($datas['url']))
  41. 41 {
  42. 42 $str .= '$json = @file_get_contents(\''.$datas['url'].'\');';
  43. 43 $str .= '$'.$return.' = json_decode($json, true);';
  44. 44 }
  45. 45 break;
  46. 46
  47. 47 case 'xml':
  48. 48 $str .= '$xml = pc_base::load_sys_class(\'xml\');';
  49. 49 $str .= '$xml_data = @file_get_contents(\''.$datas['url'].'\');';
  50. 50 $str .= '$'.$return.' = $xml->xml_unserialize($xml_data);';
  51. 51 break;
  52. 52
  53. 53 case 'get':
  54. 54 $str .= 'pc_base::load_sys_class("get_model", "model", 0);';
  55. 55 if ($datas['dbsource'])
  56. 56 {
  57. 57 $dbsource = getcache('dbsource', 'commons');
  58. 58 if (isset($dbsource[$datas['dbsource']]))
  59. 59 {
  60. 60 $str .= '$get_db = new get_model('.var_export($dbsource,true).', \''.$datas['dbsource'].'\');';
  61. 61 }
  62. 62 else
  63. 63 {
  64. 64 return false;
  65. 65 }
  66. 66 }
  67. 67 else
  68. 68 {
  69. 69 $str .= '$get_db = new get_model();';
  70. 70 }
  71. 71 $num = isset($num) && intval($num) > 0 ? intval($num) : 20;
  72. 72 if (isset($start) && intval($start))
  73. 73 {
  74. 74 $limit = intval($start).','.$num;
  75. 75 }
  76. 76 else
  77. 77 {
  78. 78 $limit = $num;
  79. 79 }
  80. 80 if (isset($page))
  81. 81 {
  82. 82 $str .= '$pagesize = '.$num.';';
  83. 83 $str .= '$page = intval('.$page.') ? intval('.$page.') : 1;if($page<=0){$page=1;}';
  84. 84 $str .= '$offset = ($page - 1) * $pagesize;';
  85. 85 $limit = '$offset,$pagesize';
  86. 86 $sql = 'SELECT COUNT(*) as count FROM ('.$datas['sql'].') T';
  87. 87 $str .= '$r = $get_db->sql_query("'.$sql.'");$s = $get_db->fetch_next();$pages=pages($s[\'count\'], $page, $pagesize, $urlrule);';
  88. 88 }
  89. 89
  90. 90 $str .= '$r = $get_db->sql_query("'.$datas['sql'].' LIMIT '.$limit.'");while(($s = $get_db->fetch_next()) != false) {$a[] = $s;}$'.$return.' = $a;unset($a);';
  91. 91 break;
  92. 92
  93. 93 case 'block':
  94. 94 $str .= '$block_tag = pc_base::load_app_class(\'block_tag\', \'block\');';
  95. 95 $str .= 'echo $block_tag->pc_tag('.self::arr_to_html($datas).');';
  96. 96 break;
  97. 97 }
  98. 98 }
  99. 99 else
  100. 100 { //pc标签分两大类:工具类和模块类。模块类执行如下代码
  101. 101 if (!isset($action) || empty($action))
  102. 102 return false;
  103. 103 //content模块:phpcms/modules/content/classes/content_tag.class.php
  104. 104 if (module_exists($op) && file_exists(PC_PATH.DIRECTORY_SEPARATOR.'modules'.DIRECTORY_SEPARATOR.$op.DIRECTORY_SEPARATOR.'classes'.DIRECTORY_SEPARATOR.$op.'_tag.class.php'))
  105. 105 {
  106. 106 //content_tag.class.php 检查content_tag类中是否存在的某方法
  107. 107 $str .= '$'.$op.'_tag = pc_base::load_app_class("'.$op.'_tag", "'.$op.'");if (method_exists($'.$op.'_tag, \''.$action.'\')) {';
  108. 108 if (isset($start) && intval($start))
  109. 109 {
  110. 110 $datas['limit'] = intval($start).','.$num; //如:limit 0 , 10
  111. 111 }
  112. 112 else
  113. 113 {
  114. 114 $datas['limit'] = $num; //如:limit 10
  115. 115 }
  116. 116 if (isset($page)) //分页参数
  117. 117 {
  118. 118 $str .= '$pagesize = '.$num.';'; //每页显示数据量
  119. 119 $str .= '$page = intval('.$page.') ? intval('.$page.') : 1;if($page<=0){$page=1;}';//当前页码
  120. 120 $str .= '$offset = ($page - 1) * $pagesize;';//要查询数据的开始位置
  121. 121 $datas['limit'] = '$offset.",".$pagesize';
  122. 122 $datas['action'] = $action; //方法,如,content_tag.class.php中的lists方法
  123. 123 $str .= '$'.$op.'_total = $'.$op.'_tag->count('.self::arr_to_html($datas).');';//分页方法
  124. 124 $str .= '$pages = pages($'.$op.'_total, $page, $pagesize, $urlrule);';
  125. 125 }
  126. 126 //调用第七步:content_tag.class.php中方法
  127. 127 $str .= '$'.$return.' = $'.$op.'_tag->'.$action.'('.self::arr_to_html($datas).');';
  128. 128 $str .= '}';
  129. 129 }
  130. 130 }
  131. 131 if (!empty($cache) && !isset($page))
  132. 132 {
  133. 133 $str .= 'if(!empty($'.$return.')){setcache($tag_cache_name, $'.$return.', \'tpl_data\');}';
  134. 134 $str .= '}';
  135. 135 }
  136. 136 /**
  137. 137 * 解析结果大概如下所示:
  138. 138 <?php
  139. 139 if(defined('IN_ADMIN') && !defined('HTML'))
  140. 140 {
  141. 141 echo "<div class=\"admin_piao\" pc_action=\"content\" data=\"op=content&tag_md5=2d4b9e3c7c2cc4bd0cec8b1fac9ae764&action=position&posid=12&thumb=1&order=listorder+DESC&num=10\">
  142. 142 <a href=\"javascript:void(0)\" class=\"admin_piao_edit\">编辑</a>";
  143. 143 }
  144. 144 $content_tag = pc_base::load_app_class("content_tag", "content");
  145. 145 if (method_exists($content_tag, 'position'))
  146. 146 {
  147. 147 $data = $content_tag->position(array('posid'=>'12','thumb'=>'1','order'=>'listorder DESC','limit'=>'10',));
  148. 148 }
  149. 149 ?>
  150. 150 */
  151. 151 return "<"."?php if(defined('IN_ADMIN') && !defined('HTML')) {echo \"<div class=\\\"admin_piao\\\" pc_action=\\\"".$op."\\\" data=\\\"".$str_datas."\\\"><a href=\\\"javascript:void(0)\\\" class=\\\"admin_piao_edit\\\">".($op=='block' ? L('block_add') : L('edit'))."</a>\";}".$str."?".">";
  152. 152 }

第六、PC标签类。文件路径:phpcms/modules/content/classes/content_tag.class.php

  1. 1 class content_tag
  2. 2 {
  3. 3 private $db;
  4. 4 public function __construct()
  5. 5 {
  6. 6 $this->db = pc_base::load_model('content_model'); //调用第七步,数据模型,对应数据表为news和news_data
  7. 7 $this->position = pc_base::load_model('position_data_model'); //数据模型
  8. 8 }
  9. 9 /**
  10. 10 * 初始化模型
  11. 11 * @param $catid
  12. 12 */
  13. 13 public function set_modelid($catid)
  14. 14 {
  15. 15 static $CATS;
  16. 16 $siteids = getcache('category_content','commons'); //获取所有栏目所属的站点id
  17. 17 if(!$siteids[$catid])
  18. 18 return false; //不存在此栏目,返回false
  19. 19 $siteid = $siteids[$catid]; //当前栏目所属站点id
  20. 20 if ($CATS[$siteid])
  21. 21 {
  22. 22 $this->category = $CATS[$siteid];
  23. 23 }
  24. 24 else
  25. 25 {
  26. 26 //获取当前站点id下所有栏目的配置信息
  27. 27 $CATS[$siteid] = $this->category = getcache('category_content_'.$siteid,'commons');
  28. 28 }
  29. 29 if($this->category[$catid]['type']!=0)
  30. 30 return false; //如果不为内部栏目,返回false 0-内部栏目 1-单网页 2-外部链接
  31. 31 $this->modelid = $this->category[$catid]['modelid']; //获取当前栏目所属模型id
  32. 32 $this->db->set_model($this->modelid); //调用第七步
  33. 33 $this->tablename = $this->db->table_name; //数据表名
  34. 34 if(empty($this->category))
  35. 35 {
  36. 36 //当前站点id下所有栏目的配置信息
  37. 37 return false;
  38. 38 }
  39. 39 else
  40. 40 {
  41. 41 return true;
  42. 42 }
  43. 43 }
  44. 44 /**
  45. 45 * 分页统计
  46. 46 * @param $data
  47. 47 */
  48. 48 public function count($data)
  49. 49 {
  50. 50 if($data['action'] == 'lists')
  51. 51 {
  52. 52 $catid = intval($data['catid']);
  53. 53 if(!$this->set_modelid($catid)) return false;
  54. 54 if(isset($data['where']))
  55. 55 {
  56. 56 $sql = $data['where'];
  57. 57 }
  58. 58 else
  59. 59 {
  60. 60 if($this->category[$catid]['child'])
  61. 61 {
  62. 62 $catids_str = $this->category[$catid]['arrchildid'];
  63. 63 $pos = strpos($catids_str,',')+1;
  64. 64 $catids_str = substr($catids_str, $pos);
  65. 65 $sql = "status=99 AND catid IN ($catids_str)";
  66. 66 }
  67. 67 else
  68. 68 {
  69. 69 $sql = "status=99 AND catid='$catid'";
  70. 70 }
  71. 71 }
  72. 72 return $this->db->count($sql);
  73. 73 }
  74. 74 }
  75. 75
  76. 76 /**
  77. 77 * 列表页标签
  78. 78 * @param $data
  79. 79 */
  80. 80 public function lists($data)
  81. 81 {
  82. 82 $catid = intval($data['catid']);
  83. 83 if(!$this->set_modelid($catid))
  84. 84 return false;
  85. 85 if(isset($data['where'])) //如果pc标签中设置了条件
  86. 86 {
  87. 87 $sql = $data['where']; //pc标签中的条件
  88. 88 }
  89. 89 else
  90. 90 {
  91. 91 $thumb = intval($data['thumb']) ? " AND thumb != ''" : '';
  92. 92 if($this->category[$catid]['child'])
  93. 93 {
  94. 94 $catids_str = $this->category[$catid]['arrchildid'];
  95. 95 $pos = strpos($catids_str,',')+1;
  96. 96 $catids_str = substr($catids_str, $pos);
  97. 97 $sql = "status=99 AND catid IN ($catids_str)".$thumb;
  98. 98 }
  99. 99 else
  100. 100 {
  101. 101 $sql = "status=99 AND catid='$catid'".$thumb;
  102. 102 }
  103. 103 }
  104. 104 $order = $data['order']; //pc标签中排序字段
  105. 105
  106. 106 //从数据库中获取主表数据,使用的也是sql语句查询
  107. 107 $return = $this->db->select($sql, '*', $data['limit'], $order, '', 'id');
  108. 108
  109. 109 //调用副表的数据
  110. 110 if (isset($data['moreinfo']) && intval($data['moreinfo']) == 1)
  111. 111 {
  112. 112 $ids = array();
  113. 113 foreach ($return as $v)
  114. 114 {
  115. 115 if (isset($v['id']) && !empty($v['id']))
  116. 116 {
  117. 117 $ids[] = $v['id'];
  118. 118 }
  119. 119 else
  120. 120 {
  121. 121 continue;
  122. 122 }
  123. 123 }
  124. 124 if (!empty($ids))
  125. 125 {
  126. 126 $this->db->table_name = $this->db->table_name.'_data';//副表名
  127. 127 $ids = implode('\',\'', $ids);
  128. 128 $r = $this->db->select("`id` IN ('$ids')", '*', '', '', '', 'id');
  129. 129 if (!empty($r))
  130. 130 {
  131. 131 foreach ($r as $k=>$v)
  132. 132 {
  133. 133 if (isset($return[$k]))
  134. 134 $return[$k] = array_merge($v, $return[$k]); //主表中数据与副表中数据合并
  135. 135 }
  136. 136 }
  137. 137 }
  138. 138 }
  139. 139 return $return; //返回查询到的数据
  140. 140 }

注意:由以上分析可知,pc标签内部原理也是通过sql语句来获取数据的。

另外,PC标签分模块来使用,内容模块PC标签可用来完成如下功能:

(1)获取内容列表:lists 方法 (如上)

(2)获取点击排行榜:hits 方法 (详细见文件content_tag.class.php)

(3)获取相关文章:relation 方法 (详细见文件content_tag.class.php)

(4)获取栏目列表:category 方法 (详细见文件content_tag.class.php)

第七、content_model类。文件路径:phpcms/model/content_model.class.php

  1. 1 /**
  2. 2 * 内容模型数据库操作类
  3. 3 */
  4. 4 pc_base::load_sys_class('model', '', 0);
  5. 5 class content_model extends model
  6. 6 {
  7. 7 public $table_name = ''; // 数据库表名
  8. 8 public $category = ''; // 栏目
  9. 9 public function __construct()
  10. 10 {
  11. 11 $this->db_config = pc_base::load_config('database'); //加载数据库配置信息
  12. 12 $this->db_setting = 'default'; // 加载数据库默认的配置信息
  13. 13 parent::__construct(); // 调用父类的构造函数
  14. 14 $this->url = pc_base::load_app_class('url', 'content');
  15. 15 $this->siteid = get_siteid(); //获取当前站点id
  16. 16 }
  17. 17 public function set_model($modelid)
  18. 18 {
  19. 19 //获取所有模型的配置信息 1-文档模型 2-下载模型 3-图片模型 跟后台设置有关
  20. 20 $this->model = getcache('model', 'commons');
  21. 21 //当前模型id
  22. 22 $this->modelid = $modelid;
  23. 23 //模型所对应的数据表(文档模型->news 图片模型->picture 下载模型->download)
  24. 24 $this->table_name = $this->db_tablepre.$this->model[$modelid]['tablename'];
  25. 25 $this->model_tablename = $this->model[$modelid]['tablename'];
  26. 26 }

phpcms V9 首页模板文件解析(转)的更多相关文章

  1. phpcms V9 首页模板文件解析

    在了解了<phpcms V9 URL访问解析>之后,我们已经知道首页最终执行的是content模块下index控制器的init方法. 下面, 我们逐步分析过程如下: 第一.首页默认执行的是 ...

  2. PHPcms v9.6.0 文件上传漏洞

    title: PHPcms v9.6.0 文件上传漏洞 date: 2021-4-5 tags: 渗透测试,CVE漏洞复现,文件上传 categories: 渗透测试 CVE漏洞复现 文件上传 PHP ...

  3. phpcms V9首页 频道页 列表页 推荐位 简单获取文章浏览量和评论统计

    phpcms V9首页 频道页 列表页 推荐位 简单获取文章浏览量和评论统计 列表取得数据方法: {pc:content action="lists" catid="$c ...

  4. PHPCMS V9添加模板自定义全局变量

    在我们使用PHPCMS V9的制作网站模板的时候,使用全局模板变量能轻松调用,使用起来非常方便,而且可以统一修改,方便维护. 下面就来讲一下在PHPCMS V9中如何添加自定义全局变量. 修改网站sy ...

  5. phpcms v9中模板标签使用及联动菜单

    {template "content","header"} 调用根目录下phpcms\template\content\header文件 {charset} 字 ...

  6. phpcms v9会员中心文件上传漏洞

    漏洞版本: phpcms v9 漏洞描述: PHPCMS V9采用OOP(面向对象)方式自主开发的框架.框架易扩展,稳定且具有超强大负载能力. phpcms v9会员中心上传头像处可未经过充分过滤,攻 ...

  7. phpcms V9 默认模板文件目录结构_PHPCms教程

    PHPCMSV9 默认模板目录结构 templates   框架系统模板目录            announce    公告                show.html       内容页  ...

  8. phpcms V9首页、列表页以及内容页调用标签

    1.页面标题:{$title} 2.发表时间:{$inputtime} 3.内容来源:{$copyfrom} 4.文章内容:{$content} 5.缩略图地址:{$thumb} 6.组图列表: {l ...

  9. phpcms v9 首页怎么调取单页内容,描述,标题等

    {pc:,  v9 数据表前缀  catid 这是单页的id

随机推荐

  1. RSA加密解密操作

    国内私募机构九鼎控股打造APP,来就送 20元现金领取地址:http://jdb.jiudingcapital.com/phone.html内部邀请码:C8E245J (不写邀请码,没有现金送)国内私 ...

  2. 设置tomcat内存

    设置Tomcat启动的初始内存其初始空间(即-Xms)是物理内存的1/64,最大空间(-Xmx)是物理内存的1/4. 可以利用JVM提供的-Xmn -Xms -Xmx等选项可进行设置 三.实例,以下给 ...

  3. java13 InputStream,Reader

    流的方向: .输入流:数据源到程序(InputStream,Reader读进来). .输出流:程序到目的地(OutPutStream,Writer写出来). 处理数据单元: 字节流:按照字节读取数据( ...

  4. LINUX 内核月报 taobao

    http://kernel.taobao.org/index.php?title=Monthly_Kernel_Reports

  5. 5 Things They Never Tell You About Making iPhone Apps

    http://blog.teamtreehouse.com/5-things-they-never-tell-you-about-making-iphone-apps So, you've decid ...

  6. CleanMyMac 1.10.8

    CleanMyMac是一个系统清理工具,删除系统缓存文件 , 多余的应用程序语言包 , PowerPc软件运行库等. 是个给你的硬盘瘦身的好工具 下载地址:http://soft.macx.cn/so ...

  7. 开启、关闭数据库mysql

    1.命令行 net start mysql net start mysql 2.点控制面板→管理→服务 招到mysql 3.找到安装目录下的bin目录

  8. vi快捷键必知必会

    文本编辑器是所有计算机系统中最常用的一种工具.UNIX下的编辑器有ex,sed和vi等,其中,使用最为广泛的是vi,而vi命令繁多,论坛里好像这方面的总结不多,以下稍做总结,以资共享!渴望更正和补充! ...

  9. java_method_删除事务回滚

    public String[] deleteEPGroup(String groupID, String groupName) { String[] operRes=new String[3]; if ...

  10. INI文件的读写

    public class INIoperation { string inipath = Utils.GetMapPath("/Integration/Sync/set.ini") ...