时间:2023-04-19 13:27:07 点击次数:14
篇幅原因,为了避免看得不耐烦,分开几章来说明。
三个办法:
做好动态网站,生成静态的时候直接使用file_get_contents(http://ww.abc.com/about);得到页面html源码,然后使用file_put_contents(E:\web/html/about.html,html源码)创建静态文件;做好静态模板,在显示模块内容的地方加上标志符,例如:公司产品列表,<div>##productlist##</div>,要生成静态的时候,读取模板内容,str_replace(##productlist##,$prolist,$mubanne);$prolist就是我们在数据库读取的产品列表;比较麻烦,要在模板内写语句,然后解析,好处可以减少更改后台程序;我们主要说第三个办法,主要用到preg_match_all,preg_match,效率并不高用到很多次for循环,做企业站生成静态页面应该也够用了。
preg_match($preg, $str, $match);截取第一个
preg_match_all($preg, $str, $match);截取所有的
参数说明:
$preg:正则,要搜索的模式;$str:搜索的字符串;$match:返回值,数组;例1:截取include/header和include/footer。
$str= {include include/header} {include include/footer} ;代码如下:
$preg="/{include(.*)}/"; preg_match_all($preg, $str, $match); print_r($match[1]);说明:
正则开始,结束写到2个/内;开始标志“{include” ,结束标志“}”;.*任意字符,不包括换行;(.*)加了括号和不加返回值的区别是:不加返回带有开始结束标志的数组元素,只有$match[0],没有1;加上以后,返回2个数组元素$match[0]不变,$match[1]是不带开始结束的标志;输出结果:
Array ( [0] => include/header [1] => include/footer )得到了包含的头部底部文件名,我们可以直接读取对应模板,替换掉<include >
具体操作:
for($i=0;$i<=count($match[1])-1;$i++){ //读取对应模板内容 $thtml=file_get_contents($match[1][$i]); $str=str_replace($match[0][$i],$thtml,$str); }例2:preg_match截取第一个include标签中的内容(字符串“111”)。
$str= {include} 111 {/include} 222 {include} 333 {/include} ; $preg="/{include}(.*?){\/include}/s"; preg_match($preg, $str, $match); print_r($match);说明:
加上修饰符s,强制按一行处理;.*?相比例一加上了问号,如果不加,结束标志会使用字符串最后出现的;$match[0]包含了起始结束标志,$match[1]不包含;例二输出结果:
Array ( [0] => {include} 111 {/include} [1] => 111 )例3:
$str= 阿斯顿开好会加速的和卡 {cmlist "t":"web_pic","f":"pic_path","c":"pic_cat=3","o":"sort desc,id desc","l":"10","name":"a"} 这是要截取的字符串1 {/cmlist} 大豪科技阿斯顿开好会加速的和卡 {cmlist "t":"web_page","f":"page_content","c":"id=80","o":"","name":"a"} 这是要截取的字符串2 {/cmlist} 大豪科技 ;截取cmlist 中的参数,还有这是要截取的字符串1,这是要截取的字符串2
$preg="/{cmlist(.*?)}(.*?){\/cmlist}/is"; preg_match_all($preg, $str, $match); print_r($match[1]);说明:
这里用到了修饰符i和 s,因为给出来的$str是换行的加上修饰符s可以把字符串当成一行来匹配,i不区分大小写,例如:CMLIST 和cmlist是一个效果;结束标志包含了“/”需要转义前边加上“\”;$match[1]是截取到的参数,$match[2]是我们截取到的字符串;$match[1]输出结果:
Array ( [0] => "t":"web_pic","f":"pic_path","c":"pic_cat=3","o":"sort desc,id desc","l":"10","name":"a" [1] => "t":"web_page","f":"page_content","c":"id=80","o":"","name":"a" )$match[2]输出结果:
Array ( [0] => 这是要截取的字符串1 [1] => 这是要截取的字符串2 )查看$match[1]输出结果,我们会发现和json格式很像只是2边差了花括号{},我们手动补充上。
具体操作:
for($i=0;$i<=count($match[1])-1;$i++){ echo json_decode("{".$match[1][$i]."}")->t; exit; }输出结果:web_pic
上边是转成了对象,也可以转成数组。
for($i=0;$i<=count($match[1])-1;$i++){ print_r( json_decode("{".$match[1][$i]."}",true)); exit; }输出结果:
Array ( [t] => web_pic [f] => pic_path [c] => pic_cat=3 [o] => sort desc,id desc [l] => 10 [name] => a )可以和tp的查询语句一一对应
$list=Db::name(t)->field(f)->where(c)->order(o)->limit(l)->select();
foreach($list as $$name){ }例4:
$str= {cmlist "t":"web_cat","f":"cat_name,cat_html_path,cat_html_name","c":"parentid=0 and projectid=81","o":"sort desc,id desc","l":"","name":"a"} <a href="/{fa cat_html_path,cat_html_name|"funcname":"definefuc","conststr":"1"}/{fa cat_html_name}.html">{fa cat_name|}</a> {/cmlist} ;要截取cat_html_path、cat_html_name、cat_name;竖线分隔,definefuc为自定义函数名称,左侧为参数变量,参数为常量放到右边(conststr对应,funcname对应函数名称);fa中的a是动态地对应了cmlist中的name;如果name:a,对应fa,如果name:aa,对应的是faa;按照例2中的方法,在for循环中再次截取 以{fa开头,以}结尾就得到了我们想要的字符串,这些字符串对应了表的字段。$match[2]是我们要重新截取的原字符串;操作如下:
for($i=0;$i<=count($match[1])-1;$i++){ $name=json_decode("{".$match[1][$i]."}")->name; $fielpreg="/{f".$name."(.*?)}/"; preg_match_all($fielpreg, $match[2][$i], $fiearr); //$fiearr就是我们得到的字段的数组 print_r( $fiearr[1]); exit; }输出结果:
Array ( [0] => cat_html_path,cat_html_name|"funcname":"definefuc","conststr":"1" [1] => cat_html_name [2] => cat_name )使用for循环,得到value值,“|”分割数组判断是否包含自定义函数;
for($i=0;$i<=count($match[1])-1;$i++){ $name=json_decode("{".$match[1][$i]."}")->name; $fielpreg="/{f".$name."(.*?)}/"; preg_match_all($fielpreg, $match[2][$i], $fiearr); for($z=0;$z<=count($fiearr[1])-1;$z++){ $isarr=explode("|",$fiearr[1][$z]); //存在自定义方法 if(count($isarr)>1){ $funcname=json_decode("{".$isarr[1]."}")->funcname; $conststr=json_decode("{".$isarr[1]."}")->conststr; $fiar=explode(",",$fiearr[0]); //可以是多个变量,合并成了字符串 $fistr=""; for($c=0;$c<=count($fiar)-1;$c++){ $fistr.=$$name[$fiar[$c]].","; } //左侧参数 $fistr 右侧常量参数$conststr $fistr=mb_substr($fistr,0,mb_strlen($fistr)-1); $str=str_replace($fiearr[0][$i],$funcname($fistr,$conststr),$str); }else{ //不存在, $str=str_replace($fiearr[0][$i],$$name[$fiearr[1][$z]],$str); } } }注意:
传递的变量参数,多个参数实际是一个字符串,在我们自定义方法内使用该参数的时候应该是先分割成数组,单个参数没有影响。