免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1913 | 回复: 1
打印 上一主题 下一主题

Discuz 7.2坑爹集锦-PHP篇3........ [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2012-01-13 10:51 |只看该作者 |倒序浏览
Discuz 7.2坑爹集锦-PHP篇3........








类型:        变量使用
坑爹指数:    ★★★
代码:
  1.    include/post.func.php=216
  2. $anew['perm'] = $allowsetattachperm ? $anew['perm'] : 0;
  3. 代码:        include/post.func.php=472
  4. $attach['perm'] = $allowsetattachperm ? intval($attachperm[$key]) : 0;
复制代码
点评:        同上

-------------------------------------------------------------------------------------------------------------------------


类型:        变量使用
坑爹指数:    ★★
代码:        pm.php=47

Php代码
  1. $pmstatus = uc_pm_checknew($discuz_uid, 4);   
  2. $filter = !emptyempty($filter) && in_array($filter, array('newpm', 'privatepm', 'announcepm')) ? $filter : ($pmstatus['newpm'] ? 'newpm' : 'privatepm');  

  3.     $pmstatus = uc_pm_checknew($discuz_uid, 4);
  4.     $filter = !empty($filter) && in_array($filter, array('newpm', 'privatepm', 'announcepm')) ? $filter : ($pmstatus['newpm'] ? 'newpm' : 'privatepm');  
复制代码
点评:         未对返回值$pmstatus['newpm']有效性进行判断

-------------------------------------------------------------------------------------------------------------------------


类型:        变量使用
坑爹指数:    ★★
代码:        pm.php=61

Php代码
  1. foreach($ucdata['data'] as $pm) {   
  2. ....   
  3. }   

  4.     foreach($ucdata['data'] as $pm) {
  5.     ....
  6.     }   
复制代码
点评:        未对 $ucdata变量'data'键有效做判断就直接开始循环,相当于对一个可能不存在的变量进行访问并迭代。问题出在line49调用uc_pm_list()对$ucdata赋值,而ucc/control/pm.php: onls() 函数返回值$result未初始化'data'键名。
虽然PHP是若类型,但好歹对函数返回值先做个判断再操作吧。偷懒也就少些几行代码,可调试维护时花的时间就多了。



-------------------------------------------------------------------------------------------------------------------------

类型:        字符处理
坑爹指数:    ★★★★
症状:        边栏模块最新帖最新回复对标题中单引号显示为'
点评:        不知道为何一直没修复这个bug,难道是我修改其他代码关联影响到这儿?反正根源是DZ在入库时htmlspecialchars()只对双引号处理而未对单引号转义
FIX:        修改如下文件调用带ENT_QUOTES参数的htmlspecialchars()函数来替代str_replace()函数处理

Php代码
  1. include/request.func.php   
  2.     $datalist[$data['tid']]['subject'] = isset($data['subject']) ? str_replace('\\\'', ''', addslashes($data['subject'])) : NULL;  

  3. include/request.func.php
  4.     $datalist[$data['tid']]['subject'] = isset($data['subject']) ? str_replace('\\\'', ''', addslashes($data['subject'])) : NULL;  
复制代码
FIXTO:

Php代码
  1.    $datalist[$data['tid']]['subject'] = isset($data['subject']) ? htmlspecialchars(htmlspecialchars_decode($data['subject']), ENT_QUOTES) : NULL;   
  2. 然后修改global.func.php, ucs/mode/base.php, ucclient/mode/base.php的cutstr()函数:   
  3.     //$string = str_replace(array('&amp;', '&quot;', '&lt;', '&gt;', '&#39;'), array('&', '"', '<', '>', '\''), $string);   
  4.     $string = htmlspecialchars_decode($string, ENT_QUOTES);   
  5. ....   
  6.     //$strcut = str_replace(array('&', '"', '<', '>', '\''), array('&amp;', '&quot;', '&lt;', '&gt;', '&#39;'), $strcut);   
  7.     $strcut = htmlspecialchars($strcut, ENT_QUOTES);  

  8.     $datalist[$data['tid']]['subject'] = isset($data['subject']) ? htmlspecialchars(htmlspecialchars_decode($data['subject']), ENT_QUOTES) : NULL;
  9. 然后修改global.func.php, ucs/mode/base.php, ucclient/mode/base.php的cutstr()函数:
  10.     //$string = str_replace(array('&amp;', '&quot;', '&lt;', '&gt;', '&#39;'), array('&', '"', '<', '>', '\''), $string);
  11.     $string = htmlspecialchars_decode($string, ENT_QUOTES);
  12. ....
  13.     //$strcut = str_replace(array('&', '"', '<', '>', '\''), array('&amp;', '&quot;', '&lt;', '&gt;', '&#39;'), $strcut);
  14.     $strcut = htmlspecialchars($strcut, ENT_QUOTES);  
复制代码
-------------------------------------------------------------------------------------------------------------------------

类型:        页面效果
坑爹指数:    ★
症状:        当bbcodeoff时帖子中‘最后修改’的标签混乱
FIX:        include/discuzcode.func.php: 添加一段判断
line126开始的判断拆分开

Php代码
  1. if(!$bbcodeoff && $allowbbcode) {// line126   
  2.     ....   
  3. }            // line201  

  4.     if(!$bbcodeoff && $allowbbcode) {// line126
  5.         ....
  6.     }            // line201  
复制代码
修改成

Php代码
  1. if($allowbbcode) {        // line126   
  2.     if (!$bbcodeoff) {   
  3.         .....   
  4.     }                  
  5.     // 添加开始   
  6.     elseif ($bbcodeoff && substr($message, 0, 5) === '[i=s]') {        // allow parse '[i=s]last modified by [/i]' even if bbcodeoff   
  7.         $message = preg_replace('/^\[i=s\](.*)\[\/i\]/', '<i class="pstatus">\\1</i>', $message );   
  8.     } //添加结束   
  9. }        // line201+n  

  10.     if($allowbbcode) {        // line126
  11.         if (!$bbcodeoff) {
  12.             .....
  13.         }               
  14.         // 添加开始
  15.         elseif ($bbcodeoff && substr($message, 0, 5) === '[i=s]') {        // allow parse '[i=s]last modified by [/i]' even if bbcodeoff
  16.             $message = preg_replace('/^\[i=s\](.*)\[\/i\]/', '<i class="pstatus">\\1</i>', $message );
  17.         } //添加结束
  18.     }        // line201+n  
复制代码
-------------------------------------------------------------------------------------------------------------------------

类型:        逻辑错误
坑爹指数:    ★★★★
代码:        topicadmin.php ~320    分割主题

Php代码
  1. $db->query("UPDATE {$tablepre}posts SET first='1', subject='$subject' WHERE fid='$waiting_fid' AND pid='".$splitauthors[0]['pid']."'" );      

  2. $db->query("UPDATE {$tablepre}posts SET first='1', subject='$subject' WHERE fid='$waiting_fid' AND pid='".$splitauthors[0]['pid']."'" );  
复制代码
点评:        first='1'只设置了一次,如果分割主题时选择包含了1楼那么原主题内变成1楼的帖子的first依然为0. 本来在不支持事务的MyISAM引擎上做分隔主题这种操作就具有一定危险性,不过DZ更直接增加了这个这个机率。提醒你分割主题时不要把顶楼分割出去哟,不然剩下变成1楼的帖子将会成为孤儿。多来几次你就会明确记住这个准则了,也不会因为数据库偶尔非原子性操作带来的随机故障而烦恼。这多么简单啊。呵呵
FIX:        line327

Php代码  
$db->query("UPDATE {$tablepre}posts SET subject='".addslashes($thread['subject'])."' WHERE pid='$fpost[pid]'");  

$db->query("UPDATE {$tablepre}posts SET subject='".addslashes($thread['subject'])."' WHERE pid='$fpost[pid]'");
  
修改为

Php代码  
$db->query("UPDATE {$tablepre}posts SET first=1, subject='".addslashes($thread['subject'])."' WHERE pid='$fpost[pid]'");  

$db->query("UPDATE {$tablepre}posts SET first=1, subject='".addslashes($thread['subject'])."' WHERE pid='$fpost[pid]'");  



-------------------------------------------------------------------------------------------------------------------------

类型:        执行流程
坑爹指数:    ★★★
代码:        include/common.inc.php 349

Php代码  
$forum = $db->fetch_first("SELECT t.tid, t.closed,".(defined('SQL_ADD_THREAD') ? SQL_ADD_THREAD : '')." f.*, ff.* $accessadd1 $modadd1, f.fid AS fid   
    FROM {$tablepre}threads t ....   
$tid = $forum['tid'];  

        $forum = $db->fetch_first("SELECT t.tid, t.closed,".(defined('SQL_ADD_THREAD') ? SQL_ADD_THREAD : '')." f.*, ff.* $accessadd1 $modadd1, f.fid AS fid
            FROM {$tablepre}threads t ....
        $tid = $forum['tid'];  
点评:        如果查询结果空$forum将会false,不做判断而直接赋值给$tid会出错,否则就可能要继续执行到后继的viewthreads.php中的判断,浪费系统资源。另外viewthreads.php 也未对$tid判断即以此为条件直接查询,徒增DB负担(MySQL会有 ‘Impossible WHERE noticed after reading const tables’ )
FIX:        应该查询结束后立即对$forum做判断并设置一个变量作标志再考虑给$tid赋值然后在当前页面最底部判断,如果标志真则立即输出404头直接退出。

-------------------------------------------------------------------------------------------------------------------------


类型:        未知
坑爹指数:    ★★★★
代码:        uc_client/model/note.php=64

Php代码
  1. foreach((array)$this->apps as $appid => $app) {   
  2.     $appid = $app['appid'];        <---------??   
  3.     if($appid == intval($appid)) {   
  4.         if($appids && !in_array($appid, $appids)) {   
  5.             $appadd[] = 'app'.$appid."='1'";   
  6.         } else {   
  7.             $varadd[] = "('noteexists{$appid}', '1')";   
  8.         }   
  9.     }   
  10. }  

  11.         foreach((array)$this->apps as $appid => $app) {
  12.             $appid = $app['appid'];        <---------??
  13.             if($appid == intval($appid)) {
  14.                 if($appids && !in_array($appid, $appids)) {
  15.                     $appadd[] = 'app'.$appid."='1'";
  16.                 } else {
  17.                     $varadd[] = "('noteexists{$appid}', '1')";
  18.                 }
  19.             }
  20.         }  
复制代码
点评:        一直没研究明白这个赋值要表达什么意思。难道这位当时正在韩大嘴语录,看到“瞄的是A,想的是B,解说的是C,观众以为是D,其实指的是E”这一段,顿悟,遂看到是代码,想的是妹妹,说的是工资,同事以为是八卦,领导以为是抽风~
FIX:    以我类人猿的智商估计可能是这样:

Php代码
  1. foreach((array)$this->apps as $appid => $app) {   
  2.     if(intval($appid) == $app['appid']) {        // 帮你精简一行代码   
  3.         if($appids && !in_array($appid, $appids)) {   
  4.             $appadd[] = 'app'.$appid."='1'";   
  5.         } else {   
  6.             $varadd[] = "('noteexists{$appid}', '1')";   
  7.         }   
  8.     }   
  9. }  

  10.         foreach((array)$this->apps as $appid => $app) {
  11.             if(intval($appid) == $app['appid']) {        // 帮你精简一行代码
  12.                 if($appids && !in_array($appid, $appids)) {
  13.                     $appadd[] = 'app'.$appid."='1'";
  14.                 } else {
  15.                     $varadd[] = "('noteexists{$appid}', '1')";
  16.                 }
  17.             }
  18.         }  
复制代码
本来计划单独开一PHP优化篇。后来发现下面坑爹代码多数会影响性能(PHP以及数据库执行),修复了bug即优化。故合并为一篇。

补充个优化PHP的:
如果你的服务器http server支持Gzip/deflate压缩,那么就使用http serer提供的功能,并到后台,全局-优化设置-服务器优化把“页面 Gzip 压缩”选项设定为否。
如果设定“是”,那么将使用DZ提供的一个gzip PHP插件来实现压缩页面。缺点是耗费PHP脚本执行时间,对于nginx+php-fpm模式运行更容易出现502错误。



版权曾经拥有,欢迎网上分享

论坛徽章:
0
2 [报告]
发表于 2012-01-13 10:51 |只看该作者
谢谢分享
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP