NuttyCoder's profile初级程序员BlogLists Tools Help

Blog


    3/26/2007

    [Nova@PHP]模版编译程序设计

    模版编译程序设计
    总体结构
    1,获取必要信息
    2,编译
    3,输出文件/缓存
    变量设计
    系统配置变量
    DATACACHE = 0 是否缓存数据项,默认为零,全部数据项重新读取.
    编译过程变量
    CacheSetup 缓存设置
    Cached data elements set(CDES[]) 缓存的数据项集,适用于CacheSetup=1
    Non-cached data elements set(NCDES[]) 不缓存的数据项集,适用于CacheSetup=2
    Instant data elements set(IDES[][2]) 即时获取的数据项集(AJAX)(0.Item/1.间隔)
    User-defined keywords(UDK) 是否自定义保留字
    User-defined keywords set(UDKS[][]) 自定义保留字集,适用于UDK=1
    Tp_Var 模版版本
    Tp_LastUpdate 模版最后更新时间
    Data_Var 数据版本
    ItemSet[][2] 数据标识及数据集(0.Item/1.Value)
    Sect[][4] 编译段落(0.All/1.类别/2.HTML段/3.编译后值)
    函数设计
    1.GetItems()
    功能:从模版中获取ItemSet[]
    返回:ItemSet[][0]
    2.GetSection()
    功能:从模版中获取编译段落
    返回:Sect[][0,1,2]
    3.ChkTpVar()
    功能:检查模版是否有更新
    返回:Bool value
    6.GetInfo()
    功能:获取必要信息主函数
    返回:设置所有必要信息

    4.GetValues()
    功能:获取每个Item对应的Value
    返回:Sect[][3]
    5.Compile()
    功能:编译模版
    返回:编译完成的模版

    6.Output()
    功能:输出缓存文件,刷新模版文件等
    返回:无
    7.Response()
    功能:向浏览器响应
    返回:无

    [Nova@PHP]模版结构v0.2

    模版文件结构
    <!--
    $$Rem
    {
    //注释信息,本区段不参与编译
    模版版本:
    相关说明:
    }
    $$Config

    //配置变量
    $$Cache={0|1|2|3};(不缓存|缓存某变量|不缓存某变量|全部缓存}
    如果Cache=1
    $$CacheSet={标识名,标识名,标识名...};
    如果Cache=2
    $$NoCacheSet={标识名,标识名,标识名...};
    如果自定义保留字
    $$User-Defined_Keywords={段开始符,段分隔符,段结束符,数据标识前导符},{段开始符,段分隔符,段结束符,数据标识前导符}...;
    }
    $$Compile
    {
    //编译信息,这部分由编译程序在模版最后添加
    $$Tp_Var=1;
    $$Tp_LastUpdate=2007-3-21 20:00:00;
    $$Data_Var=101010010110;
    $$Items=a,b,c,d;
    $$Values=A,B,C,D;
    }
    -->
    $$HTMLBEGIN
    模版体HTML内容
    其中编译段结构如下
    {
    段开始符 类型{单值|循环(最大循环次数)[,条件]} 段分隔符 含有数据标识的HTML 段结束符
    段开始符:可自定义,编译段开始的标志,从此位置到结束符之间的内容将被编译器解析.
    段结束符:可自定义,编译段结束的标志.
    段分割符:可自定义,分割编译段中的不同部分.
    类型:标识此编译段的类型,具体如下
    单值:编译器将根据此编译段中的数据标识找到唯一的数据替换到HTML串中
    循环(最大循环次数):编译器将根据数据标识找到一组数据,将每个分别替换到HTML段中得到一段HTML,合并后输出.当组中元素小于最大循环次数时,以组中元素个数为准.当最大循环次数为0时以组中元素个数为准.
    条件:输出单值的条件或循环中某次是否输出的条件,可以为常量或者单个数据标识
    含有数据标识的HTML:编译器将段落中的数据标识替换为相应数据拼接后输出.
    单值:single
    循环:iteration
    默认段开始符:{|
    默认段分隔符||
    默认段结束符|}
    默认数据标识前导符$$
    循环变量:Iter(从1开始)
    }
    $$HTMLEND
    3/21/2007

    [Nova@PHP]模版结构v0.1

    模版文件结构
    <!--
    $$Rem
    {
    //注释信息,本区段不参与编译
    模版版本:
    相关说明:
    }
    $$Config
    {
    //配置变量
    Cache={0|1|2|3}(不缓存|缓存某变量|不缓存某变量|全部缓存}
    如果Cache=1
    CacheSet={标识名,标识名,标识名...}
    如果Cache=2
    NoCacheSet={标识名,标识名,标识名...}
    如果自定义保留字
    User-Defined_Keywords={段开始符,段分隔符,段结束符,数据标识前导符},{段开始符
    ,段分隔符,段结束符,数据标识前导符}...
    }
    -->

    模版体HTML内容
    其中编译段结构如下
    {
    段开始符 类型{单值|循环(最大循环次数)[,条件]} 段分隔符 含有数据标识的HTML
    段结束符
    段开始符:可自定义,编译段开始的标志,从此位置到结束符之间的内容将被编译器解析
    .
    段结束符:可自定义,编译段结束的标志.
    段分割符:可自定义,分割编译段中的不同部分.
    类型:标识此编译段的类型,具体如下
    单值:编译器将根据此编译段中的数据标识找到唯一的数据替换到HTML串中
    循环(最大循环次数):编译器将根据数据标识找到一组数据,将每个分别替换到HTML段
    中得到一段HTML,合并后输出.当组中元素小于最大循环次数时,以组中元素个数为准.
    当最大循环次数为0时以组中元素个数为准.
    条件:输出单值的条件或循环中某次是否输出的条件,可以为常量或者单个数据标识
    含有数据标识的HTML:编译器将段落中的数据标识替换为相应数据拼接后输出.
    单值:single
    循环:iteration
    默认段开始符:{|
    默认段分隔符||
    默认段结束符|}
    默认数据标识前导符$$
    循环变量:Iter(从1开始)
    }
    <!--
    $$Translate
    {
    //编译信息,这部分由编译程序在模版最后添加
    Var=1;
    DateTime=2007-3-21 20:00:00;
    DataEdition=101010010110;
    Variables=a,b,c,d;
    }
    -->
     
     
    注:也考虑将配置信息写在对应的.php文件中,此事待定.
    3/16/2007

    [Nova@PHP]网站从需求分析开始

    在网站开发的第一阶段,应确定需求,并且由需求分析文档得到功能需求。分析功能需求,将其划分为多个模块分别加以实现。
    在模块级别上,分析用户任务路径,应绘制用例图。从任务路径可以得到所需用户界面以及数据入口,此二项是直接和Nova@PHP相关的。只有完成以上工作,Nova@PHP才可以在接下来的过程中发挥作用,见附图。
     
    美工人员根据界面设计创建模版。模版中除HTML外,还应包含如下内容:
    1、模版程序段。模版程序段是为不变的模版写入变化的数据的部分。其内容又包括数据内容(对象、对象组)和控制内容(选择/判断、循环)。编译过程就是分析模版中的程序段,并根据程序段向模版中拼接入相应的数据。
    2、配置信息和编译信息。配置信息由开发者按照约定格式写入主要是关于缓存:此页面是否被缓存、缓存级别等;编译信息由编译程序写入,包括最后编译时间、模版版本、模版中引用的数据以及这些数据的版本等等。
    模版机制:
    接受请求-》根据请求装载模版-》分析配置信息和编译信息-》校验模版更新日期-》如果无缓存则生成并输入页面-》如果有缓存,则检查缓存版本-》如果缓存版本最新则输出页面-》如果已经有数据更新则重新生成页面-》重新生成缓存-》输出页面
    数据引擎部分的一点想法
    见附图。由数据流分析得到数据元素(数据对象),比对用户任务路径和界面,构造多个数据投影。数据投影可能是某个数据对象的一部分属性,也可能是几个数据对象某些属性的集合。数据投影直接对应界面上某处现实,或某处表单提交的内容。数据对象不直接面向模版,而有投影来实现。
    3/15/2007

    [Nova@PHP]开始时候的话

    Nova@PHP被设计为一个PHP模版引擎,用以实现数据和数据的表现的分离。显然,其名字来源于Nova+(ASP),鉴于Nova@PHP和Nova+纠缠不清的关系,我想先赘述一下Nova+。
    Nova+是一个ASP项目,大一下学期提出时名字是Nova,是一个ASP框架(不过那时候我还没有理解什么是框架)。暑假我和Ripple等五人完成大部分功能类,事实上把这个项目变成了一个函数库项目。我们用VBS类的形式将ASP中常用的功能重写增强。这些类后来一直被我用在很多ASP项目中,还算好用吧。大二以后,因为种种原因,Nova变成我一个人的项目,方向也有所偏转,更名为Nova+。经过了几次徘徊后,我在Nova+中重点实现了数据和表现分离以及静态化。Nova+在这方面被我认为成功,但是作为ASP为基础的技术发展潜力不大,所以停工掉。也是停工后,我才意识到我写的是一种叫做模版引擎的东西。在Nova+周围,还衍生出了两个未完成的部分:一个是想象中的数据引擎,可以理解为PHP框架中的数据库抽象类,数据库抽象类我还未及了解,但是想象中的数据引擎除了数据库抽象外还重点考虑数据多级缓存机制;另一个是NPPassport,是一个跨域整合身份验证系统。其中后者完成度稍高一些,前者可以认为尚在想象阶段。这两个东西原本是纠缠在Nova+里面的,直到大二的下学期我才明智的把他们剥离,成为独立的两个东西。这些东西里面基本融入了我对ASP的所有理解以及经验,虽然有些部分还糙了点。
    下面说Nova@PHP
    作为一个可以独立引用的模版引擎,但是事实上Nova@PHP并并不是一个孤立的项目:它是设想中的PHP Framework的一部分。我从06年底开始对PHP Framework产生兴趣。大多数人认为目前PHP Framework的发展并不理想,没有非常合用的作品。当然目前我还没有勇气说填补这个空白,我的目标只是借此完成我的PHP学习,实践一下从ASP项目中获得的经验,同时增加对“框架”和“模式”的认识。目前我想象中PHP Framework中可能包括模版引擎(包括静态化模块),数据引擎(包括数据缓存),身份认证模块等,当然还很模糊。我原想做出一个完整的设计再开工,但是发现做不到,不大现实,也没有必要。事实上整个框架可以被设计为几个分立的部分,每个部分单独设计完成是可以实现的。所以,这个未命名的Framework是一个多模块集成结构,其开发周期也将分为几个段落,并且我在开工时候只能预计当前段落的时间成本。我希望这个蓝图随着时间和当前部分的推进而日渐清晰。
    正是因为Nova+积累了不少经验的缘故,所以我选取模版引擎作为整个PHP框架计划的第一动工的项目。我目前对PHP还不很了解,只在做作业的时候写过一个没有实用价值的小站。所以3月底以前,我要做的只是在语法要求内将Nova+由ASP翻译为PHP,并作为Nova@PHP的第一个版本。之后的时间我会随着PHP了解的增加,根据PHP的特点对它作一些有限的优化。不会很多,因为对PHP了解必经尚浅。可能我会用这个版本的Nova@PHP重写视听在线(vod.bitnp.net)。随后会立即开始第二个部分,有可能是数据引擎吧,未定。如果是的话,可能在完成后重写GoShop(go.bitnp.net)。目前只想好这么多,可以权当只有一个模板引擎的计划吧。
    Nova@PHP将是一个轻量级的模板引擎,着重实现常用功能,第一个版本的目标主要锁定在:1、易上手;2、易用;3、满足中小型常规站点功能需要;4、效率不差。
    易上手是指一个新人从未知到掌握使用方法的过程要容易。易用指的是其应用简洁而非繁琐。之所以将这两条写在前面,是因为搜索引擎上看到的大部分人对于目前的模版引擎的抱怨是复杂难以驾驭。虽然某些人确实懒得可以,但是毕竟程序开发的目标就是解决问题,如果Nova@PHP能因为简单简洁成为大家喜欢用的模版引擎,那么也就算成功了。
    Nova@PHP项目从今天正式开始了。