PHP大型Web应用入门(三) php
接上一篇:仍是郁字符长度的限制。
早期版本的PHPWIND论坛的cache机制是不好的,虽然它很快,可是很脆弱,一旦cache文件损坏或丢失,它不会本身去建立它,而是直接致使程序没法运行,这种只能叫作临时文件,而不能叫cache。我不知道如今的PHPWIND什么样,由于我一直没兴趣去看它……
下面的部分是mSession的实现,它只是模拟了session的存取过程,并对系统session进行了改进。它用了Hash目录。它的缺点是在程序结束部分还要Rewrite一下,把数据更新到session文件里,固然这个很容易被改进。
< ? php class BsmSession { var $ sid ; var $ sess_file ; function mSession_Start ( ) { // Special Function...session_start() global $ cookie_sess_id_varname , $ cookie_path , $ sess_liftime , $ mSession ; $ sid = $ _COOKIE [ $ cookie_sess_id_varname ] ? $ _COOKIE [ $ cookie_sess_id_varname ] : $ this - > _Gen_Sid( ) ; setcookie ( $ cookie_sess_id_varname , $ sid , $ sess_liftime , $ cookie_path ) ; $ sess_file = $ this - > _Hash_Dir( $ sid ) . 'sess_' . $ sid ; if ( file_exists ( $ sess_file ) ) { if ( ! @ $ fp = fopen ( $ sess_file , 'rb' ) ) { // Debug Info...No Log. fatal_error ( 'Session Error...' ) ; } if ( 0 = = ( $ fl = filesize ( $ sess_file ) ) ) $ sess_content = '' ; else $ sess_content = fread ( $ fp , $ fl ) ; } else { if ( ! @ $ fp = fopen ( $ sess_file , 'wb' ) ) { // Debug Info...No Log. fatal_error ( 'Session Error...' ) ; } $ sess_content = '' ; } fclose ( $ fp ) ; $ this - > sid = $ sid ; $ this - > sess_file = $ sess_file ; $ mSession = unserialize ( $ sess_content ) or $ mSession = array ( ) ; } function mSession_Destroy ( ) { global $ mSession ; $ mSession = array ( ) ; return @ unlink ( $ this - > sess_file) ; } function mSession_Rewrite ( ) { // Restore Session Data into Session File global $ mSession ; $ sess_content = serialize ( $ mSession ) ; if ( ! @ $ fp = fopen ( $ this - > sess_file, 'wb' ) ) { // Debug Info...No Log. fatal_error ( 'Session Error...' ) ; } fwrite ( $ fp , $ sess_content ) ; fclose ( $ fp ) ; return ; } function _Hash_Dir ( $ sid ) { // Hash the Session file Dir global $ user_sess_base_dir ; $ sess_dir = $ user_sess_base_dir . substr ( $ sid , 0, 1) . '/' . substr ( $ sid , 16, 1) . '/' ; return $ sess_dir ; } function _Gen_Sid ( ) { // Gen an Unique Session ID $ key_1 = rand ( 32768, 65535) ; $ key_2 = microtime ( ) ; $ key_3 = sha1 ( time ( ) ) ; $ sid = md5 ( $ key_1 . $ key_3 . $ key_2 ) ; return $ sid ; } function _Get_Sid ( ) { // Get Current Session ID global $ cookie_sess_id_varname ; $ sid = $ _COOKIE [ $ cookie_sess_id_varname ] ? $ _COOKIE [ $ cookie_sess_id_varname ] : FALSE ; return $ sid ; } } ? > html |
Hash目录是一种优化文件存储性能的方法。不管是Windows仍是Linux,不管是NTFS仍是ext3,每一个目录下所能容纳的项目数是有限的。并非不能保存,而是当项目数量过大的时候,会下降文件索引速度,因此权衡一个目录下应该保存多少文件是很必要的。保存得多了会影响性能,保存得少了会形成目录太多和空间浪费。因此当保存大批文件的时候,须要有一种算法能将文件比较均匀地“打散”在不一样的子目录下以提升每一级的索引速度,这种算法就是 Hash。一般用的MD五、sha1等均可以用来作Hash目录,个人mSession里也一样使用了MD5,取得sessionID的第一位和第九位,这就构成了两级Hash路径,也就是说,系统把全部的Session文件分散到了16×16=256个子目录下。假设Linux每一个目录下保存1000个文件能够得到最好的空间性能比,那么系统在理想状况下能够同时有256000个session文件在被使用。
Hash目录还被普遍应用在备份、图库、电子邮件、静态页生成等文件密集型应用上。
再来点一下个人模板类,我很懒地保留了Discuz模板函数的全部标签。一方面是我确实很懒,另外一方面是我曾经试图修改Discuz,把它改为一个专用的版本,不过这是一个类,它的使用方法和Discuz函数没什么两样,都是include一个parse结果返回的文件名。
所不一样的是在处理{template}标签的时候。Discuz的处理方式是把{template}替换成再次调用模板解析函数去解析另外一个模板文件,这样,模板函数可能会被调用屡次,编译的结果里也会有不少include另外一个模板文件Parse结果的地方。这里涉及另外一个优化点——尽可能少地 include文件。过多地include会带来更多的IO开销和CPU处理开销,因此我把{template}改为直接读入文件内容,而后再 parse。这样一个模板文件即便有1000个{template},编译的结果也只有一个文件。
这个模板类用起来是如此地简单方便,更重要的是,它确实很快~~呵呵,我历来不否定我有时候也会作一些比较有用的事,哈哈: 算法
阅读全文>>cookie