轉自: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 class index
2 {
3 private $db;
4 function __construct()
5 {
6 $this->db = pc_base::load_model('content_model');
7 $this->_userid = param::get_cookie('_userid');
8 $this->_username = param::get_cookie('_username');
9 $this->_groupid = param::get_cookie('_groupid');
10 }
11 //首頁
12 public function init()
13 {
14 if(isset($_GET['siteid']))
15 {
16 $siteid = intval($_GET['siteid']); //當前站點id 函數intval作用變量轉成整數類型
17 }
18 else
19 {
20 $siteid = 1;
21 }
22 $siteid = $GLOBALS['siteid'] = max($siteid,1);
23 define('SITEID', $siteid);
24 $_userid = $this->_userid;
25 $_username = $this->_username;
26 $_groupid = $this->_groupid;
27 //SEO 搜索引擎優化信息
28 $SEO = seo($siteid); //調用第二步,獲取當前站點當前欄目下生成的SEO信息
29 $sitelist = getcache('sitelist','commons'); //緩存後台設置的所有站點配置信息
30 $default_style = $sitelist[$siteid]['default_style']; //當前站點默認模板風格配置
31 $CATEGORYS = getcache('category_content_'.$siteid,'commons'); //當前站點所有欄目詳細配置信息
32 include template('content','index',$default_style); //調用第三步:模板調用
33 }

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

1 /**
2 * 生成SEO
3 * @param $siteid 站點ID
4 * @param $catid 欄目ID
5 * @param $title 標題
6 * @param $description 描述
7 * @param $keyword 關鍵詞
8 */
9 function seo($siteid, $catid = '', $title = '', $description = '', $keyword = '')
10 {
11 if (!empty($title))
12 $title = strip_tags($title); //過濾title。 strip_tags() 函數剝去字符串中的 HTML、XML 以及 PHP 的標簽。
13 if (!empty($description))
14 $description = strip_tags($description); //過濾description
15 if (!empty($keyword))
16 $keyword = str_replace(' ', ',', strip_tags($keyword)); //過濾keyword
17 $sites = getcache('sitelist', 'commons'); //獲取所有站點詳細配置信息
18 $site = $sites[$siteid]; //當前站點詳細配置信息
19 $cat = array();
20 if (!empty($catid)) //欄目ID不為空
21 {
22 $siteids = getcache('category_content','commons'); //獲取所有欄目對應的站點ID緩存文件,格式:欄目ID=>站點ID
23 $siteid = $siteids[$catid]; //當前欄目對應的站點ID
24 $categorys = getcache('category_content_'.$siteid,'commons'); //獲取當前站點下所有欄目的詳細配置信息
25 $cat = $categorys[$catid]; //當前站點下當前欄目的詳細配置信息
26 $cat['setting'] = string2array($cat['setting']); //當前站點當前欄目詳細配置信息的setting設置信息,轉化為數組
27 }
28 //站點title
29 $seo['site_title'] =isset($site['site_title']) && !empty($site['site_title']) ? $site['site_title'] : $site['name'];
30 //關鍵字
31 $seo['keyword'] = !empty($keyword) ? $keyword : $site['keywords'];
32 //描述
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 //標題
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 foreach ($seo as $k=>$v)
37 {
38 $seo[$k] = str_replace(array("\n","\r"), '', $v); //將seo信息中\n和\r替換為空
39 }
40 return $seo; //返回seo數組信息
41 }

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

1 /**
2 * 模板調用
3 *
4 * @param $module 默認為content
5 * @param $template 默認為index
6 * @param $istag
7 * @return unknown_type
8 */
9 function template($module = 'content', $template = 'index', $style = '')
10 {
11 if(strpos($module, 'plugin/')!== false)
12 { // 檢測模塊裡面是否包含plugin字符,這裡進行了對插件模板的判斷,插件模板需要調用p_template過程解析
13 $plugin = str_replace('plugin/', '', $module);
14 return p_template($plugin, $template,$style);
15 }
16 $module = str_replace('/', DIRECTORY_SEPARATOR, $module);
17 if(!empty($style) && preg_match('/([a-z0-9\-_]+)/is',$style))
18 {
19 }
20 elseif (empty($style) && !defined('STYLE'))
21 {
22 if(defined('SITEID')) // 是否定義了SITEID常量
23 {
24 $siteid = SITEID;
25 }
26 else
27 {
28 $siteid = param::get_cookie('siteid');
29 }
30 if (!$siteid) $siteid = 1;
31 $sitelist = getcache('sitelist','commons'); //獲取所有站點的詳細配置信息
32 if(!empty($siteid))
33 {
34 $style = $sitelist[$siteid]['default_style']; //獲取當前站點的默認模板風格
35 }
36 }
37 elseif (empty($style) && defined('STYLE'))
38 {
39 $style = STYLE;
40 }
41 else
42 {
43 $style = 'default';
44 }
45 if(!$style)
46 $style = 'default';
47 //模板解析類,文件路徑:phpcms/libs/classes/template_cache.class.php
48 $template_cache = pc_base::load_sys_class('template_cache');
49 //編譯文件緩存路徑:根目錄/caches/caches_template/default/content/index.php
50 $compiledtplfile = PHPCMS_PATH.'caches'.DIRECTORY_SEPARATOR.'caches_template'.DIRECTORY_SEPARATOR.$style.DIRECTORY_SEPARATOR.$module.DIRECTORY_SEPARATOR.$template.'.php';
51 //首頁模板文件,如文件路徑:phpcms/templates/dafault/content/index.html
52 if(file_exists(PC_PATH.'templates'.DIRECTORY_SEPARATOR.$style.DIRECTORY_SEPARATOR.$module.DIRECTORY_SEPARATOR.$template.'.html'))
53 {
54 //如果編譯文件不存在或者說模板文件的創建時間大於編譯文件的生成時間,則重新編譯
55 if(!file_exists($compiledtplfile) || (@filemtime(PC_PATH.'templates'.DIRECTORY_SEPARATOR.$style.DIRECTORY_SEPARATOR.$module.DIRECTORY_SEPARATOR.$template.'.html') > @filemtime($compiledtplfile)))
56 {
57 $template_cache->template_compile($module, $template, $style); //調用第四步:適用模板風格不是default的情況
58 }
59 }
60 else
61 {
62 //編譯文件緩存路徑:根目錄/caches/caches_template/default/content/index.php
63 $compiledtplfile = PHPCMS_PATH.'caches'.DIRECTORY_SEPARATOR.'caches_template'.DIRECTORY_SEPARATOR.'default'.DIRECTORY_SEPARATOR.$module.DIRECTORY_SEPARATOR.$template.'.php';
64 //如果編譯文件不存在或者說前台公共的模板文件存在,並且前台公共模板文件的創建時間大於編譯文件的生成時間
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 {
67 //重新編譯
68 $template_cache->template_compile($module, $template, 'default');
69 }
70 elseif (!file_exists(PC_PATH.'templates'.DIRECTORY_SEPARATOR.'default'.DIRECTORY_SEPARATOR.$module.DIRECTORY_SEPARATOR.$template.'.html'))
71 { //如果前台公共的模板文件不存在的話,則提示模板不存在
72 showmessage('Template does not exist.'.DIRECTORY_SEPARATOR.$style.DIRECTORY_SEPARATOR.$module.DIRECTORY_SEPARATOR.$template.'.html');
73 }
74 }
75 //返回編譯文件
76 return $compiledtplfile;
77 }

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

1 /**
2 * 模板解析緩存
3 */
4 final class template_cache
5 {
6
7 /**
8 * 編譯模板
9 *
10 * @param $module 模塊名稱
11 * @param $template 模板文件名
12 * @param $istag 是否為標簽模板
13 * @return unknown
14 */
15
16 public function template_compile($module, $template, $style = 'default')
17 {
18 if(strpos($module, '/')=== false) // 如果“/”不存在
19 {
20 //路徑:phpcms/templates/default/content/index.html 如:首頁公共模板文件
21 $tplfile = $_tpl = PC_PATH.'templates'.DIRECTORY_SEPARATOR.$style.DIRECTORY_SEPARATOR.$module.DIRECTORY_SEPARATOR.$template.'.html';
22 }
23 elseif (strpos($module, 'yp/') !== false)
24 {
25 $module = str_replace('/', DIRECTORY_SEPARATOR, $module);
26 $tplfile = $_tpl = PC_PATH.'templates'.DIRECTORY_SEPARATOR.$style.DIRECTORY_SEPARATOR.$module.DIRECTORY_SEPARATOR.$template.'.html';
27 }
28 else
29 {
30 $plugin = str_replace('plugin/', '', $module);
31 $module = str_replace('/', DIRECTORY_SEPARATOR, $module);
32 $tplfile = $_tpl = PC_PATH.'plugin'.DIRECTORY_SEPARATOR.$plugin.DIRECTORY_SEPARATOR.'templates'.DIRECTORY_SEPARATOR.$template.'.html';
33 }
34 if ($style != 'default' && !file_exists ( $tplfile ))
35 {
36 $style = 'default';
37 $tplfile = PC_PATH.'templates'.DIRECTORY_SEPARATOR.'default'.DIRECTORY_SEPARATOR.$module.DIRECTORY_SEPARATOR.$template.'.html';
38 }
39 if (! file_exists ( $tplfile ))
40 {
41 //如果公共模板文件不存在,則提示模板文件不存在,如:/templates/default/content/index.html is not exists!
42 showmessage ( "templates".DIRECTORY_SEPARATOR.$style.DIRECTORY_SEPARATOR.$module.DIRECTORY_SEPARATOR.$template.".html is not exists!" );
43 }
44 //獲取公共模板文件中的內容
45 $content = @file_get_contents ( $tplfile );
46 //要生成的編譯文件所在目錄
47 $filepath = CACHE_PATH.'caches_template'.DIRECTORY_SEPARATOR.$style.DIRECTORY_SEPARATOR.$module.DIRECTORY_SEPARATOR;
48 if(!is_dir($filepath))
49 {
50 //如果目錄不存在,則層級創建所有目錄
51 mkdir($filepath, 0777, true);
52 }
53 //編譯文件的全路徑
54 $compiledtplfile = $filepath.$template.'.php';
55 //解析公共模板文件中的內容及標簽,並返回解析後的內容
56 $content = $this->template_parse($content); // 調用下一個過程
57 //將解析後的公共模板文件內容寫入到要生成的編譯文件中
58 $strlen = file_put_contents ( $compiledtplfile, $content );
59 //給生成的編譯文件設置權限
60 chmod ( $compiledtplfile, 0777 );
61 //返回寫入編譯文件的字節數
62 return $strlen;
63 }
64
65 /**
66 * 解析模板
67 *
68 * @param $str 模板內容
69 * @return ture
70 */
71 public function template_parse($str) {
72 $str = preg_replace ( "/\{template\s+(.+)\}/", "<?php include template(\\1); ?>", $str );
73 $str = preg_replace ( "/\{include\s+(.+)\}/", "<?php include \\1; ?>", $str );
74 $str = preg_replace ( "/\{php\s+(.+)\}/", "<?php \\1?>", $str );
75 $str = preg_replace ( "/\{if\s+(.+?)\}/", "<?php if(\\1) { ?>", $str );
76 $str = preg_replace ( "/\{else\}/", "<?php } else { ?>", $str );
77 $str = preg_replace ( "/\{elseif\s+(.+?)\}/", "<?php } elseif (\\1) { ?>", $str );
78 $str = preg_replace ( "/\{\/if\}/", "<?php } ?>", $str );
79 //for 循環
80 $str = preg_replace("/\{for\s+(.+?)\}/","<?php for(\\1) { ?>",$str);
81 $str = preg_replace("/\{\/for\}/","<?php } ?>",$str);
82 //++ --
83 $str = preg_replace("/\{\+\+(.+?)\}/","<?php ++\\1; ?>",$str);
84 $str = preg_replace("/\{\-\-(.+?)\}/","<?php ++\\1; ?>",$str);
85 $str = preg_replace("/\{(.+?)\+\+\}/","<?php \\1++; ?>",$str);
86 $str = preg_replace("/\{(.+?)\-\-\}/","<?php \\1--; ?>",$str);
87 $str = preg_replace ( "/\{loop\s+(\S+)\s+(\S+)\}/", "<?php \$n=1;if(is_array(\\1)) foreach(\\1 AS \\2) { ?>", $str );
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 $str = preg_replace ( "/\{\/loop\}/", "<?php \$n++;}unset(\$n); ?>", $str );
90 $str = preg_replace ( "/\{([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff:]*\(([^{}]*)\))\}/", "<?php echo \\1;?>", $str );
91 $str = preg_replace ( "/\{\\$([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff:]*\(([^{}]*)\))\}/", "<?php echo \\1;?>", $str );
92 $str = preg_replace ( "/\{(\\$[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)\}/", "<?php echo \\1;?>", $str );
93 $str = preg_replace("/\{(\\$[a-zA-Z0-9_\[\]\'\"\$\x7f-\xff]+)\}/es", "\$this->addquote('<?php echo \\1;?>')",$str);
94 $str = preg_replace ( "/\{([A-Z_\x7f-\xff][A-Z0-9_\x7f-\xff]*)\}/s", "<?php echo \\1;?>", $str );
95 $str = preg_replace("/\{pc:(\w+)\s+([^}]+)\}/ie", "self::pc_tag('$1','$2', '$0')", $str);
96 $str = preg_replace("/\{\/pc\}/ie", "self::end_pc_tag()", $str);
97 $str = "<?php defined('IN_PHPCMS') or exit('No permission resources.'); ?>" . $str;
98 return $str;
99 }

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

1 /**
2 * 解析PC標簽
3 * @param string $op 操作方式
4 * @param string $data 參數
5 * @param string $html 匹配到的所有的HTML代碼
6 */
7 public static function pc_tag($op, $data, $html)
8 {
9 preg_match_all("/([a-z]+)\=[\"]?([^\"]+)[\"]?/i", stripslashes($data), $matches, PREG_SET_ORDER);
10 $arr = array('action','num','cache','page', 'pagesize', 'urlrule', 'return', 'start');
11 $tools = array('json', 'xml', 'block', 'get');
12 $datas = array();
13 $tag_id = md5(stripslashes($html));
14 //可視化條件
15 $str_datas = 'op='.$op.'&tag_md5='.$tag_id;
16 foreach ($matches as $v)
17 {
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 if(in_array($v[1], $arr))
20 {
21 $$v[1] = $v[2];//如果pc標簽中參數在默認參數數組$arr中存在,則將參數轉換為變量,如:$page=value等
22 continue;
23 }
24 $datas[$v[1]] = $v[2];//如果pc標簽中參數不在默認參數數組$arr中存在,則直接將其放置到$datas[參數名]=value中
25 }
26 $str = '';
27 $num = isset($num) && intval($num) ? intval($num) : 20;
28 $cache = isset($cache) && intval($cache) ? intval($cache) : 0;
29 $return = isset($return) && trim($return) ? trim($return) : 'data';
30 if (!isset($urlrule)) $urlrule = '';
31 if (!empty($cache) && !isset($page))
32 {
33 $str .= '$tag_cache_name = md5(implode(\'&\','.self::arr_to_html($datas).').\''.$tag_id.'\');if(!$'.$return.' = tpl_cache($tag_cache_name,'.$cache.')){';
34 }
35 if (in_array($op,$tools))
36 { //pc標簽分兩大類:工具類和模塊類。工具類執行如下代碼
37 switch ($op)
38 {
39 case 'json':
40 if (isset($datas['url']) && !empty($datas['url']))
41 {
42 $str .= '$json = @file_get_contents(\''.$datas['url'].'\');';
43 $str .= '$'.$return.' = json_decode($json, true);';
44 }
45 break;
46
47 case 'xml':
48 $str .= '$xml = pc_base::load_sys_class(\'xml\');';
49 $str .= '$xml_data = @file_get_contents(\''.$datas['url'].'\');';
50 $str .= '$'.$return.' = $xml->xml_unserialize($xml_data);';
51 break;
52
53 case 'get':
54 $str .= 'pc_base::load_sys_class("get_model", "model", 0);';
55 if ($datas['dbsource'])
56 {
57 $dbsource = getcache('dbsource', 'commons');
58 if (isset($dbsource[$datas['dbsource']]))
59 {
60 $str .= '$get_db = new get_model('.var_export($dbsource,true).', \''.$datas['dbsource'].'\');';
61 }
62 else
63 {
64 return false;
65 }
66 }
67 else
68 {
69 $str .= '$get_db = new get_model();';
70 }
71 $num = isset($num) && intval($num) > 0 ? intval($num) : 20;
72 if (isset($start) && intval($start))
73 {
74 $limit = intval($start).','.$num;
75 }
76 else
77 {
78 $limit = $num;
79 }
80 if (isset($page))
81 {
82 $str .= '$pagesize = '.$num.';';
83 $str .= '$page = intval('.$page.') ? intval('.$page.') : 1;if($page<=0){$page=1;}';
84 $str .= '$offset = ($page - 1) * $pagesize;';
85 $limit = '$offset,$pagesize';
86 $sql = 'SELECT COUNT(*) as count FROM ('.$datas['sql'].') T';
87 $str .= '$r = $get_db->sql_query("'.$sql.'");$s = $get_db->fetch_next();$pages=pages($s[\'count\'], $page, $pagesize, $urlrule);';
88 }
89
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 break;
92
93 case 'block':
94 $str .= '$block_tag = pc_base::load_app_class(\'block_tag\', \'block\');';
95 $str .= 'echo $block_tag->pc_tag('.self::arr_to_html($datas).');';
96 break;
97 }
98 }
99 else
100 { //pc標簽分兩大類:工具類和模塊類。模塊類執行如下代碼
101 if (!isset($action) || empty($action))
102 return false;
103 //content模塊:phpcms/modules/content/classes/content_tag.class.php
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 {
106 //content_tag.class.php 檢查content_tag類中是否存在的某方法
107 $str .= '$'.$op.'_tag = pc_base::load_app_class("'.$op.'_tag", "'.$op.'");if (method_exists($'.$op.'_tag, \''.$action.'\')) {';
108 if (isset($start) && intval($start))
109 {
110 $datas['limit'] = intval($start).','.$num; //如:limit 0 , 10
111 }
112 else
113 {
114 $datas['limit'] = $num; //如:limit 10
115 }
116 if (isset($page)) //分頁參數
117 {
118 $str .= '$pagesize = '.$num.';'; //每頁顯示數據量
119 $str .= '$page = intval('.$page.') ? intval('.$page.') : 1;if($page<=0){$page=1;}';//當前頁碼
120 $str .= '$offset = ($page - 1) * $pagesize;';//要查詢數據的開始位置
121 $datas['limit'] = '$offset.",".$pagesize';
122 $datas['action'] = $action; //方法,如,content_tag.class.php中的lists方法
123 $str .= '$'.$op.'_total = $'.$op.'_tag->count('.self::arr_to_html($datas).');';//分頁方法
124 $str .= '$pages = pages($'.$op.'_total, $page, $pagesize, $urlrule);';
125 }
126 //調用第七步:content_tag.class.php中方法
127 $str .= '$'.$return.' = $'.$op.'_tag->'.$action.'('.self::arr_to_html($datas).');';
128 $str .= '}';
129 }
130 }
131 if (!empty($cache) && !isset($page))
132 {
133 $str .= 'if(!empty($'.$return.')){setcache($tag_cache_name, $'.$return.', \'tpl_data\');}';
134 $str .= '}';
135 }
136 /**
137 * 解析結果大概如下所示:
138 <?php
139 if(defined('IN_ADMIN') && !defined('HTML'))
140 {
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 <a href=\"javascript:void(0)\" class=\"admin_piao_edit\">編輯</a>";
143 }
144 $content_tag = pc_base::load_app_class("content_tag", "content");
145 if (method_exists($content_tag, 'position'))
146 {
147 $data = $content_tag->position(array('posid'=>'12','thumb'=>'1','order'=>'listorder DESC','limit'=>'10',));
148 }
149 ?>
150 */
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 }

第六、PC標簽類。文件路徑:phpcms/modules/content/classes/content_tag.class.php

1 class content_tag
2 {
3 private $db;
4 public function __construct()
5 {
6 $this->db = pc_base::load_model('content_model'); //調用第七步,數據模型,對應數據表為news和news_data
7 $this->position = pc_base::load_model('position_data_model'); //數據模型
8 }
9 /**
10 * 初始化模型
11 * @param $catid
12 */
13 public function set_modelid($catid)
14 {
15 static $CATS;
16 $siteids = getcache('category_content','commons'); //獲取所有欄目所屬的站點id
17 if(!$siteids[$catid])
18 return false; //不存在此欄目,返回false
19 $siteid = $siteids[$catid]; //當前欄目所屬站點id
20 if ($CATS[$siteid])
21 {
22 $this->category = $CATS[$siteid];
23 }
24 else
25 {
26 //獲取當前站點id下所有欄目的配置信息
27 $CATS[$siteid] = $this->category = getcache('category_content_'.$siteid,'commons');
28 }
29 if($this->category[$catid]['type']!=0)
30 return false; //如果不為內部欄目,返回false 0-內部欄目 1-單網頁 2-外部鏈接
31 $this->modelid = $this->category[$catid]['modelid']; //獲取當前欄目所屬模型id
32 $this->db->set_model($this->modelid); //調用第七步
33 $this->tablename = $this->db->table_name; //數據表名
34 if(empty($this->category))
35 {
36 //當前站點id下所有欄目的配置信息
37 return false;
38 }
39 else
40 {
41 return true;
42 }
43 }
44 /**
45 * 分頁統計
46 * @param $data
47 */
48 public function count($data)
49 {
50 if($data['action'] == 'lists')
51 {
52 $catid = intval($data['catid']);
53 if(!$this->set_modelid($catid)) return false;
54 if(isset($data['where']))
55 {
56 $sql = $data['where'];
57 }
58 else
59 {
60 if($this->category[$catid]['child'])
61 {
62 $catids_str = $this->category[$catid]['arrchildid'];
63 $pos = strpos($catids_str,',')+1;
64 $catids_str = substr($catids_str, $pos);
65 $sql = "status=99 AND catid IN ($catids_str)";
66 }
67 else
68 {
69 $sql = "status=99 AND catid='$catid'";
70 }
71 }
72 return $this->db->count($sql);
73 }
74 }
75
76 /**
77 * 列表頁標簽
78 * @param $data
79 */
80 public function lists($data)
81 {
82 $catid = intval($data['catid']);
83 if(!$this->set_modelid($catid))
84 return false;
85 if(isset($data['where'])) //如果pc標簽中設置了條件
86 {
87 $sql = $data['where']; //pc標簽中的條件
88 }
89 else
90 {
91 $thumb = intval($data['thumb']) ? " AND thumb != ''" : '';
92 if($this->category[$catid]['child'])
93 {
94 $catids_str = $this->category[$catid]['arrchildid'];
95 $pos = strpos($catids_str,',')+1;
96 $catids_str = substr($catids_str, $pos);
97 $sql = "status=99 AND catid IN ($catids_str)".$thumb;
98 }
99 else
100 {
101 $sql = "status=99 AND catid='$catid'".$thumb;
102 }
103 }
104 $order = $data['order']; //pc標簽中排序字段
105
106 //從數據庫中獲取主表數據,使用的也是sql語句查詢
107 $return = $this->db->select($sql, '*', $data['limit'], $order, '', 'id');
108
109 //調用副表的數據
110 if (isset($data['moreinfo']) && intval($data['moreinfo']) == 1)
111 {
112 $ids = array();
113 foreach ($return as $v)
114 {
115 if (isset($v['id']) && !empty($v['id']))
116 {
117 $ids[] = $v['id'];
118 }
119 else
120 {
121 continue;
122 }
123 }
124 if (!empty($ids))
125 {
126 $this->db->table_name = $this->db->table_name.'_data';//副表名
127 $ids = implode('\',\'', $ids);
128 $r = $this->db->select("`id` IN ('$ids')", '*', '', '', '', 'id');
129 if (!empty($r))
130 {
131 foreach ($r as $k=>$v)
132 {
133 if (isset($return[$k]))
134 $return[$k] = array_merge($v, $return[$k]); //主表中數據與副表中數據合並
135 }
136 }
137 }
138 }
139 return $return; //返回查詢到的數據
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 /**
2 * 內容模型數據庫操作類
3 */
4 pc_base::load_sys_class('model', '', 0);
5 class content_model extends model
6 {
7 public $table_name = ''; // 數據庫表名
8 public $category = ''; // 欄目
9 public function __construct()
10 {
11 $this->db_config = pc_base::load_config('database'); //加載數據庫配置信息
12 $this->db_setting = 'default'; // 加載數據庫默認的配置信息
13 parent::__construct(); // 調用父類的構造函數
14 $this->url = pc_base::load_app_class('url', 'content');
15 $this->siteid = get_siteid(); //獲取當前站點id
16 }
17 public function set_model($modelid)
18 {
19 //獲取所有模型的配置信息 1-文檔模型 2-下載模型 3-圖片模型 跟後台設置有關
20 $this->model = getcache('model', 'commons');
21 //當前模型id
22 $this->modelid = $modelid;
23 //模型所對應的數據表(文檔模型->news 圖片模型->picture 下載模型->download)
24 $this->table_name = $this->db_tablepre.$this->model[$modelid]['tablename'];
25 $this->model_tablename = $this->model[$modelid]['tablename'];
26 }
