【PHP开源代码栏目提醒】:网学会员--在 PHP开源代码编辑为广大网友搜集整理了:PHPCMS整站源代码分析讲解【很不错!】 - 艺术绩等信息,祝愿广大网友取得需要的信息,参考学习。
PHPCMS 整站
代码分析讲解(一)昨天在网上逛看到这个帖子,就转来与大家分享!原作者 逆雪寒。
首先我对 PHPCMS 的 头程序文件开始讲解 : include/common.inc.
php 这个文件是程序启动的核心文件.Copy to clipboard - CODE:ltphp/
代码讲解分析: 逆雪寒. 2007 - 12 - 20/mtime explode microtimephpcms_starttime mtime1 mtime0/计算脚本开始运行的时间。
很常见的写法。
最后结算还在程序运行的终点位置。
讲到了在给各位说。
/unsetLANG _REQUEST HTTP_ENV_VARS HTTP_POST_VARS HTTP_GET_VARSHTTP_POST_FILES HTTP_COOKIE_VARS/把 HTTP_ENV_VARS HTTP_POST_VARS 全局变量设置为 NULL 因为
php4.1.0 以上默认以_POST 来替代。
unset 后防止程序运行在低版本会出现安全等问题。
比如变量注入/set_magic_quotes_runtime0//地球人都知道。
关了字符窜入库自动转意 比如 my name is onx 转成 my name ison x 为了最大的程序性能所以我们关掉吧哈哈defineIN_PHPCMS TRUE/程序入口标记。
为什么需要这个东西呢。
就好比你进一个小区,保安大哥哥肯定要你签字或是挂个鸟牌证明你是从正门进来的。
防止你翻墙进入去偷东西搞破坏。
这个入口标记也有这个功能。
在这里定义了一个常量IN_PHPCMS 为 TRUE ,然后我在其他程序文件里面检查这个标记。
如果不存在或不为真,那么就基本可以肯定你这个家伙是个小偷来的。
人可能翻墙进入。
但程序怎么翻墙呢。
只要在
php.ini 文件里面激活 allow_url_fopen 选项,include 就可以包含 URL 地址了。
你想下如果你有个 放密码的
PHP 文件。
如果给人家 include 了以后。
你怕不怕。
/definePHPCMS_ROOT str_replacequotquot / substrdirname__FILE__ 0 -8/为了程序产品的跨平台。
自动获取程序的安装目录路径 定义为 PHPCMS_ROOT 常量。
方便以后程序使用。
建议大家都这样做哦/require PHPCMS_ROOT./include/global.func.
php/包含 全局函数 global.func.
php 文件。
里面放了些程序全局都有需要用的函数.大家看到了吧。
常量 PHPCMS_ROOT 已经发挥作用。
这样程序给人家发布到了 二级目录下。
也不需要人家手动改整站根目录路径了。
。
。
自己好好理解下。
。
。
/search_arr arrayquot/ union /iquotquot/ select /iquotquot/ update /iquotquot/ outfile /iquotquot/ or/iquot/quot/ union /iquot 这个是正则的写法?不懂正则的自己百度找教程来学。
这里不详细说了/replace_arr array union select update outfile or /看这个意思很明了。
union :连接两条 SQL 语句。
outfile : 主要用来导出数据库资料到其他介质上。
干啥字要定义这两个变量呢? 在 global.func.
php 文件前面已经加载里面有个函数sfunction strip_sqlstringglobal search_arrreplace_arrreturn is_arraystring array_mapstrip_sql string :preg_replacesearch_arr replace_arr string函数里面定义了这两个变量为 global 全局变量。
那么函数里就可以直接使用了。
先讲解下这个函数吧。
顾名思义这个函数是过滤字符窜里面的 SQL 语句使得关键的 SQL 语句单词失效。
主要过滤那些 SQL 语句呢。
主要是这几个关键字: union select update outfile or 等。
因为这几个 SQL 字是极度容易在_GET 传输中给截注.这个函数写得实在精妙。
is_array 来判断 string 是否为数组。
如果 是 就 array_map函数来递归过滤 string 数组里面的每一个单元. 每个单元是一个字符窜吧?当递归调用 strip_sql 以后 is_array判断 string 肯定为假了, 因为string 已经不是数组而是字符窜。
所以 执行 preg_replace函数。
这个函数很好理解了。
就是替换了。
/_POST strip_
sql_POST_GET strip_sql_GET_COOKIE strip_sql_COOKIE/使用 strip_sql函数来过滤 _POST _GET _COOKIE一般不是
开源的站。
很少过 SQL 关键字过滤。
不过这个也是冒很大风险的。
/unsetsearch_arr replace_arr/unset 使用过但以后不需要的变量。
这个是很好的习惯。
第一不会浪费内存。
如果变量存了大量的数据字节,而后你的程序是一直不需要用的。
那么就会很浪费内存。
拉底程序性能 . 哈哈。
真很书面。
反正是好习惯我们都要学习的拉。
/magic_quotes_gpc get_magic_quotes_gpc // get_magic_quotes_gpc检测 gpc 是否系统自动转意。
gpc 是什么呢? GET POST COOKIE 来来去去就这几个东西罗。
会返回 真或假ifmagic_quotes_gpc_POST new_addslashes_POST_GET new_addslashes_GET/判断一下
系统是否打开了自动对 gpc 进行转意这个选择。
如果是的话,就不需要我们自动转意了。
如果不是那么还是要老百姓的手段。
自己动手丰衣足食。
来看下也是在 global.func.
php 文件里面定义的这个函数: 其实是一个封装好的
php 的addslashes 函数的函数。
PHP 都自己有了为什么还要自己封装成函数呢?理由很简单。
为了以后的扩展更改容易罗。
如果我们一开始就全部用 addslashes 这个函数来对 进行转意的话。
那么以后随着程序的发展。
我可能想多过滤个 之类的那如何是好呢?所以为了以后孩子的成长。
我们还是最好封起来吧。
记住:以后有可能会边的东西。
最好都封装成模块。
函数 。
类。
这样
程序的灵活度就上去了。
function new_addslashesstringifis_arraystring return addslashesstringforeachstring as key gt val stringkey new_addslashesvalreturn string这个函数也是哈哈。
我们要懂模仿。
/extract_POST EXTR_OVERWRITEextract_GET EXTR_OVERWRITE/嘿。
extract 前面加个 鸡蛋做什么呢??抑制错误的。
还不懂的话。
自己百度了。
为什么用 extract函数呢. 平时我们程序 是不是要常使用 _POST _GET 来获取传递的变量呀。
是不是感觉贼麻烦呀。
比如 _POSTxx 这样接受是挺好。
但写多了很麻烦是吧。
我是感觉麻烦。
我现在想直接就 xx 就可以获取传递过来的东西。
那怎么办呢。
就用了 extract函数来实现这么一个技巧。
这个技巧在 discuz 论坛上也有应用。
/unset_POST _GET/unset 好处不用说了吧。
释放 _POST _GET 数组 ,因为已经不需要他们了。
/gt明天放假了.今天在写点罗.放假没空写了.要陪老婆,大家看了有什么不明白的.可以跟帖问.我懂的我会回答.谢谢PHPCMS 整站
代码分析讲解(二)Copy to clipboard - CODE:/
代码讲解分析: 逆雪寒. 2007 - 12 - 21/require PHPCMS_ROOT./config.inc.
php/加栽整站的配置参数文件。
一般的程序都会有这个文件。
做什么的呢?比如一些数据库连接地址。
用户名,密码等。
需要用到的参数都定义在这个文件里面。
这样以后配置变了。
我们只要改动下这个文件里面的变量值就好。
是不是很方便呢。
呵呵. 在这里说下 require 这个加载函数。
require 和include 都是用来加载其他
PHP 文件用的。
但他们是有区别的。
require 函数:是quot预解释quot函数。
就是程序一加载,就执行了 require 函数。
而 include 呢。
是个过程加载函数。
我们可以在逻辑里比如: if 里面使用 include 来动态的加载其他程序片段。
而 require 就不行。
/require PHPCMS_ROOT./languages/.CONFIGlanguage./phpcms.lang.
php/顾名思义: 这个就是加载语言包了。
PHP的国际化目前做得最多的。
就是直接用PHP文件来实现。
在 phpcms.lang.
php 文件里面定义程序中要用到的中文信息。
然后在程序一开始就加载。
那里程序里面就可以使用这个文件里面的变量和一切。
那么就简单了。
模板上就不需要直接写中文信息了。
直接用这个文件里面定义的变量等来替换。
从而实现国际化。
over最好自己打开这个语言文件再加上自己思考下。
就知道。
原来如此简单。
/definePHPCMS_PATH CONFIGrootpathdefinePHPCMS_CACHEDIR CONFIGcachedir/CONFIGrootpath 这个就是全局配置文件 config.inc.
php 文件里面数据库信息。
等全部配置信息。
在这里把他们定用到这两个变量多。
所以干脆定义为常量。
方便使用。
再多说一个技巧: CONFIGrootpath 其实也可以写成 CONFIGrootpath 但是最好不要这样。
为什么呢。
因为PHP引擎会先判断 rootpath 是不是常量。
如果不是才会认定CONFIGrootpath 是数组。
这样性能上就差了一点点了。
再多说一个技巧: 为什么程序多数都用 单引号呢而不用 quotquot 双引号呢。
因为这样效率好 quotquot 双引号。
php 引擎还会先检查里面是否有变量,如果有就解释。
而 单引号不会做这一步的检查。
而直接就当成字符窜了。
所以效率上也会有一点点影响哦。
/CONFIGenablephplog set_error_handlerphpcms_error :error_reportingE_ERROR E_WARNING E_PARSE/CONFIGenablephplog 是 否 开 启 错 误 日 志 设 置 。
这 个 设 置 在 全 局 配 置 文 件 里面.config.inc.
php 。
这里使用了 三目运算符 偶最喜欢用了。
一些简短的逻辑判断。
可以使用 : ; 来实现比较简洁set_error_handler 这个函数就大有来头了。
php4 里面的典型自定义程序出错后行为的一个函数。
十分好用。
怎么用呢? set_error_handler函数 的参数也是一个函数。
这个函数。
反映了程序出错后行为的。
phpcms_error 函数存在 global.func.
php 全局函数里面。
function phpcms_errorerrno errmsg filename linenum varsfilename str_replacePHPCMS_ROOT . filename filename str_replacequotquot / filename // 把 win 平台的 换成/兼容常见系统的路径 ifdefinedE_STRICT defineE_STRICT 2048dt dateY-m-d H:i:serrortype array E_ERROR gt Error E_WARNING gt Warning E_PARSE gt Parsing Error E_NOTICE gt Notice E_CORE_ERROR gt Core Error E_CORE_WARNING gt Core Warning E_COMPILE_ERROR gt Compile Error E_COMPILE_WARNING gt Compile Warning E_USER_ERROR gt User Error E_USER_WARNING gt User Warning E_USER_NOTICE gt User Notice E_STRICT gt Runtime Notice user_errors arrayE_USER_ERROR E_USER_WARNING E_USER_NOTICEerr quotlterrorentrygtnquoterr . quottltdatetimegtquot . dt . quotlt/datetimegtnquoterr . quottlterrornumgtquot . errno . quotlt/errornumgtnquoterr . quottlterrortypegtquot . errortypeerrno . quotlt/errortypegtnquoterr . quottlterrormsggtquot . errmsg . quotlt/errormsggtnquoterr . quottltscriptnamegtquot . filename . quotlt/scriptnamegtnquoterr . quottltscriptlinenumgtquot . linenum . quotlt/scriptlinenumgtnquotif in_arrayerrno user_errors err . quottltvartracegtquot . wddx_serialize_valuevars quotVariablerr . quotlt/errorentrygtnnquotecho errerror_logerr 3 PHPCMS_ROOT./data/
php_error_log.xmlchmodPHPCMS_ROOT./data/
php_error_log.xml 0777就是这个鸟蛋。
现在我们慢慢来干掉他。
呵呵 这个自定义出错信息函数默认带有四个参数。
第一个参数 errno 是程序出错的等级。
第二参数是程序出错的界面信息。
第三是出现错误的程序文件名。
第四是 第几行出现错误。
第五个参数。
要不要都行是当前变量状态的快照.看吧。
我们有这些信息后。
想定义怎么样的错误信息给客户看都很容易了是吧?但现在我们是要生成错误日志呢?这里 phpcms 作者是动态生成一个XML文件来做错误日志的。
不错不错. 他使用了in_array 函 数 来 实 现 ( 因 为 比 较 简 单 , 自 己 理 解 下 ) 只 记 录 E_USER_ERRORE_USER_WARNING E_USER_NOTICE 这三个级别的错误日志信息。
n 是文本换行符 t 是制表符. 这里他使用了一个比较漂亮而不
常用的函数 wddx_serialize_value wddx 其实也是一种
xml 。
wddx_serialize_value 这个函数就是把一般变量以XML格式输出。
这样我们就不用自己模拟写 xml 了。
方便吧。
呵呵 第一个参数就是: 要格式输出的变量,第二个参数是输出的 xml 的介绍信息. 下面就是 error_log 函数。
这个函数十分有用了。
就是生成错误日志ML文件。
不需要我们 fopen 了。
方便吧。
它还有很多功能。
详细的看手册。
chmod 设置日志文件的权限是 可读可写可执行。
在
php5 中。
我习惯使用 extendsException 来定义自己的出错信息。
所以很少用 set_error_handle. 如果没开启日志功能。
那么 error_reportingE_ERROR E_WARNING E_PARSE 就运行了。
把一般出错信息先出过来。
/ifCONFIGsessionsavepath session_save_pathCONFIGsessionsavepath/定义 session 的存储路径, session 其实 也是 cookie 不过 session 是实现在服务器端的。
安全但负载重点。
这样做的好处?效率很好。
如果你在虚拟主机的话。
大家的 session cookie都放在了
php.ini 里面设置的默认地方。
文件夹臃肿就会慢罗。
是吧。
第二就是安全罗。
记得一定要定义在 session_start函数之前/session_startiffunction_existsdate_default_timezone_setdate_default_timezone_setCONFIGtimezone/
php5 开始有时区的概念了。
记得就行/headerContent-type: text/html charset.CONFIGcharset/设置页面编码.
php 编码有: 页面编码。
数据库编码。
文件内码。
如果三码相同就一般不会出现乱码. 文件内码是什么呢?每个文件都有自己的内部编码。
一般都用UTF8比较爽。
怎么改变文件内码?你用DW也行 UE 也行。
随便。
数据库编码那肯定是要指页面编码:ltmeta http-equivquotContent-Typequot c /gt 这句就是。
一般的HTML头文件都有。
那 还需要 headerContent-type: text/html charset.CONFIGcharset吗?其实需要的。
因为有些自己写的提示层呀。
或是文件里没指定页面编码的。
就很容易出现乱码那么我们就防范于未然。
header 一个编码过去。
那就OK了。
多好。
/ifgetenvHTTP_CLIENT_IP ampamp strcasecmpgetenvHTTP_CLIENT_IP unknownPHP_IP getenvHTTP_CLIENT_IPelseifgetenvHTTP_X_FORWARDED_FOR ampampstrcasecmpgetenvHTTP_X_FORWARDED_FOR unknownPHP_IP getenvHTTP_X_FORWARDED_FORelseifgetenvREMOTE_ADDR ampamp strcasecmpgetenvREMOTE_ADDR unknownPHP_IP getenvREMOTE_ADDRelseifisset_SERVERREMOTE_ADDR ampamp _SERVERREMOTE_ADDR ampampstrcasecmp_SERVERREMOTE_ADDR unknownPHP_IP _SERVERREMOTE_ADDRpreg_matchquot/d.715/quot
PHP_IP ipmatchesPHP_IP ipmatches0 ipmatches0 : unknownPHPCMS 整站
代码分析讲解(二) 续QUOTE:原帖由 peixin229 于 2008-1-19 09:46 AM 发表/
代码讲解分析: 逆雪寒. 2007 - 12 - 21/require
PHPCMS_ROOT./config.inc.
php/加栽整站的配置参数文件。
一般的程序都会有这个文件。
做什么的呢?比如一些数据库连接地址。
用户名,密码等 ...由于论坛字符限制,所以分两次发,接上面一部分。
Copy to cli
pboard - CODE:/函数 getenv 是获取环境变量。
环境变量: HTTP_CLIENT_IP 是获取客户端的IP 。
但有可能人家是通过代理来访问你的程序的呢。
那么这时候就要用 环境变量:HTTP_X_FORWARDED_FOR 了 。
包 括 getenvREMOTE_ADDR_SERVERREMOTE_ADDR 都是获取人家 IP的。
反正碰罗。
碰到那个能获取就大工告成。
/
PHP_TIME timePHP_SELF isset_SERVERPHP_SELF _SERVERPHP_SELF :isset_SERVERSCRIPT_NAME _SERVERSCRIPT_NAME :_SERVERORIG_PATH_INFO/获取当前运行的脚本名: 刚开始看是不是有点乱呢。
咋没用 if else 呢。
看这样的东西 。
我 们 最 好 从 右 看 到 左 。
这 样 比 较 好 明 白 点 。
_SERVERSCRIPT_NAME_SERVERPHP_SELF _SERVERORIG_PATH_INFO 这三个服务器全局变量都是获取当前脚本名的。
主要看服务器当前环境了。
那个存在的就获取那个。
isset 函数 十分有用。
测试一个变量是否已经定义。
注: a NULL isseta 这样会返回 false 的哦。
注意 isset 和 empty 两个函数的用法。
用得不好会出大
问题的。
自己看手册。
/
PHP_QUERYSTRING _SERVERQUERY_STRINGPHP_DOMAIN _SERVERSERVER_NAMEPHP_REFERER
PHP_SCHEME _SERVERSERVER_PORT 443 https:// :http:// //测试服务器是否启动了 ssl 连接如果是的话。
就用 https://安全连接来进行通行
PHP_PORT _SERVERSERVER_PORT 80 : :._SERVERSERVER_PORTPHP_SITEURL
PHP_SCHEME.
PHP_DOMAIN.
PHP_PORT.PHPCMS_PATHPHP_URL
PHP_SCHEME.
PHP_DOMAIN.
PHP_PORT.
PHP_SELF.
PHP_QUERYSTRING .
PHP_QUERYSTRING : /获取当前脚本的URL/db_file db_class db_.CONFIGdatabaseifdefinedIN_ADMIN //如果不是在后台。
常量 IN_ADMIN 是后台标志ifCONFIGdbiscache db_file . _cacheifCONFIGphpcache 2 // 如果在 config.inc.
php 里面开启了缓存 cachefileid md5
PHP_SELF..
PHP_QUERYSTRING //把脚本名和后面的 get 信息md5 加密,以此来生成下面的缓存目录和缓存文件 cachefiledir PHPCMS_ROOT./data/phpcache/.substrcachefileid 0 2.///缓存目录 cachefile cachefiledir.cachefileid..html //缓存文件: xxx.html 格式 iffile_existscachefile ampamp
PHP_TIME lt filemtimecachefile CONFIGphpcacheexpires //如果缓存文件存在和缓存没有过期效,那么就返回缓存文件名 require cachefile exit ifPHP_QUERYSTRING ampamp preg_matchquot/..htmhtmlshtmshtml/quotPHP_QUERYSTRING urlvar //获取传递过来的变量。
有什么用的呢?请看下面解释 parse_strstr_replacearray/ - arrayamp urlvar1/上面这部分相对复杂了点。
但没关系。
慢慢讲解. 首先缓存只针对前台.所以我们一开始就判断.这个脚本是运行在前台的而不是在后台 definedIN_ADMIN 来判断.然后呢.再看客户配置 config.inc.
php 文件是否开启了缓存. 2 就是开启了. .接着开始用一系列的规则来找出缓寸的文件名和目录: 以 脚本名:xx.
php 和后续传递的参数 xxeeampbbjj 他两的字符窜的 MD5 .以这个 md5 窜来定义出了缓存目录.和缓存文件 .接着再判断这个缓存文件是否存在和是否没过缓存有效期.如果没有就返回这个缓存文件的名字.然后到主菜了. 最后一个 if 逻辑是做什么的呢 不知道大家有没见过 这样的网址:urlhttp://www.beihai.com/dd.
php/xxhttp://www.beihai.com/dd.
php/xx/url -23/cc-22.html 他们其实都算是伪静态.优化URL用的.咋看起来还很象静态.爽. 但你可能想.这样的地址.我们写PHP程序的.怎么获取 get 变量呢? 最后 if 就是解答这个问题的. 先剥离 url 来获取 传递的字符窜.然后 str_replace 来把 / -替 换 成 标 准 的 amp 好 象 :urlhttp://www.beihai.com/dd.phpampxx23ampcc22http://www.beihai.com/dd.phpampxx23ampcc22/url/PHPCMS 整站
代码分析讲解(三)Copy to .