宿迁网站建设开发,公司 宜宾网站建设,个人做旅游网站怎样,珠海移动网站定制?php /* April 18,2012 discuz二次开发学习 author:xuqin 不能为了完成任务去做一件事#xff0c;要举一反三#xff0c;融会贯通的去学习。 */ error_reporting(0); /* * error_reporting(0); //抑制所有的出错信息 * error_reporting(E_ALL);//显示所有的出错信息 … ?php /* April 18,2012 discuz二次开发学习 author:xuqin 不能为了完成任务去做一件事要举一反三融会贯通的去学习。 */ error_reporting(0); /* * error_reporting(0); //抑制所有的出错信息 * error_reporting(E_ALL);//显示所有的出错信息 */ set_magic_quotes_runtime(0); /* * set_magic_quotes_runtime(0); //关闭魔法引用 * set_magic_quotes_runtime(1); //开启魔法引用 * 什么事魔术引号 * 当打开时所有的 单引号双引号\反斜线和 NULL 字符都会被自动加上一个反斜线进行转义。 * 这和 addslashes() 作用完全相同。 * 一共有三个魔术引号指令 * magic_quotes_gpc 影响到 HTTP 请求数据GETPOST 和 COOKIE。不能在运行时改变。在 PHP 中默认值为 on。 参见 get_magic_quotes_gpc()。 * magic_quotes_runtime 如果打开的话大部份从外部来源取得数据并返回的函数包括从数据库和文本文件所返回的数据都会被反斜线转义。该选项可在运行的时改变在 PHP 中的默认值为 off。 参见 set_magic_quotes_runtime() 和 get_magic_quotes_runtime()。 * magic_quotes_sybase 如果打开的话将会使用单引号对单引号进行转义而非反斜线。此选项会完全覆盖 magic_quotes_gpc。如果同时打开两个选项的话单引号将会被转义成 。而双引号、反斜线 和 NULL 字符将不会进行转义。 如何取得其值参见 ini_get()。 */ $mtime explode( , microtime()); /* * microtime()取得Unix 时间戳和微秒数后使用explode()进行切割并存进数组变量$mtime; * eg * echo microtime(); //将显示 0.29353300 1164349567 (根据时间的不同会显示不同的数字但格式是一样的 * $mtime[0]0.29353300; * $mtime[1]1164349567; */ $discuz_starttime $mtime[1] $mtime[0];//得到脚本开始运行的时间 define(SYS_DEBUG, FALSE);//关闭debug模式 /* * 编译方式的本质区别 Debug 通常称为调试版本它包含调试信息并且不作任何优化便于程序员调试程序。Release 称为发布版本它往往是进行了各种优化使得程序在代码大小和运行速度上都是最优的以便用户很好地使用。 */ define(IN_DISCUZ, TRUE);//用于防止非法引用定义一个常量表示只有DISCUZ才可以使用本脚本 define(DISCUZ_ROOT, substr(dirname(__FILE__), 0, -7));//定义常量DISCUZ_ROOT的值(即bbs的路径) define(MAGIC_QUOTES_GPC, get_magic_quotes_gpc());//将魔术引号开启状态存入常量 !defined(CURSCRIPT) define(CURSCRIPT, );//这个写法很特别哦初始化当前运行的脚本名称为空CURSCRIPT这个常量在很多页面都有意思是如果没定义CURSCRIPT常量, 则定义CURSCRIPT为空。 if(PHP_VERSION 4.1.0) {//php旧版本超全局变量兼容处理注意是引用赋值$ php基础知识哦去复习下吧 $_GET $HTTP_GET_VARS; $_POST $HTTP_POST_VARS; $_COOKIE $HTTP_COOKIE_VARS; $_SERVER $HTTP_SERVER_VARS; $_ENV $HTTP_ENV_VARS; $_FILES $HTTP_POST_FILES; } /* * 作用当PHP版本小于4.1.0 的时候使用传址方式获取内置全局变量 * 示例 * 为什么要使用传址而不是传值方式 * 要点在变量前加 符号既是传址 * ?php * $a1; * $b$a; * $b; * echo b.$b. a.$a; //显示b2 a1 可以看到 b变了而a 却还是没变 * * echo br; * $c1; * $d$c; //注意这行 符号 * $d; * echo d.$d. c.$c; //显示: d2 c2 可以看到d变了可是c也变了 * ? */ if (isset($_REQUEST[GLOBALS]) OR isset($_FILES[GLOBALS])) { exit(Request tainting attempted.); } /* * 众所周知当php.ini里面的register_globalson时各种变量都被注入代码例如来自 HTML 表单的请求变量。再加上 PHP 在使用变量之前是无需进行初始化的。那么就有可能导致不安全假如有人恶意发出这么一个get请求http://yourdomain /unsafe.php?GLOBALS,那么就会清除$GLOBALS变量的值而导致不安全。 * * register_globals是php.ini里的一个配置这个配置影响到php如何接收传递过来的参数如果你的问题是为什么我的表单无法传递数据为什么我的程序无法得到传递过来的变量等等那么你需要仔细的阅读以下的内容。 * register_globals的值可以设置为On或者Off我们举一段代码来分别描述它们的不同。 * 代码: * form namefrmTest idfrmTest actionURL * input typetext nameuser_name iduser_name * input typepassword nameuser_pass iduser_pass * input typesubmit valuelogin * /form * 当register_globalsOff的时候下一个程序接收的时候应该用$_GET[user_name] 和$_GET[user_pass]来接受传递过来的值。注当form的method属性为post的时候应该用$_POST[user_name]和$_POST[user_pass] * 当register_globalsOn的时候下一个程序可以直接使用$user_name和$user_pass来接受值。 * 顾名思义register_globals的意思就是注册为全局变量所以当On的时候传递过来的值会被直接的注册为全局变量直接使用而Off的时候我们需要到特定的数组里去得到它。 * */ require_once DISCUZ_ROOT../include/global.func.php;//引入全局函数库很重要 /* * 这里复习下require;require_once();include();incdlue_once()区别 * require() *include() *这两一般放在代码前面功能除了处理失败情况不一样其它都是一样如果包含的文件不存在时require会停止运行发生致命错误提示。而include则是只显示一警告代码会继续执行。 *require_once() *include_once() *这两一个一般放在流程控制中除了以上错误处理的区别外功能都是一样的跟没有once的区别就是包含的文件已经在前包含过第二次包含不会再被引入。 */ define(IS_ROBOT, getrobot());//定义IS_ROBOT常量判断浏览此页面的user-agent是否为搜索引擎蜘蛛getrobot函数见global.func.php if(defined(NOROBOT) IS_ROBOT) {//如果定义了此页不能被机器人找到但是发现访问者是搜索引擎蜘蛛则返回禁止信息。 exit(header(HTTP/1.1 403 Forbidden)); } foreach(array(_COOKIE, _POST, _GET) as $_request) {//过滤提交的变量提高安全性 foreach($$_request as $_key $_value) { $_key{0} ! _ $$_key daddslashes($_value);//变量名第一个字母不能为下划线防止有类似伪造的$_POST变量产生 } } /* * addslashes() 函数在指定的预定义字符前添加反斜杠。 * [单引号 ()双引号 ()反斜杠 (\)NULL]默认情况下PHP 指令 magic_quotes_gpc 为 on对所有的 GET、POST 和 COOKIE 数据自动运行 addslashes()。不要对已经被 magic_quotes_gpc 转义过的字符串使用 addslashes()因为这样会导致双层转义。遇到这种情况时可以使用函数 get_magic_quotes_gpc() 进行检测。 * stripcslashes() 函数 删除 由 addcslashes() 函数添加的反斜杠。也可删除服务器开启magic_quotes_gpc后自动添加上的反斜杠 */ if (!MAGIC_QUOTES_GPC $_FILES) {//转义$_FILES变量注意这里先要判断MAGIC_QUOTES_GPC常量的状态如果是关闭的才进行转义否则会造成多次转义 $_FILES daddslashes($_FILES); } $charset $dbcharset $forumfounders $metakeywords $extrahead $seodescription ; //全局变量初始化初始化文件字符集数据库字符集版块创建者SEO的论坛关键字、描述头部其他信息等变量 $plugins $hooks $admincp $jsmenu $forum $thread $language $actioncode $modactioncode $lang array(); /* * 初始化插件钩子后台管理js弹出菜单版块帖子语言动作代码系统提示信息等数组 * [钩子]实际上是一个处理消息的程序段通过系统调用把它挂入系统。每当特定的消息发出在没有到达前台目的窗口前钩子程序就先捕获该消息亦即钩子函数先得到控制权。这时钩子函数即可以加工处理改变该消息也可以不作处理而继续传递该消息还可以强制结束消息的传递。 */ require_once DISCUZ_ROOT../config.inc.php;//引入系统配置文件内含如数据库连接信息、cookie域、UC信息等 $_DCOOKIE $_DSESSION $_DCACHE $_DPLUGIN $advlist array();//初始化cookiesession缓存插件广告列表等数组 $prelength strlen($cookiepre);//定义获取COOKIE前缀长度$prelength为$cookiepre的长度(见config.inc) foreach($_COOKIE as $key $val) { if(substr($key, 0, $prelength) $cookiepre) { $_DCOOKIE[(substr($key, $prelength))] MAGIC_QUOTES_GPC ? $val : daddslashes($val); } } /* * 从浏览器$_COOKIE得到$_DCOOKIE数组如果cookie的前缀与系统配置的cookie前缀相同则填入各cookie的值 这里$_DCOOKIE各变量的名称是不包含前缀的例如$_COOKIE[tmp_cook1]变成了$_DCOOKIE[cook1]同时对值进行转义 */ unset($prelength, $_request, $_key, $_value); /* * 上面对COOKIE遍历完成后便立即销毁$prelength等相关变量。 * 清空一些无用变量如临时的$_POST、$_GET等(因为已经在本文件前面处理中得到了很多的单独变量) */ $inajax !emptyempty($inajax);//先定义一个备用的变量吧与ajax有关吗 $timestamp time();//获得一个当前的时间戳变量如1334714617与前面到microtime不同time()只会得到毫秒数 if($attackevasive CURSCRIPT ! seccode) { require_once DISCUZ_ROOT../include/security.inc.php;//防御文件根据$attackevasive设定的不同级别做相应处理。 } /* * 是否启用攻击防御。$attackevasive默认为0关闭论坛防御。如果配置文件config.inc定义了论坛防御级别且当前脚本文件名不是seccode验证码则引入相关防御的文件 */ require_once DISCUZ_ROOT../include/db_.$database..class.php;//引入数据库处理类 $PHP_SELF $_SERVER[PHP_SELF] ? $_SERVER[PHP_SELF] : $_SERVER[SCRIPT_NAME];//获得当前执行脚本的文件相对路径 $BASESCRIPT basename($PHP_SELF);//返回路径的文件名部分 $boardurl htmlspecialchars(http://.$_SERVER[HTTP_HOST].preg_replace(/\/(api|archiver|wap)?\/*$/i, , substr($PHP_SELF, 0, strrpos($PHP_SELF, /)))./); /* * 取当前url 返回bbs的urlhtmlspecialchars将特殊字符”“等转换为”lt $gt“等仔细看下substr、strpos那段看这样是什么效果 * strrpos() 函数查找字符串在另一个字符串中最后一次出现的位置 * preg_replace() 执行一个正则表达式的搜索和替换 */ if(getenv(HTTP_CLIENT_IP) strcasecmp(getenv(HTTP_CLIENT_IP), unknown)) { $onlineip getenv(HTTP_CLIENT_IP); } elseif(getenv(HTTP_X_FORWARDED_FOR) strcasecmp(getenv(HTTP_X_FORWARDED_FOR), unknown)) { $onlineip getenv(HTTP_X_FORWARDED_FOR); } elseif(getenv(REMOTE_ADDR) strcasecmp(getenv(REMOTE_ADDR), unknown)) { $onlineip getenv(REMOTE_ADDR); } elseif(isset($_SERVER[REMOTE_ADDR]) $_SERVER[REMOTE_ADDR] strcasecmp($_SERVER[REMOTE_ADDR], unknown)) { $onlineip $_SERVER[REMOTE_ADDR]; } /* * 获得用户到ip地址存入$onlineip变量 * 注意PHP三个获取ip的系统变量。 * HTTP_CLIENT_IP 是tcp/ip协议里得到的ip地址apache收到请求并返回就是要返回到这个ip去。 * HTTP_X_FORWARDED_FOR 要想透过代理服务器取得客户端的真实 IP 地址。 * REMOTE_ADDR 取得客户端的 IP地址如果客户端是使用代理服务器来访问那取到的就是代理服务器的IP地址。 */ preg_match(/[\d\.]{7,15}/, $onlineip, $onlineipmatches);//使用正则匹配函数得到符合格式的ip地址看看ip是不是点分段7-15个数字之间 $onlineip $onlineipmatches[0] ? $onlineipmatches[0] : unknown;//如果上面获取到符合ip格式的ip就赋值给$onlineip unset($onlineipmatches);//立即清空 IP检查变量方便下次处理 $cachelost (include DISCUZ_ROOT../forumdata/cache/cache_settings.php) ? : settings; extract($_DCACHE[settings]); /* * 读取论坛设置的缓存文件cache_settings.php * 如果能够正常读到cachelost为空既没有lost丢失这一步得到$_DCACHE[settings]数组很重要很多变量以后都要用到 * 这一段是获得./forumdata/cache/cache_settings.php即缓存下的设置数组并展开方便以后的写法 * 将setting数组变量导入符号表成为独立变量的形式前面循环$$_key $value处理$_POST等也是这个原理吧 */ if($gzipcompress function_exists(ob_gzhandler) !in_array(CURSCRIPT, array(attachment, wap)) !$inajax) { ob_start(ob_gzhandler); } else { $gzipcompress 0; ob_start();//输出缓存开启输出缓冲 } /* * $gzipcompress是否启用gzip此变量来自extract($_DCACHE[settings]) * 检查gzip是不是打开了打开就用ob_gzhandler没有就用ob_start。 * 如果开启了gzip压缩并且ob_gzhandler函数存在并且当前脚本不是附件和wap并且不是ajax则开始使用ob_gzhandler压缩,否则只进行输出缓存而不压缩 */ if(!emptyempty($loadctrl) substr(PHP_OS, 0, 3) ! WIN) { if($fp fopen(/proc/loadavg, r)) { list($loadaverage) explode( , fread($fp, 6)); fclose($fp); if($loadaverage $loadctrl) { header(HTTP/1.0 503 Service Unavailable); include DISCUZ_ROOT../include/serverbusy.htm; exit(); } } } /* * 此段为在linux平台下处理负载平衡 * 对于非win平台进行服务器负载判断并进行操作。$loadctrl为负载临界值。 */ if(in_array(CURSCRIPT, array(index, forumdisplay, viewthread, post, topicadmin, register, archiver))) { $cachelost . (include DISCUZ_ROOT../forumdata/cache/cache_.CURSCRIPT..php) ? : .CURSCRIPT; } /* * 继续判断当前dz缓存存在的状况看看index, forumdisplay, viewthread这些文件是不是缓存了有的话把它装到$cachelost这个变量中。 * 对不同的脚本页面引入不同的缓存文件 */ $db new dbstuff; $db-connect($dbhost, $dbuser, $dbpw, $dbname, $pconnect, true, $dbcharset); $dbuser $dbpw $dbname $pconnect NULL; /* * 这里是初始化一个dbstull类的实例也就是说前面的require_once DISCUZ_ROOT../include/db_.$database..class.php;在这里用上了 * 然后连接数据库并清理相关变量。由此可见DZ的安全性考虑真是牛到不行了。小气鬼 呵呵 */ $sid daddslashes(($transsidstatus || CURSCRIPT wap) (isset($_GET[sid]) || isset($_POST[sid])) ? (isset($_GET[sid]) ? $_GET[sid] : $_POST[sid]) : (isset($_DCOOKIE[sid]) ? $_DCOOKIE[sid] : )); /* * 这里是个很长的三元运算符哦对自定义的回话标识符进行过滤 * 开启sid后即使禁用cookie也可以登陆论坛$transsidstatus也是extract($_DCACHE[setting])得到的,所以熟悉cache_setting里面的变量才不会经常一头雾水 * 如果开启了$sid且是wap且从GET或POST传递来$sid,则从GET或者POST中取得否则从cookie取得 */ $discuz_auth_key md5($_DCACHE[settings][authkey].$_SERVER[HTTP_USER_AGENT]); /* 定义验证字符串验证钥匙。authkey 0ee545SPQKK3jOP2也是extract($_DCACHE[setting])定义的。 * $_SERVER[HTTP_USER_AGENT]获取客户端浏览器的型号这个不是一定准确的是可以随意伪造的 */ list($discuz_pw, $discuz_secques, $discuz_uid) emptyempty($_DCOOKIE[auth]) ? array(, , 0) : daddslashes(explode(\t, authcode($_DCOOKIE[auth], DECODE)), 1); /* * 初始化变量密码安全问题用户id如果$_DCOOKIE[auth]为空则初始化他们否则解码并读取相应变量。 * 对常用变量进行赋值。$discuz_secques为用户按安全验证回答的哈希值。authcode()根据$authkey对输入参数进行加密解密的操作。 * 这一段是用来检查是不是$_DCOOKIE[‘auth’]存在如果有的话就把其中存放的东西分别给$discuz_pw, $discuz_secques, $discuz_uid这三个变量分别对应密码提示问题和uid。 */ $newpm $newpmexists $sessionexists $seccode 0;//初始化用户的新消息安全问题验证码等变量 $membertablefields m.uid AS discuz_uid, m.username AS discuz_user, m.password AS discuz_pw, m.secques AS discuz_secques, m.adminid, m.groupid, m.groupexpiry, m.extgroupids, m.email, m.timeoffset, m.tpp, m.ppp, m.posts, m.digestposts, m.oltime, m.pageviews, m.credits, m.extcredits1, m.extcredits2, m.extcredits3, m.extcredits4, m.extcredits5, m.extcredits6, m.extcredits7, m.extcredits8, m.timeformat, m.dateformat, m.pmsound, m.sigstatus, m.invisible, m.lastvisit, m.lastactivity, m.lastpost, m.newpm, m.accessmasks, m.editormode, m.customshow, m.customaddfeed; /* * 将用户表中所有需要读取的字段放在一个字符串中便于后面的sql语句调用 */ if($sid) {//如果变量$sid存在 if($discuz_uid) {//如果cookie中有用户uid则根据uid在数据库session表、member表中查询取出相关字段值 $query $db-query(SELECT s.sid, s.styleid, s.groupid6 AS ipbanned, s.pageviews AS spageviews, s.lastolupdate, s.seccode, $membertablefields FROM {$tablepre}sessions s, {$tablepre}members m WHERE m.uids.uid AND s.sid$sid AND CONCAT_WS(.,s.ip1,s.ip2,s.ip3,s.ip4)$onlineip AND m.uid$discuz_uid AND m.password$discuz_pw AND m.secques$discuz_secques); } else {//如果cookie中没有用户uid则仅仅从session表中取出相关信息 $query $db-query(SELECT sid, uid AS sessionuid, groupid, groupid6 AS ipbanned, pageviews AS spageviews, styleid, lastolupdate, seccode FROM {$tablepre}sessions WHERE sid$sid AND CONCAT_WS(.,ip1,ip2,ip3,ip4)$onlineip); } /* * groupid6IP Banned 被禁止的ip * MySQL的几个实用字符串函数 * concat()可以连接一个或者多个字符串但是在连接字符串的时候只要其中一个是NULL,那么将返回NULL * concat_ws()表示concat with separator,即有分隔符的字符串连接在执行的时候,不会因为NULL值而返回NULL * group_concat()可用来行转列, * repeat()用来复制字符串,如select repeat(ab,2);ab表示要复制的字符串2表示复制的份数 */ ? 本文转自许琴 51CTO博客原文链接http://blog.51cto.com/xuqin/882308如需转载请自行联系原作者