phpwind的rewrite重写原理

没有深入过pw,被人问到这方面的问题,搜索了一下,发现了一篇博文,但原博客已打不开。

http://www.phpsoho.com/html/document/200608/1154750694.html

phpwind 8.7

有人说过“phpwind“在技术是成功的,而dz在商业上成功的,在rewrite的控制中,pw做得远远比dz好。

关于pw的重写,首先他用到了一般人不会太关注的一个技术点,输出缓冲(output buffer - ob_):

就是一般我们用echo print 输出字符到页面上的时候,意味着只要执行到了echo,php就会立即输出到客户端,但php有几个和缓冲相关的函数(参看:http://us1.php.net/manual/zh/function.flush.php),他可以控制你输出的行为,就是不立马输出,而是等你调用了ob_flush/flush函数,才输出。

而pw就是利用了这个原理,等页面所有的内容都生成完毕了,最后调footer()时,ob_get_contents(),获取缓冲的内容,通过正则批量替换url,构造rewrite的url格式。

关于ob,其实有两种主要的使用场景,一个是实现页面压缩输出 - ob_gzhandler;再一个是在ajax/自定义api返回数据时,程序执行过程中,你不知道前面的程序是否有些意外的输出字符如空格、空行等,他们在数据返回时会造成很多意外情况,所以可以在你输出数据前,清除前面的缓冲内容,重新开始输出。

官方默认的重写规则(注:重写是web服务器 - 如apache、nginx或应用容器tomcat的功能,不是程序语言自己的功能),如pw的一条重写规则 - apache:

RewriteRule ^(.*)-htm-(.*)$ $1.php?$2

首先,我们分析他的构成。当我们打开 global.php 文件,找到 :

 

<?php
$db_obstart == 1 ? ob_start('ob_gzhandler') : ob_start();
?>

 

我们会发现,这个全局文件打开了一个ob_start,并且进行一些判断。这个是pw系统进行rewrite的一个关键

然后我们再找到footer()函数:

<?php
function footer(){
    global $db,$db_obstart,$db_footertime,$db_htmifopen,$P_S_T,$mtablewidth,$db_ceoconnect,$wind_version,$imgpath,$stylepath,$footer_ad,$db_union,$dbinfo,$timestamp;
    Update_ol();
    if($db){
        $qn=$db->query_num;
    }
    $ft_gzip=($db_obstart==1 ? "Gzip enabled" : "Gzip disabled").$db_union[3];
    if ($db_footertime == 1){
        $t_array    = explode(' ',microtime());
        $totaltime    = number_format(($t_array[0]+$t_array[1]-$P_S_T),6);
        $wind_spend    = "Total $totaltime(s) query $qn,";
    }
    $ft_time=get_date($timestamp,'m-d H:i');
    include PrintEot('footer');
    $output = str_replace(array('<!--<!---->','<!---->'),array('',''),ob_get_contents());
    if($db_htmifopen){
        $output = preg_replace(
            "/<a(s*[^>]+s*)href=(["|']?)([^"'>s]+.php?[^"'>s]+)(["|']?)/ies",
            "Htm_cv('3','<a1href="')",
            $output
        );
    }
    ob_end_clean();
    $db_obstart == 1 ? ob_start('ob_gzhandler') : ob_start();
    echo $output;
    flush;
    exit;
}
?>

common.php中:

function parseHtmlUrlRewrite($html, $flag) {
    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;
}

/**
 * url处理
 *
 * @param string $url
 * @param string $tag
 * @return string
 */
function Htm_cv($url, $tag) {
    return stripslashes($tag) . urlRewrite($url) . '"';
}

function urlRewrite($url) {
    global $db_htmifopen, $db_dir, $db_ext;
    if (!$db_htmifopen) return $url;
    $tmppos = strpos($url, '#');
    $add = $tmppos !== false ? substr($url, $tmppos) : '';
    $turl = str_replace(array('.php?', '=', '&amp;', '&', $add), array($db_dir, '-', '-', '-', ''), $url);//pw的重写规则在这里进行字符的替换
    $turl != $url && $turl .= $db_ext;
    return $turl . $add;
}

 

### Nginx Rewrite重写的概念 Nginx中的Rewrite模块主要用于实现URL地址的重写以及重定向功能。通过该模块可以将传入Web服务器的请求重新导向至其他指定的URL路径,从而优化网站结构、提升用户体验并增强安全性[^1]。 #### URL重写的作用 - **改善SEO效果**:搜索引擎更倾向于简洁明了的链接形式; - **简化访问路径**:使复杂的查询字符串变为直观易懂的形式; - **保护内部资源**:隐藏真实的文件位置以增加系统的安全防护能力; ### 使用场景实例分析 当需要将以参数形式呈现出来的动态页面转换成静态样式时,可通过如下方式设置: ```xml <rule> <from>^/login/(.*).html</from> <to>/loginController.do?login&parameter=$1</to> </rule> ``` 上述配置表示任何匹配`/login/*.html`模式的请求都会被转发给后台处理器`/loginController.do`处理,并传递相应的参数值$1作为附加信息[^3]。 ### 实际操作指南 为了确保修改过的Nginx配置生效,在完成编辑之后应当先验证语法正确性再执行重启命令: ```bash [root@web01 ~]# nginx -t nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful [root@web01 ~]# systemctl restart nginx ``` 此过程能够有效防止因错误配置而导致的服务中断风险[^4]。 ### 安全措施应用案例 针对特定类型的文件下载或图片展示需求,可以在location区块内加入防盗链机制来阻止非法站点盗用带宽资源: ```nginx server { ... location ~ \.(svg)$ { root /code/; valid_referers none blocked *.baidu.com *.google.com; if ($invalid_referer) { return 403; } } } ``` 这里定义了一个仅允许来自百度和谷歌域名下的引用者获取SVG图像的规定,对于不符合条件的情况则返回HTTP状态码403拒绝服务响应[^5]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值