正则匹配出所有的arclist标签并构造SQL
取出数据并替换field为相应字段的数据
为field标签添加一个function属性
<?php
require_once
(dirname(
__FILE__
).
"/../include/common.inc.php"
);
//1. 读入模板文件
$str
=
file_get_contents
(
'test.html'
);
//2. 使用正则匹配出页面中所有的 arclist 标签
$re
=
'/{dede:arclist(.*)}(.*){\/dede:arclist}/Us'
;
// 执行正则匹配
// 第一个参数:正则
// 第二个参数:字符串
// 第三个参数:这个函数会把匹配到的结果放第三个参数的数组中
// 返回值:匹配到的个数
preg_match_all(
$re
,
$str
,
$a
);
//3. 循环每一个匹配到的arclist标签进行处理
foreach
(
$a
[0]
as
$k
=>
$v
)
{
/****************处理标签1.根据标签上的属性构造一个SQL语句 **************/
// 取出标签相应的属性字符串并把属性转化成一个数组,如 row="10" channelid="17" addfields="pffz,pfrs,yuyan" orderby="id" orderway="desc"
$attrArr
= strToArray(
$a
[1][
$k
]);
// 根据构造构造SQL语句上的变量
if
(isset(
$attrArr
[
'row'
]))
$limit
=
$attrArr
[
'row'
];
else
$limit
= 20;
if
(isset(
$attrArr
[
'orderby'
]))
$orderby
=
$attrArr
[
'orderby'
];
else
$orderby
=
'id'
;
if
(isset(
$attrArr
[
'orderway'
]))
$orderway
=
$attrArr
[
'orderway'
];
else
$orderway
=
'desc'
;
// 连表的属性
if
(isset(
$attrArr
[
'channelid'
]))
$leftJoin
=
' LEFT JOIN dede_addon17 b ON a.id=b.aid '
;
else
$leftJoin
=
''
;
if
(isset(
$attrArr
[
'addfields'
]))
$extraFields
=
','
.
$attrArr
[
'addfields'
];
else
$extraFields
=
''
;
// 解析属性
$sql
= "SELECT a.*
$extraFields
FROM dede_archives a
$leftJoin
ORDER BY
$orderby
$orderway
LIMIT
$limit
";
$dsql
->Execute(
'me'
,
$sql
);
$html
=
''
;
// 每个arclist对应的多个数据
while
(
$row
=
$dsql
->GetArray(
'me'
))
{
// 重置模板字符串,不要在原模板上面进行替换
$_tep
=
$a
[2][
$k
];
/**
<li>
<img src="[field:litpic/]" /><br />
标题:[field:title/]<br />
评分分值:[field:pffz function="getSmallStar(@me)"/]<br />
评分人数:[field:pfrs/]<br />
语言:[field:yuyan/]
</li>
**/
// 把字符串中的[field:xxxx/]替换成$row['xxxx']变量。
$_re
=
'/\[field:(\w+)(\s+function=("|\')(\w+)\((.*)\)\3)?\/\]/U'
;
preg_match_all(
$_re
,
$_tep
,
$_a
);
/**
array
0 =>
array
0 => string '[field:litpic/]' (length=15)
1 => string '[field:title/]' (length=14)
2 => string '[field:pffz/]' (length=13)
3 => string '[field:pfrs/]' (length=13)
4 => string '[field:yuyan/]' (length=14)
1 =>
array
0 => string 'litpic' (length=6)
1 => string 'title' (length=5)
2 => string 'pffz' (length=4)
3 => string 'pfrs' (length=4)
4 => string 'yuyan' (length=5)
*/
// 再循环每一条 记录中的每个字段的值
foreach
(
$_a
[0]
as
$_k
=>
$_v
)
{
if
(
$_a
[4][
$_k
] ==
''
)
// 把[field:xxx/]字符串替换成相应的$row[xxx]变量
$_tep
=
str_replace
(
$_v
,
$row
[
$_a
[1][
$_k
]],
$_tep
);
else
{
// 如果参数中有@me就把@me替换成当前这个字段的数据库中的值
$_a
[5][
$_k
] =
str_replace
(
'@me'
,
$row
[
$_a
[1][
$_k
]],
$_a
[5][
$_k
]);
// 如果有函数就调用函数
$funStr
=
'$_val='
.
$_a
[4][
$_k
].
"({$_a[5][$_k]});"
;
eval
(
$funStr
);
$_tep
=
str_replace
(
$_v
,
$_val
,
$_tep
);
}
}
$html
.=
$_tep
;
}
// 到这arclist标签就已经都解析成了相应的数据,把整个arclist标签替换成解析之后的数据,$html就是
arclist最终解析完成之后的HTML的字符串
$str
=
str_replace
(
$v
,
$html
,
$str
);
// 一个arclist就解析完成了
}
// 把解析好的字符串生成前台静态页
file_put_contents
(
'./index.html'
,
$str
);
echo
'解析成功!'
;
function
strToArray(
$str
)
{
$str
= trim(
$str
);
// 从属性字符串中匹配出每个属性,格式如:row="10" channelid="17" addfields="pffz,pfrs,yuyan" orderby="id" orderway="desc"
$re
=
'/[a-z]+\s*=\s*("|\').*\1/U'
;
$data
=
array
();
preg_match_all(
$re
,
$str
,
$a
);
foreach
(
$a
[0]
as
$k
=>
$v
)
{
$_a
=
explode
(
'='
,
$v
);
// 去掉属性值左右的引号,属性左右的引号是单引号还是双引号不能确定所以需要使用$a[1][$k]变量来代替,这个变量是正则中
的第一个括号的内容,匹配的就是引号
$_a
[1] = ltrim(
$_a
[1],
$a
[1][
$k
]);
$_a
[1] = rtrim(
$_a
[1],
$a
[1][
$k
]);
$data
[
$_a
[0]] =
$_a
[1];
}
return
$data
;
}