Skip to Content

完善ecmall的速度

因为现在想一步步自己运营商城,但发现自己缺好多条件,但我想其它人也一样,肯定有缺这缺那的,那就让我们组织起来一起奋斗。
我对程序比较擅长,就让我在完善程序的过程中结识更多的朋友,让我们一起努力。很简单,你有一技之长就来,到时我共享(低价有偿、无偿)代码,你共享特长。
好,进入今天的正题,关于ecmall2的速度篇,ecmall2的代码真的让我想不只一次的赞美,让我一个新手可以学习到这么好的代码,真是万分感谢。
真天就来讲讲缓存类,在ecmall中的缓存类有两个子类实现,分别是基于文件的以及基于分布式缓存memecached的实现,后者是使用内存的缓存,理应比文件更快,现在我们就来打开这项ecmall2已经准备好的功能。
打开的前提条件是你的服务器上装有memcached以为memcache的php扩展,我假设这些你都有了,我们直接修改ecmall的几个配置点。
打开data/config.inc.php文件,找到里面的CACHE_SERVER这一项,改成这样,'CACHE_SERVER' => 'memcached',就表示启用memcached来缓存,然后再指明memcached的服务器和端口即可。分别添加 ('MEMCACHE_HOST' => '192.168.1.47','MEMCACHE_PORT' => '11211',)(不包括括号)来指明服务器ip和端口,因为我本机使用linux,已经安装上述条件,所以可以快速启用。启用前你要选测试能不能连 接,启用后可以先清空temp目录下面的cache目录,然后再访问一下网站,如果这里面不再生成文件,那就证明启用成功。
好,缓存基本到这里,下一个改进还是速度。
next target 让ecmall2生成全站静态。

 

缓存模板--总感觉ecmall2有时慢的进

本来是打算全站静态的,但是考虑到商城的特殊原因,并不需要把某一篇文件放在那里很久。所以转而缓存模板文件,以达到加快ecmall2速度的目的。
这篇比上一篇更加实用,因为如果是缓存模板文件的话,那就算不使用内存来缓存从数据库读取的数据也没关系,因为最后会把模板文件连同数据一起缓存进一个文 件,那后面读取时就只读取这个文件而不用再去缓存数据库,但与静态化有点不同,这个文件里面还有一点php信息,并不能用来直接输出,模板引擎会在去掉这 点php信息后输出。
我在使用ecmall2时也觉得有时反应不过来,相比来讲ecshop还快,经过观察,其实ecshop在display时是加了一个id的,就是用来缓 存这次输出的。而我们现在要做的就是在ecmall2里面实现缓存模板输出,通俗点讲就是在$this->display()时给一个id这个id 要唯一。
其实所有的东西ecmall2已经准备好了,只是不知道为什么没有使用,详细的原理不再介绍修改完后就可以使你的商城在运行方面的速度上一层楼,但是网络方面可不包哦。

我们以商品详细页为例
1、修改app/goods.app.php的index方法的最后一行成这样{$this->display('goods.index.html','goods_detail_'.$id);}(不包括大括号,以下不再提示)。
2、app/frontend.base.php文件里面的class StorebaseApp extends FrontendApp类的function _config_view()方法里的最后添加如下代码{$this->_view->cache_dir  = ROOT_PATH . "/temp/html_cache/store/{$template_name}";}这里设置缓存的目录。
3、再找到app/frontend.base.php的class FrontendApp extends ECBaseApp类的function display($tpl)方法的方法名改成这样{function display($tpl,$cache_id="")}接着把方法里面的parent::display($tpl);改成 {parent::display($tpl,$cache_id);}。
4、找到includes/ecapp.base.php里的function display($f)方法的方法名改成{function display($f,$cache_id="")},以及里面的parent::display($f);改成 {parent::display($f,$cache_id);}。
5、eccore/controller/app.base.php里面的function display($n)方法改成{function display($n,$cache_id='')},以及里面的$this->_view->display($n);改{$this-& gt;_view->display($n,$cache_id);}。

再修改eccore/view/template.php的function fetch($filename, $cache_id = '')方法如下。

     function fetch($filename, $cache_id = '')
    {
        if (!$this->_seterror)
        {
            error_reporting(E_ALL ^ E_NOTICE);
        }
        $this->_seterror++;

        if (strncmp($filename,'str:', 4) == 0)
        {
            $out = $this->_eval($this->fetch_str(substr($filename, 4)));
        }
        else
        {
            if ($this->_checkfile)
            {
                if (!is_file($filename))
                {
                    $filename = $this->template_dir . '/' . $filename;
                }
            }
            else
            {
                $filename = $this->template_dir . '/' . $filename;
            }

            if ($this->direct_output)
            {
                $this->_current_file = $filename;
                $out = $this->_eval($this->fetch_str(file_get_contents($filename)));
            }
            else
            {

                if ($this->is_cached($filename,$cache_id)&&$cache_id && $this->caching)
                {
                    $out = $this->template_out;
                }
                else
                {
                    if (!in_array($filename, $this->template))
                    {
                        $this->template[] = $filename;
                    }

                    $out = $this->make_compiled($filename);

                    if ($cache_id)
                    {
                        if ($this->appoint_cache_id)
                        {
                            $cachename = $cache_id;
                        }
                        else
                        {
                            $cachename = basename($filename, strrchr($filename, '.')) . '_' . $cache_id;
                        }
                        $data = serialize(array('template' => $this->template, 'expires' => $this->_nowtime + $this->cache_lifetime, 'maketime' => $this->_nowtime));
                        $out = str_replace("\r", '', $out);

                        while (strpos($out, "\n\n") !== false)
                        {
                            $out = str_replace("\n\n", "\n", $out);
                        }

                            if (!file_exists($this->cache_dir))
                                    {
                                        ecm_mkdir($this->cache_dir);
                                    }

                        if (file_put_contents($this->cache_dir . '/' . $cachename . '.php', '<?php exit;?>' . $data . $out, LOCK_EX) === false)
                        {
                            trigger_error('can\'t write:' . $this->cache_dir . '/' . $cachename . '.php');
                        }
                        $this->template = array();
                    }
                }
            }
        }

        $this->_seterror--;
        if (!$this->_seterror)
        {
            error_reporting($this->_errorlevel);
        }

        return $out; // 返回html数据
    }

怎么样确定成功没有呢?你打开一个商品详细页面,多刷新几次,如果下面的执行时间不变就表示成功。

其实用这个方法,你甚至可以给商城的商品分类、店铺的商品分类都缓存起来,条件是你要给$this->display()方法一个能确定唯一的id。

现在的问题:
这些修改后好像是不会在固定时间后自动更新的缓存的,你可以去temp/html_cache/下面删除所有的东西,就会重新生成缓存了。

另外,我会继续研究,会有一个比较完善的生成静态的方案,但是应该是收费的(如果有资源的朋友可以过来互换啊,或者能成为核心交流人员的可以免费提供),但基本都是基于这些代码了。

[php]