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-(.*)$ $.php?$
首先,我们分析他的构成。当我们打开 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?', '=', '&', '&', $add), array($db_dir, '-', '-', '-', ''), $url);//pw的重写规则在这里进行字符的替换
$turl != $url && $turl .= $db_ext;
return $turl . $add;
}
phpwind的rewrite重写原理的更多相关文章
- nginx rewrite重写
通过官方文档可以看到,rewrite的作用上下文是 server location,可以写在 server里面 亦或location里面; 命令: if (条件) {} 条件判断 set #设置 ...
- nginx之rewrite重写,反向代理,负载均衡
rewrite重写(伪静态): 在地址栏输入xx.com/user-xxx.html, 实际上访问的就是xxx.com/user.php?id=xxx rewrite就这么简单 附上ecshop re ...
- 09 nginx Rewrite(重写)详细解析
一:Rewrite(重写)详细解析 rewrite 重写 重写中用到的指令 if (条件) {} 设定条件,再进行重写 set #设置变量 return #返回状态码 break #跳出rewri ...
- rewrite重写基础实列
nginx 重写 rewrite 基础及实例 nginx rewrite 正则表达式匹配 大小写匹配 ~ 为区分大小写匹配 ~* 为不区分大小写匹配 !~和!~*分别为区分大小写不匹配及不区分大小写不 ...
- 04 . Nginx的Rewrite重写
Rewrite简介 # Rewrite对应URL Rewrite,即URL重写,就是把传入web的请求重定向到其他URL的过程. # 当运维遇到要重写情况时,往往是要程序员把重写规则写好后,发给你,你 ...
- 第十七章 nginx动静分离和rewrite重写
一.动静分离 动静分离,通过中间件将动静分离和静态请求进行分离:通过中间件将动态请求和静态请求分离,可以减少不必要的请求消耗,同时能减少请求的延时.通过中间件将动态请求和静态请求分离,逻辑图如下: 1 ...
- Nginx中的 location 匹配和 rewrite 重写跳转
Nginx中的location匹配和rewrite重写跳转 1.常用的Nginx正则表达式 2.location 3.rewrite 4.rewrite实例 1.常用的Nginx正则表达式: ^ :匹 ...
- Url Rewrite 重写
前几天看到园子里一篇关于 Url 重写的文章<获取ISAPI_Rewrite重写后的URL>, URL-Rewrite 这项技术早已不是一项新技术了,这个话题也已经被很多人讨论过多次.搜索 ...
- apache开启rewrite重写
命令开启 sudo a2enmod rewrite sudo /etc/init.d/apache2 restart 即可开启重写,不行的话再试下下面方法 ubuntu如何开启Rewrite模块 在终 ...
随机推荐
- Android程序的签名保护及绕过方法
随着Android 市场的扩大,各类盗版.破解.打包党纷纷涌现,其使用的手法无非是apk _> smali ->修改代码 ->重打包签名,为对抗此类技术,广大程序员挖掘了Androi ...
- 开发Android必知的工具
程序开发有时候非常依赖使用的开发工具,好的完备的开发工具可以让开发人员的工作效率有大幅度的提高.开发Android也是如此,大家可能都离不开Eclipse或Android Studio这些工具,但他们 ...
- oracle 数据库时间类型为字符串 时间范围大小查询
select * from invoicedetail t2 where t2.Memo is null and to_char(to_date(t2.PrintDate,'yyyy-MM-dd hh ...
- [转]android开发之字节顺序
原文在此 android上C++程序为小端字节顺序,和windows上一样. 而android上的JAVA程序则使用的是大端字节顺序. 用NDK和java SDK 做android程序时发现的问题,记 ...
- iOS开发- Xcode 7添加pch文件
1.打开你的Xcode工程. 在Supporting Files目录下,选择 File > New > File > iOS > Other > PCH File 然后点 ...
- iOS开源项目教程大合集
UI篇 1.MMDrawerController http://www.cnblogs.com/shangdahao/p/3142204.html 2.SVPullToRefresh http://w ...
- Apache MPM winnt
Win32DisableAcceptEx 指令在 apache2.4 被 AcceptFilter None 取代
- Android代码截屏
本文来源:http://myhpu2008.iteye.com/blog/999779 这种方法应该只能对当前Activity本身进行截屏,因而你只能在你应用程序中参照该代码对其应用程序本身截屏. i ...
- Visual Studio 2015开发Android App启动调试始终无法完成应用部署的解决方案
创建一个Android App项目后,直接启动调试发现Visual Studio Emulator for Android已成功运行,但应用始终处于Build中(等待时间超过1小时),并未如预期通过a ...
- 利用Cydia Substrate进行Android HOOK(二)
在前面关于Substrate的介绍中我们已经讲了用Substrate hook java代码,现在我们讲下怎么用它hook native代码.hook native代码我们需要编写Substrate ...