31 个回复 | 最后更新于 2015-10-12
2015-10-10   #20

回复#19 @小明 :

1、TopicsArray只有一个地方会用到,那就是View中,要调用直接写TopicsArray即可,因此只需要在一个地方声明。

封装和复用的话,我觉得已经做了很多,毕竟抽象不是只有OOP一种,普通的函数抽象也是很好用的,实际上我觉得你也很难写出比这更短的代码了。


顺便一提,解释型语言中OOP的代价非常巨大,特别是内存占用上,因此只有必须的地方我才抽象了几个类出来。

如果你来写CF,我估计页面下方显示的执行时间和内存占用,都得加个0。


2、大多数现今MVC架构(MVC framework)的开发框架(Framework),使用所谓的前端控制器(Front Control),每一次浏览器提出Request请求时,就会呼叫这个前端控制器,再由前端控制器来分辨,使用者想要执行哪一支程式。这样做,一点意义 都没有。

在浏览器层次,程式完全能知道使用者想要做什麽事情,例如使用者只是要读信,程式就不用再把需求送到伺服器,让伺服器判断使用者要读信还是送信。将这类决策工作拉出浏览器,由伺服器处理,就会浪费大量伺服器资源,来处理那些对使用者没有实际功用的工作。扩充性来自架构,很多开发框架,将所有事情绑在一起,限制了架构。选错开发框架,你就没有扩充性。(出自:Rasmus Lerdorf)



3、不妨你就我上面的例子,给出你的ORM抽象?

 $TopicsArray = $DB->query('SELECT `ID`, `Topic`, `Tags`, `UserID`, `UserName`, `LastName`, `LastTime`, `Replies`     
    FROM ' . $Prefix . 'topics force index(LastTime)     
    WHERE LastTime<=(SELECT LastTime     
        FROM ' . $Prefix . 'topics force index(LastTime)     
        WHERE IsDel=0     
        ORDER BY LastTime DESC     
        LIMIT ' . ($Page - 1) * $Config['TopicsPerPage'] . ',1)     and IsDel=0     
    ORDER BY LastTime DESC     
    LIMIT ' . $Config['TopicsPerPage']);


4、黑线部分我倒是我觉得我做得很好了。

2015-10-10   #21

如何改,这么改一下看看是否更清晰

<?php    
require(__DIR__ . '/common.php');    
require(__DIR__ . '/language/' . ForumLanguage . '/home.php');    
$Page = getPage($Config['NumTopics'], $Config['TopicsPerPage']);   //New Line
$TopicsArray = TopicsModel::getTopicsByPage($Page);//New Line
$PageTitle = $Page > 1 ? ' Page' . $Page . '-' : '';    
$PageTitle .= $Config['SiteName'];    
$PageMetaDesc = htmlspecialchars(mb_substr($Config['SiteDesc'], 0, 150, 'utf-8'));    
$ContentFile  = $TemplatePath . 'home.php';    
include($TemplatePath . 'layout.php');

提取一个getPage()的方法,用到分页的地方还多着呢,参数设置自己抽象

并不需要每次都copy代码吧

$Page      = intval(Request('Get', 'page'));    
$TotalPage = ceil($Config['NumTopics'] / $Config['TopicsPerPage']);    
if ($Page < 0 || $Page == 1) {    
    header('location: ' . $Config['WebsitePath'] . '/');    
    exit;    
}    
if ($Page > $TotalPage) {    
    header('location: ' . $Config['WebsitePath'] . '/page/' . $TotalPage);    
    exit;    
}    
if ($Page == 0)    
    $Page = 1;

这个封装成类还是啥其他的,不重要,自行处理。

index.php的逻辑里面还没有到关注这个过程的细节的程度。

再说了,基本的重用不考虑的话,那大家就呵呵吧

$TopicsArray = array();    
if ($MCache && $Page == 1) {    
    $TopicsArray = $MCache->get(MemCachePrefix . 'Homepage');    
}    
if (!$TopicsArray) {    
    if ($Page <= 10) {    
        $TopicsArray = $DB->query('SELECT `ID`, `Topic`, `Tags`, `UserID`, `UserName`, `LastName`, `LastTime`, `Replies`     
            FROM ' . $Prefix . 'topics force index(LastTime)     
            WHERE IsDel=0     
            ORDER BY LastTime DESC     
            LIMIT ' . ($Page - 1) * $Config['TopicsPerPage'] . ',' . $Config['TopicsPerPage']);    
        if ($MCache && $Page == 1) {    
            $MCache->set(MemCachePrefix . 'Homepage', $TopicsArray, 600);    
        }    
    } else {    
        $TopicsArray = $DB->query('SELECT `ID`, `Topic`, `Tags`, `UserID`, `UserName`, `LastName`, `LastTime`, `Replies`     
            FROM ' . $Prefix . 'topics force index(LastTime)     
            WHERE LastTime<=(SELECT LastTime     
                    FROM ' . $Prefix . 'topics force index(LastTime)     
                    WHERE IsDel=0     
                    ORDER BY LastTime DESC     
                    LIMIT ' . ($Page - 1) * $Config['TopicsPerPage'] . ',1)     
                and IsDel=0     
            ORDER BY LastTime DESC     
            LIMIT ' . $Config['TopicsPerPage']);    
    }    
}    
$DB->CloseConnection();


2015-10-10   #22

回复#20 @lincanbin :

1、对此我只想对你说,你还只停留在coding的层面

我想问你,你怎么针对你的这个index.php的取TopicsArray做测试

每次都要去访问index.php来做吗?



如果你来写CF,我估计页面下方显示的执行时间和内存占用,都得加个0。

不要总是用自己的主观意识来说事。

Processed in 2.378 ms, 2 SQL Queries, 230.79 KB Memory Usage

自己安装一个debug工具看看你统计的时间是否准确

如此简单一个回帖页面,耗费230.79kb的内存,好意思跟我扯优化


2、通过命名规则和文件包含的思路来做contorller分发,这个确实可行

通过类包含及调用来做,也是办法,这个没必要争


3、呵呵

4、那真的只是你自己的以为

2015-10-10   #23

回复#21 @小明 :

关于分页的抽象你有些想当然了,有2个变量是必须声明的,因为它在其他地方会使用到。

302的跳转虽然非必需,但是也需要传入一个分页的URL模板。

那12行最后各种传值和取回数据再赋值。

保证可读性不差于原来的情况,就是类似于https://www.94cb.com/t/3194#Post10275那样。

如果考虑最少行数,那么也要6行,各种类初始化和传值、取回赋值。

实际上并不划算。


最后再问问你对于

 $TopicsArray = $DB->query('SELECT `ID`, `Topic`, `Tags`, `UserID`, `UserName`, `LastName`, `LastTime`, `Replies`     
    FROM ' . $Prefix . 'topics force index(LastTime)     
    WHERE LastTime<=(SELECT LastTime     
        FROM ' . $Prefix . 'topics force index(LastTime)     
        WHERE IsDel=0     
        ORDER BY LastTime DESC     
        LIMIT ' . ($Page - 1) * $Config['TopicsPerPage'] . ',1)     and IsDel=0     
    ORDER BY LastTime DESC     
    LIMIT ' . $Config['TopicsPerPage']);

的ORM抽象的看法?

2015-10-10   #24

回复#22 @小明 :

数据来自PHP解释器上返回的memory_get_usage()函数,第三方Debug工具会比PHP解释器本身更加准确?

你只要在你以前做过的项目程序结尾打印memory_get_usage()就知道了。


然后看得出你真的没有什么PHP开发经验,根本不知道230.79 KB的内存占用对于PHP意味着什么。

你只要来几个OOP,就要远远超过这个内存占用了,这点你可以在自己的项目中测试。

2015-10-10   #25

回复#23 @lincanbin :


拿php自己来测自己本身就没意义,一个请求过来,消耗内存的并非php自身。


如果你非要拿php自己来测自己的话,请用memory_get_peak_usage看你的峰值内存消耗,在脚本结尾放一个memory_get_usage()所得到的东西并不是我们想要的东西,另外也请加上参数true


到这里我就不争了,已然没有意义了。

1、orm不是我所提到的东西,我也没有表达任何意见,让我写,我也没那个精力和时间

2、那个page的抽象(既然是抽象,那两个参数当然是传值进去)你觉得没有意义,你后续是想每个地方都那个copy一遍代码吗

3、302的含义是什么,异常就是异常,错误就是错误,302本质被设计出来不是干这个的

4、你写的东西,根本就没有考虑过封层、封装以及测试

5、最后一句

然后看得出你真的没有什么PHP开发经验,根本不知道230.79 KB的内存占用对于PHP意味着什么

呵呵。,那你给我说说意味着什么。

2015-10-10   #26

回复#25 @小明 :

1、那你前面说的不能拼SQL是指?

2、如果抽象了分页,那么实际上在需要分页的地方,还是要copy代码来实例化类、给对象传值、取回数据再赋值。

3、使用302是符合HTTP协议的Status Code的语义的,这种情况下使用是正确的选择,很多人一辈子只知道200和404,那么其他HTTP Status Code设计出来是干嘛用的?

4、5、不妨展示你的代码以及你的项目的内存占用数据?

2015-10-10   #27

回复#26 @lincanbin :

1、指的是,直接操作db属于最基础的东西,如果考虑一下维护的话,出现在这里不合适,没有封装的话,各种测试、及代码保护不好做,假设,手抖一下,多了一个什么不可见的字符,我可以很快速的排除不是拼SQL啊、cache的问题,如果按照你这个过程来写的话,整个文件都得测一遍。

说拼sql,我只是举栗子说你代码面条在哪里,我本来想说一个log都没有的,但我知道大部分phper都没有打log的习惯,就没举这个例子

2、唉,我真心无语了。那肯定是抽象的不对啊,别让我展示代码了,看看国外写的好点的代码吧,有取page的例子,不必每次都copy一堆的代码。

3、我知道你没明白我意思,http协议里面30*基本都代表着某个URL发生了转移,你url发生转移了吗?哪里只是用户访问了一个不存在的分页,对吧,该记日志做现场分析,该爆异常爆异常,异常可以友好点,然后给提示了,你弄了一个302干嘛,你要是给我说为了用户体验的话,也是给提示,然后做页面跳转吧。这里我这么说你可能还不理解,但是你记住我说的“异常就是异常,错误就是错误,302本质被设计出来不是干这个的”


4、第三方工具啊,如果你非要拿php自己来测自己的话,请用memory_get_peak_usage看你的峰值内存消耗,在脚本结尾放一个memory_get_usage()所得到的东西并不是我们想要的东西,另外也请加上参数true

2015-10-10   #28

回复#27 @小明 :

关于HTTP协议的Status Code的问题,实际上也与SEO的问题。

https://www.94cb.com/page/2000

例如说有这么一个页面,2000页,实际上不存在的,如果你爆了一个异常,按照语义返回了50X。

那么就可以利用这个来降低你的网站的搜索引擎排名,具体操作方法就是制造这种几千页几千页大页码的外链,搜索引擎会将这些URL标记为不存在不再抓取,那么当你的页数真的达到了2000页的时候,搜索引擎也不会抓取——因为之前已经标记为不存在了。

if ($TopicsArray) {
    //Do something
} else {
    AlertMsg('404 Not Found', '404 Not Found', 404);
}

顺便一提,你可以自己实际测试一番,PHP抛出一个异常的CPU Time和Memory Usage代价是非常高昂的。

在这种情况下通过阈值判断来避免异常显然更加划算。

2015-10-11   #29

回复#28 @lincanbin :

小明说的对,对标准理解真的很到位,作者是没有理解小明的话啊

50x是服务器内部错误,也不是这么用的

异常是程序层面的东西


小明是做什么,很好奇啊,没有一点水平,对协议和分层封装和测试理解应该没有这么深刻,求带啊

2015-10-11   #30

回复#29 @超级小白菜 :

程序抛出一个异常的同时,按照语义应该同时在HTTP Header中标识此页面为错误页面,防止Spider错误抓取影响权重,同时在API设计中不同的Status Code也可以在更下层对一些异常进行统一的处理。

很多人不这样做,不代表不应该这样做。


代码风格也见仁见智,下面这种代码风格在我看来也是相当清晰的呢:

https://github.com/gcc-mirror/gcc/blob/master/gcc/c/c-parser.c

https://github.com/php/php-src/blob/master/main/main.c


然后是解释型语言中的高度解耦跟性能是一对矛盾,不服可以自测。

代码风格也是权衡的结果,用Laravel直接写,拿着《设计模式》的教科书各种套,可能就非常对楼主风格了,可是资源消耗还真的得加个0,这点可以参考各种Laravel写出来的程序。

2015-10-12   #31

回复#29 @超级小白菜 :

小明是一个霸占广大70后、80后、90后、00后、10后小学语文、数学课本, 乃至习题长达四五十年之久的人物,和小红、小刚并称“黄金不败铁三角”。

登录后方可回帖

登 录
信息栏

Carbon Forum是一个基于话题的高性能轻型PHP论坛

下载地址:Carbon Forum v5.9.0
QQ群:12607708(QQ我不常上)

donate

手机支付宝扫描上方二维码可向本项目捐款

粤公网安备 44030602003677号
粤ICP备17135490号

Loading...