分类目录归档:点滴笔录

2010年个人总结

又是一年年终,感叹时间的飞逝。

该有个总结,其实很少下笔,这很不该,下来务必好好加强。

2010年,总体不给力,接触面是多,却蜻蜓点水居多。心态还不够稳重,急,抱怨……

2011年的计划:

  • 一个团队
  • 一次旅行
  • 学习英语
  • 加强技术:PHP,JAVA
  • 集中精力:放好心态,加强执行力,循序渐进。
  • 阅读写作:每个星期至少2篇Blog。

告别2010,给力2011年,在明年的今日,展示力量的时候~

祝愿朋友们新的一年健康,快乐,进步!

浅谈ECSHOP

许多人应该ecshop并不陌生,它粉丝不少。它对我php的入门学习帮助不少,在此非常感谢它的开源(http://www.ecshop.com)!

总的来说,它的架构清晰,易扩展,可以适合二次开放大型应用的雏形。但它细节的东西还比较粗糙,逻辑任务分解不到位(有些代码块太长,冗余多),稳定性欠佳。我这也是很笼统的说它缺点,它的程序对于入门不久phper也是很容易阅读。本人文笔不够,建议去看它,就知道其中缺点,更能学到许多有用的东西。到时欢迎讨论。也是希望可以帮助改进ecshop,支持开源!

下来就说点ecshop的问题,挑个它模板机制吧,它是模板机制核心在includes/cls_template.php,是改写smarty模板引擎的。改得不错,很方便,Just for it。它里面的诸多细节还需要改进。

它有个动态库文件,就是可以后台添加,删除在前台某个区域显示的内容。如添加广告显示,某类的产品等呀。所以,它不是实时显示内容(不进行缓存)。

这个处理它在cls_template.php中template类的smarty_prefilter_preCompile()方法,在这方法中,对动态库文件的处理,仅仅是加入smarty标签,如{assign var=”” value=”” },然后,比如首页index.php, 写起控制程序的时候,又写了并调用了assign_dynamic()函数,里面不干什么,也是注册动态库的smarty变量。这里虽然通过一个“桥”,来实现对相同的smarty的变量赋值不同的值(如{assign var=”cat_goods”  value=”cat_goods_’. $id .'”}(smarty_prefilter_preCompile()方法实现), $smarty->assign(‘cat_goods_’.$id, $cat_goods) [assign_dynamic()函数实现]),觉得这不错–对动态添加或删除某个显示内容,但是,smarty_prefilter_preCompile()的复杂且多的正则开销,每个方法或函数连接数据库的开销,smarty变量命名的不稳定性(如果方法和函数中某个变量写的不一致,就不能对应赋值啦),这些开销省下来,是多么的可观啊!呼呼~,可以省去assign_dynamic()函数,在preg_replace_callback()中的调用函数,在进行匹配处理的时候,就进行相应的赋值。

还有,smarty_prefilter_preCompile()对动态库文件那么辛苦的工作,就是为了在对应的include的动态库文件前,加入对应{assign var=” value=”}。既然在后台处理模版布局的时候,ecshop对添加的动态文件会在对应的模板,即是对应的.dwt文件里添加<!– #BeginLibraryItem “*.lbi” –>,何不添加一个标识(唯一),在smarty_prefilter_preCompile用str_replace()替换,不轻松许多吗?!

不过,这样也一个弊端,就是对模板可视化编辑的时候,添加的动态库文件不能按原来的规则(即<!– #BgeinLibraryItem ”*.lib” –>, Dreamweaver的模板文件)显示出来。

如果不用标识替换,即保持原来处理方法。在smarty_prefilter_preCompile()方法中,觉得不需要用正则来{include file=”动态库文件”}来前面加上{assign var=”” value=””},而且还要整个$GLOBALS[‘libs’]来协助。稳定性可想而知了。何不用explode敲入数组处理(处理匹配的第一个就可以,这样说很多人不清楚,它的动态库文件存储在数组中,在某个区域内,相同类型的包含的动态文件是相同的,所以在前面{assign}来赋不同的值。在遍历该动态库文件,遇到匹配字符,立即处理便可。)。用处理处理效率高很多,也减少许多不稳定行因素。

再稍稍说下category.php页,有些once write的感觉,很容易看到在相同的应用下调用get_extension_goods()函数许多次,而get_extension_goods()每次都需要和数据库“握握手”。太过奢侈啦!里面可以改进许多,有兴趣者欢迎Email探讨~

以上也是个人看法,自己能力还不够强,还很有待指点。BTW,shopex比ecshop完善许多,可惜不开源。希望ecshop越来越高级,支持开源!

附上改过后的code: ecshop_20101226.zip

无人喝彩

无人喝彩的人生,就似没有花香的小径。

人生的赛场常常是这样开始的:两旁是朋友助威的呐喊,身后有亲人关注的目光。我们太多数人的生命是在这亲朋们的赞美与喝彩中长成的,那是我们成长过程中快乐的源泉。

但是,我们要前行,就要有一天会远离朋友的呐喊的范围和亲人关注的视野。当生命孑然独行于荒野,可经受的孤独和痛苦的煎熬?

甚至,在你蹒跚的身影之后还有无数的诽谤和嘲讽,你是否仍能默然坚守?沙滩能让汹涌澎湃的海浪心平气静的退去,并且留下些珍贵的贝壳,是因其胸襟的坦然与博大。

那些只是习惯与繁花锦簇的春天的生命,如何度过群芳凋零的冬天?那些被众星捧月般拥戴和欢呼的人们不经受孤独和冷漠,如何蓄积一种于困境中自信从容的人生大气?

孤独与痛苦验证着生命的弹性,让人更真切地感受到生命的硬度和精神的韧性。我们生命的最大值正是这种承受和忍耐中求得的,而不是以他人的喝彩为砝码来度量的。

喝彩本是人们对那些闪烁真善美光辉的人和事的真诚赞颂,是人们内心对人性的亮点情不自禁的共鸣的反应。由衷的喝彩,对于自卑和脆弱的人,确是一根能去支撑其前行的手杖。但在这个浮世时态,许多喝彩成了随意的问候或礼节性的安慰,甚至不乏谄媚的精神贿赂。正如太多的泡沫只会令人窒息而不能将其抬升一样。廉价的掌声和无端的喝彩总是让人陶醉其中的人们,放慢了快行的脚步。

其实,对于我们这些很平凡的生命,能否赢得别人的喝彩并不重要,只要在自己生存和生活的环境里,大部分人能容纳你,接受你;小部分人能善待你,喜欢你;有那么几个能牵挂你,真爱你,便是幸福的人生了。

而那些一心埋头走路的人,纵会忽略沿途许多美丽的风景。却能明晓自己的每一步迈与何处,跋涉之途是否花香满径,他们是不会在意的。对于这些真正值得喝彩的人,喝彩于他们,反倒成了煞风景的惊扰。

无人喝彩,依然昂扬向前;没有掌声,一样虔诚歌唱~

设计模式

我们在写程序中遇到许多问题,会发现一些的解决方法很是类似。其实,这些解决方法原理,也是许多programer广泛重复使用的方法。这就涉及到设计模式 — 用来描述在程序设计中解决特定问题的一种可重复的方法。

但是,如果过度使用,为了增加设计的灵活性和架构的适应性,以便应对可能永远不会出现的未来需求,导致应用的实现被该用哪些设计模式比较恰当等这些因素所阻碍,这就是所谓的“分析瘫痪”状态。

所以,设计模式只在一些特定的情形中才是有用的。

有个小小体会,程序的“职责分离”,尽量创建小的,易读的,易修改的代码块,用来解决特定的问题。

真谛

真谛难寻。开花只是预言,预言是软弱的;结果只能反馈,反馈是迷乱的。也许唯有凋谢和跌落才生的生动而惊心地反证什么,可这时粗心的人们却不会特别去留意,更很少自觉的参悟。

真谛从你眼前滑过,而你睁着眼却在困惑。

有时你无意中开始优雅的只有自己一个读者的诗行里设计真谛,梦想的翅膀把真谛倾诉成浪漫的平平仄仄,缥缈的意象把真谛摇曳成更难意会的隐隐约约。你的心情很好,你很满意自己的灵气,只是从此春天别来春寒,秋天别来秋风,上路别跌倒,抬头别撞墙,你害怕惊扰那温暖的脆弱的梦。

然而,只有风风雨雨起起落落,才会撞击自设的欺骗,才会清醒自入的梦乡,恰恰在这时真谛就在痛苦中起舞,你能看明白,但更需你咬着牙爬起来去捕捉。真谛,原来是你经历中最黯淡的时候转瞬即逝的一抹光亮。

真谛就在你奔走的脚下,而你一旦脚步悬在了空中,就是真谛深情的望着你,你也不会理会它。有时你甚至更迷恋名人的演义和演义中无意甩出的话语,因为他们的钥匙已经打开迷宫的门,他们的步履已证明了一种逻辑,于是你想把握住那万能的真谛。诚然,精彩的故事本身就清晰出一种秘诀,但与此同时这种秘诀又模糊出一种美丽的光环,天真的人们沉醉于此,又模糊于此,殊不知名人的“芝麻开门”咒语,只是他的秘密武器,于你只能欣赏而不能操作。名人的成功只是他做出的解,其实还有万千方程在冥冥中等候着你。别人的真谛也许会把你导入糟糕的误区,因为一旦某种真谛已显示出魅力,那么随着这种魅力到达顶峰,这种真谛便逐渐作废。

一种选择只有一种真谛,唯一的你要做唯一的寻找,你耐着性子独步吧,真谛就在远处放歌,此时你不已寻找到了那歌声的去向?

真谛难寻,常常是因为有时错把预言当成结论,真谛提前被假象蒙住了。还因为有时错把收获当成成熟,真谛被浅薄的陶醉给吓跑了;甚至还因为有时错把失去当成得到,扭曲的真谛给你一个空虚的满足。

急不得,懒不得,看好了,稳着些,白天上路,夜里琢磨,闯出一重天,蓦然回首,真谛原来就是你的脚窝。

国庆假期

很快,十一假期已结束~

假期,依然是回家。家乡变化不是太大,但空气很好,特别喜欢晚上的寂静。

这些天来,亲朋好友间走走,大半在家和两老唠叨,莫名有着幸福,责任……

很平淡的过完了假期,今天已是返回远离家乡的工作的城市,也觉得,下来的路更要踏实~

数列

还是记下来,方便使用:

1 等差数列
1)公差d:d = an-an-1
2)通项公式:an = a1 + (n-1) d = S1 = Sn – Sn-1 (n >= 2)
3)等差中项:A = (a+b) / 2
4)前n项和:
Sn = n(a1 + an) / 2 = na1 + n(n-1) * d / 2
5)a1 + an = a2 + an-1 = ….

2 等比数列
1)公比q: q = an / an-1
2)通项公式:an = a1qn-1
3)等比中项:b2 = ac
4)前n项和:Sn = a1(1-qn) / (1-q) (q != 1)
5)a1an = a2an-1 = …..

动态级联下拉框

今天需要遇到添加商品的某一类型的时候,原来的类型只有一个下拉框,虽然下拉框有层次缩进,但太长了,很不好使用,于是,想有这么一个处理:

1)首先生成根类的下拉框
2)选择某一个父类的时候,随后生成一个其子类的下拉框,如果有子类的子类(即孙子),不列出它们。
3)以此类推

完成以上功能的话,非JavaScript莫属了。

这里有一个难点,如果处理好只能生成当前父类的子类(如果存在的话),而且不能重复生成子类的下拉框(select)。变化到同级中的另一个父类的时候,之前父类的子类(还有由点击子类生成的其子类(即孙子类)的下拉框,再类推以下几级),都要消失,而是生成当前指向的父类的子类。

说得乱七八糟的吧。其实,也简单,我们要处理的是,当前某层类位置以后东东,我们需要一个东西记录这些东东,以便选择同层中另一个类时候的删除它们,插进该类的子类。

以上也只是自己想得处理这问题的一个方法,当前能力还非常有待提高,所以很期待高人指点。下边贴出代码,JavaScript好些东西是用于致学(即是用的时候,查看了下参考手册,很多东西没了解,用的比较生硬),还有,以下只支持IE,非常郁闷!其它浏览器不支持Event对象的srcElement属性哦!

类别的XML文档category.xml

HTML DOM:

处理xml并生成category的select菜单的JavaScript:xml_category.js

/**
 * @param   xml_name     xml文档的路径
 * @param   target_id      html的DOM的ID
 */
function xml_category(xml_name, target_id)
{
  var self = this;             // 私有变量,指向对象本身,在JS“类”的封装和访问机制,理解还有待加强。
  
   this.xmlDoc       = loadXMLDoc(xml_name)        // loadXMLDoc函数见/?p=302
   this.targetID     = document.getElementByID(target_id);
   this.catTree      = new Array();                       // 记录select的情况

   /**
    *  产生select下拉框
    */
   this.createSelect = function(parent_id)
   {
      var xmlDoc = self.xmlDoc;
      var cat, cat_num;

      // 以下为了都兼容各浏览器,不使用用与IE的XML DOM的selectNodes() 方法用一个 XPath(//cat[pid=*])[*表传来对应的parent_id] 查询选择节点.其它浏览器可参考Document.evaluate()。
      cat = xmlDoc.getElementByTagName("cat");
      cat_num = parseInt(cat.length);
     
      if (cat_num > 0) // 类别存在
      {
         var slt;
         var is_set = false;                                            // 为标志该层是否有类别,即有option选项
         slt = document.createElement("SELECT")              // 创建一个select元素节点
         slt.onchange = self.createChildSelect;                 // onchange事件

         // 每次都是整树遍历啊! !--
         for (var i=0, j=0; i < cat_num; i++)
         {
            // 同层的类别
            if (parseInt(cat[i].getAttribute("pid")) === parseInt(parent_id))
            {
               // option选项
               slt.optons[j] = new Option(cat[i].childNodes[0].nodeValue, cat[i].getAttribute("id"));
               is_set = true;
               j++; 
            }
         }

         // 有选项值
         if (is_set)
         {
             self.catTree.push(slt);          // 记录这个select下拉框
             self.targetID.appendChild(slt);
         }
         else
         {
            slt = null;
         }

      }
   }

   /** 
    * 生成子类
    */
  this.createChildSelect = function()
  {
       var slt_len = self.catTree.length;
       
       if (slt_len > 0)
       {
            var s = 0;                     // 标记当前触发option在catTree的位置(如果存在的情况)

            // 很不顺眼的遍历
            for (var i=0; i < slt_len; i++)
            { 
                // srcElement是IE的属性。 !--
                if (self.catTree[i] == event.srcElement)
                {
                    s = i ; break;
                }
            }

            // 删除该层位置以后所有的东东
            for (var i= slt_len - 1; i > s; i--)
            {
                 self.targetID.removeChild(self.catTree[i]);
                 seft.catTree.pop();
             }

            self.createSelect(event.srcElement.value);
       }

  }

}

下来在之前HTML文档位于id=”cat”写下如下JS,便可实现了:

var xml = xml_category("xml_category.xml", "cat")
xml.createSelect(0);

以上处理,还非常欠缺灵活性,就是初始化这个select下拉框的时候,如果输入的parent_id不是根类的ID,而是子类,或以下几层的子类的ID的时候,不能生成相应的select下拉框。

到此,写下这点记录,希望高人指点,也继续更进~

UTF-8的BOM

在window下面用记事本编辑文件的时候,如果保存为UNICODE或UTF-8,分别会在文件的开头加上两个字节“\xFF\xFE”(UNICODE)和三个字节“\xEF\xBB\xBF”(UTF-8)。在读取的时候就可能会遇到问题,但是不同的环境对这几个多于字符的处理也不一样。

Unicode规范中有一个BOM的概念。全名Byte Order Mark(字节序标记)。

BOM告诉编辑器当前文件采用何种编码,方便编辑器识别(如果接收者收到以EF BB BF开头的字节流,就知道这是UTF-8编码了),也为了支援UTF-16,UTF-32才加上。

 在开发中,如果不涉及太多区域的应用,BOM作用不是很大,在php设计时没有考虑BOM的问题,这三个字节会直接输出,如果这时在程序里调用了session函数,就会出问题了。所以一般情况下,文件应该使用 Unicode (UTF-8) 编码保存。同时不要使用字节序标记(BOM)。所以,生成文件时,过滤“\xEF\xBB\xBF”即可。