黑帽联盟

 找回密码
 会员注册
查看: 1066|回复: 1
打印 上一主题 下一主题

[建站文章] phpwind的rewrite重写原理

[复制链接]

148

主题

9

听众

337

积分

版主

Rank: 7Rank: 7Rank: 7

  • TA的每日心情
    擦汗
    2018-6-6 11:33
  • 签到天数: 348 天

    [LV.8]以坛为家I

    关于pw的重写,phpwind用到了一般人不会太关注的一个技术点,输出缓冲(output buffer - ob_),下面我们就分析一下phpwind的rewrite重写原理

    就是一般我们用echo print 输出字符到页面上的时候,意味着只要执行到了echo,php就会立即输出到客户端,但php有几个和缓冲相关的函数,他可以控制你输出的行为,就是不立马输出,而是等你调用了ob_flush/flush函数,才输出。而pw就是利用了这个原理,等页面所有的内容都生成完毕了,最后调footer()时,ob_get_contents(),获取缓冲的内容,通过正则批量替换url,构造rewrite的url格式。

    关于ob,其实有两种主要的使用场景,一个是实现页面压缩输出 - ob_gzhandler;再一个是在ajax/自定义api返回数据时,程序执行过程中,你不知道前面的程序是否有些意外的输出字符如空格、空行等,他们在数据返回时会造成很多意外情况,所以可以在你输出数据前,清除前面的缓冲内容,重新开始输出。
    官方默认的重写规则(注:重写是web服务器 - 如apache、nginx或应用容器tomcat的功能,不是程序语言自己的功能),如pw的一条重写规则 - apache:
    1. RewriteRule ^(.*)-htm-(.*)$ $1.php?$2
    复制代码
    首先,我们分析他的构成。当我们打开 global.php 文件,找到 :
    1. <?php
    2. $db_obstart == 1 ? ob_start('ob_gzhandler') : ob_start();
    3. ?>
    复制代码
    我们会发现,这个全局文件打开了一个ob_start,并且进行一些判断。这个是pw系统进行rewrite的一个关键。
    然后我们再找到footer()函数:
    1. <?php
    2. function footer(){
    3. global $db,$db_obstart,$db_footertime,$db_htmifopen,$P_S_T,$mtablewidth,$db_ceoconnect,$wind_version,$imgpath,$stylepath,$footer_ad,$db_union,$dbinfo,$timestamp;
    4. Update_ol();
    5. if($db){
    6. $qn=$db->query_num;
    7. }
    8. $ft_gzip=($db_obstart==1 ? "Gzip enabled" : "Gzip disabled").$db_union[3];
    9. if ($db_footertime == 1){
    10. $t_array = explode(' ',microtime());
    11. $totaltime = number_format(($t_array[0]+$t_array[1]-$P_S_T),6);
    12. $wind_spend = "Total $totaltime(s) query $qn,";
    13. }
    14. $ft_time=get_date($timestamp,'m-d H:i');
    15. include PrintEot('footer');
    16. $output = str_replace(array('<!--<!---->','<!---->'),array('',''),ob_get_contents());
    17. if($db_htmifopen){
    18. $output = preg_replace(
    19. "/<a(s*[^>]+s*)href=(["|']?)([^"'>s]+.php?[^"'>s]+)(["|']?)/ies",
    20. "Htm_cv('3','<a1href="')",
    21. $output
    22. );
    23. }
    24. ob_end_clean();
    25. $db_obstart == 1 ? ob_start('ob_gzhandler') : ob_start();
    26. echo $output;
    27. flush;
    28. exit;
    29. }
    30. ?>
    复制代码
    common.php中:
    1. function parseHtmlUrlRewrite($html, $flag) {
    2. return $flag ? preg_replace("/\<a(\s*[^\>]+\s*)href\=([\"|\']?)((index|cate|thread|read|faq|rss)\.php\?[^\"\'>\s]+\s?)[\"|\']?/ies", "Htm_cv('\\3','<a\\1href=\"')", $html) : $html;
    3. }</p> <p>/**
    4. * url处理
    5. *
    6. * @param string $url
    7. * @param string $tag
    8. * @return string
    9. */
    10. function Htm_cv($url, $tag) {
    11. return stripslashes($tag) . urlRewrite($url) . '"';
    12. }</p> <p>function urlRewrite($url) {
    13. global $db_htmifopen, $db_dir, $db_ext;
    14. if (!$db_htmifopen) return $url;
    15. $tmppos = strpos($url, '#');
    16. $add = $tmppos !== false ? substr($url, $tmppos) : '';
    17. $turl = str_replace(array('.php?', '=', '&', '&', $add), array($db_dir, '-', '-', '-', ''), $url);//pw的重写规则在这里进行字符的替换
    18. $turl != $url && $turl .= $db_ext;
    19. return $turl . $add;
    20. }
    复制代码
    帖子永久地址: 

    黑帽联盟 - 论坛版权1、本主题所有言论和图片纯属会员个人意见,与本论坛立场无关
    2、本站所有主题由该帖子作者发表,该帖子作者与黑帽联盟享有帖子相关版权
    3、其他单位或个人使用、转载或引用本文时必须同时征得该帖子作者和黑帽联盟的同意
    4、帖子作者须承担一切因本文发表而直接或间接导致的民事或刑事法律责任
    5、本帖部分内容转载自其它媒体,但并不代表本站赞同其观点和对其真实性负责
    6、如本帖侵犯到任何版权问题,请立即告知本站,本站将及时予与删除并致以最深的歉意
    7、黑帽联盟管理员和版主有权不事先通知发贴者而删除本文

    yun 黑帽联盟官方人员 

    920

    主题

    37

    听众

    1364

    积分

    超级版主

    Rank: 8Rank: 8

  • TA的每日心情
    奋斗
    2019-10-18 11:20
  • 签到天数: 678 天

    [LV.9]以坛为家II

    不錯,挺好的
    来自安卓客户端来自安卓客户端
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 会员注册

    发布主题 !fastreply! 收藏帖子 返回列表 搜索
    回顶部