Patrick's profileService Temporary Unavai...PhotosBlogListsMore Tools Help

Blog


    15 February

    扩展phplib的模板功能,增加模板的条件判断能力

    最近几月使用phplib,觉得功能很强大,语法也很简洁,也用它做出了不少模块,可是就是感觉没有模板内置条件判断而不得不在程序逻辑中实现需要的功能而感觉很不爽。经过数日的查阅资料和研究代码,终于成功扩展了phplib的Template类使之支持条件判断选择,代码如下:

        function set_if($parent, $varname, $value = true, $outputname="") {
            /*
                PHPLib set_if Extention by Platinas
            */

            if ($this->debug & 4) {
                echo "<p><b>set_if:</b> parent = $parent, varname = $varname, name = $name</p>\n";
            }
            if (!$this->loadfile($parent)) {
                $this->halt("set_if: unable to load $parent.");
                return false;
            }
            if ($outputname == "") {
                $outputname = $parent;
            }

            $str = $this->get_var($parent);
            $reg = "/[ \t]*<!--\s+IF $varname\s+-->\s*?\n?(\s*.*?\n?)\s*(<!--\s+ELSE $varname\s+-->\s*?\n?(\s*.*?\n?)\s*)?<!--\s+ENDIF $varname\s+-->\s*?\n?/sm";

            if($value){
                $str = preg_replace($reg, "\\1", $str);
            }else{
                $str = preg_replace($reg, "\\3", $str);
            }
            $this->set_var($outputname,$str);
            return true;
        }

     效果怎样呢,举个简单的例子看看下面这个Sample:

    模板文件:test.html

    <!-- IF isuser -->
    Hello user!
    <!-- ENDIF isuser -->

    <!-- IF isuser -->

        Hello user again!
        <!-- IF isvip -->
        Hello vip user!
        <!-- ELSE isvip -->
        You are not vip!
        <!-- ENDIF isvip -->
    <!-- ELSE isuser -->

        Please Login!
    <!-- ENDIF isuser -->

    PHP文件:

    $t=new Template();
    $t->set_file("testfile","test.html");
    $t->set_if( "testfile","isuser",true);
    $t->set_if("testfile","isvip",true);

    这样输出为:
    Hello user! Hello user again! Hello vip user!
    如果把第二个改成false,输出:
    Hello user! Hello user again! You are not vip!
    如果把第一个改成false,输出
    Please Login!

    这样看来以后又可以省很多事了。

    这东西不但支持嵌套,还支持循环,例如表格不同行通过这个Block而达到每行显示不同颜色的效果,写法要复杂一点,不过确实很不错。

    10 March

    乱码战斗笔记

    开发中文系统最大的问题是什么? 可能乱码要算上一个,这次我就差点被乱七八糟的编码弄疯了,白白浪费了几天功夫。

    首先是数据库,最早测试过程中遇到了个这样的问题:Mysql报错,内容荒谬到难以想象,原话记不清了,大概是:Mysql Error: INSERT INTO `table`(`col1`,....) VALUES ('一二三四五六七'....) . Value too long for Column `col1`。而这种情况是绝对不可能发生的因为我还不至于会把col1的长度设置得这么短,然后我把它报错的那句SQL原话拷贝到phpmyadmin,屏幕一闪,顺利通过!我靠,手工拷就行,程序自己执行就不行?  网上查阅了很多资料未果,然后我在看数据库的时候翻阅到数据库编码,灵光一闪,难道是编码问题?

     因为我的数据源是网上获取的,手工查看了数据源,看到数据开头赫然写着“encoding=utf-8”,而我的数据库是gb2312。 这下有着落了,在每个数据进入数据库前用php重新编码,把uft-8转换成gb2312的,再执行,通过!这样才知道,windows的剪贴板欺骗了我们很多事情,比如编码。

    过了一会儿问题又来了,我用UltraEdit写的,会出现这样的情况:刚开始还是正常的,改了几行无关的代码后,再去刷新页面测试,居然就成了乱码,而且ctrl-z撤销回来也没用,无论怎么刷出来都是乱码了,只能打开原来的备份再把修改内容拷进去再存档。而且即使这样也不能保证过一会没有乱码产生。鉴于乱码产生过程过于随机并且不可逆转,严重影响了我的效率,因此我放下了手头的来钻研这个问题。

    通过打开多种文件反复操作比较,最后找到的解决办法是:所有文件打开-另存为-选择统一的编码-覆盖自己。这样操作以后,随机乱码现象终于得到了缓解,至少最近没有出现过了。考虑到我一直使用UltraEdit,估计这样的原因是我在不同机器上使用的编辑器的默认编码不一样,这样即使打开来看没什么区别,不过内部编码是完全不同的,当他们在某种情况下需要互相引用的时候,相互之间就会出现语言不通的情况,从而反映出来就是乱码。

    后来还出现了个更荒谬的问题:某网页甲,有一些内容,自己打开的时候没问题,某网页乙,包含一个框架,打开也没问题,然后,用乙包含甲,出现情况是乙的部分显示正常,甲的部分全是乱码。

    由于有上次经验,右键查看网页编码,发现网页是GB2312的,强制换成UTF-8,OK,甲的内容显示正常,乙的部分变成了乱码。荒谬不?不能再荒谬。不过问题的原因找到了。

    因为我的数据源来自网上,再次比对了数据解析程序和数据源,得出结论是数据源是主要utf-8的,数据解析程序为了确保兼容性,自己先解析了数据的编码并且把不是utf-8的转换成utf-8,再送给xml_parser_create()函数解析,于是修改,你要强制转utf我就偏不让你转,给它改成强制转为gb2312再送解析,这下应该好了吧?刷新我靠怎么一个内容都没了?连乱码都一起消失了。查看代码很久以后不解,网上找有人说xml_parser_create()对gb2312支持不好,没办法改回来。

    既然数据被处理之前不能动,前台又需要换编码,那就只能在两个交界处动脑筋了。在数据的内容被解析完毕进一步处理之前,用一个叠代把数据的所有内容转换编码,,这样虽然增加了很多计算量,不过问题终于解决了。叠代函数代码是这样的:

    function convert_encoding($var,$enc){
    if(is_array($var)){
    foreach($var AS $vk => $vv){
    $var[$vk]=$this->convert_encoding($vv,$enc);
    }
    return $var;
    }
    return iconv($this->encoding, $enc, $var);
    }

    至此...乱码问题终于告一个段落,结论是因为有人喜欢utf有人喜欢gbk,所以数据源来源不定的时候,一定要小心编码阿。