专业编程基础技术教程

网站首页 > 基础教程 正文

php手把手教你做网站(三十三)网站静态生成一preg_match_all

ccvgpt 2024-10-12 13:32:19 基础教程 10 ℃

篇幅原因,为了避免看得不耐烦,分开几章来说明。

三个办法:

php手把手教你做网站(三十三)网站静态生成一preg_match_all

  1. 做好动态网站,生成静态的时候直接使用file_get_contents('http://ww.abc.com/about');得到页面html源码,然后使用file_put_contents('E:\web/html/about.html',html源码)创建静态文件;
  2. 做好静态模板,在显示模块内容的地方加上标志符,例如:公司产品列表,<div>##productlist##</div>,要生成静态的时候,读取模板内容,str_replace(##productlist##,$prolist,$mubanne);$prolist就是我们在数据库读取的产品列表;
  3. 比较麻烦,要在模板内写语句,然后解析,好处可以减少更改后台程序;

我们主要说第三个办法,主要用到preg_match_all,preg_match,效率并不高用到很多次for循环,做企业站生成静态页面应该也够用了。

preg_match($preg, $str, $match);截取第一个

preg_match_all($preg, $str, $match);截取所有的

参数说明:

  1. $preg:正则要搜索的模式;
  2. $str:搜索的字符串;
  3. $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]);

说明:

  1. 正则开始,结束写到2个/内;
  2. 开始标志“{include” ,结束标志“}”;
  3. .*任意字符,不包括换行;
  4. (.*)加了括号和不加返回值的区别是:不加返回带有开始结束标志的数组元素,只有$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);

说明:

  1. 加上修饰符s,强制按一行处理;
  2. .*?相比例一加上了问号,如果不加,结束标志会使用字符串最后出现的;
  3. $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]);

说明:

  1. 这里用到了修饰符i和 s,因为给出来的$str是换行的加上修饰符s可以把字符串当成一行来匹配,i不区分大小写,例如:CMLIST 和cmlist是一个效果;
  2. 结束标志包含了“/”需要转义前边加上“\”;
  3. $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}
';
  1. 要截取cat_html_path、cat_html_name、cat_name;
  2. 竖线分隔,definefuc为自定义函数名称,左侧为参数变量,参数为常量放到右边(conststr对应,funcname对应函数名称);
  3. fa中的a是动态地对应了cmlist中的name;
  4. 如果name:a,对应fa,如果name:aa,对应的是faa;
  5. 按照例2中的方法,在for循环中再次截取 以{fa开头,以}结尾就得到了我们想要的字符串,这些字符串对应了表的字段。
  6. $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);
		
		}
	}
}

注意:

传递的变量参数,多个参数实际是一个字符串,在我们自定义方法内使用该参数的时候应该是先分割成数组,单个参数没有影响。

Tags:

最近发表
标签列表