文档章节

smarty太臃肿!手动原创一个视图模板引擎

voyage1314
 voyage1314
发布于 2013/12/24 16:33
字数 860
阅读 189
收藏 0
点赞 0
评论 6
<?php
/**
 * 模板引擎
 *
 */
class View {
    //编译目录
    private $compile_dir = '/tmp/';
    //存储文本数组
    private $template_array;
    //文件路径
    private $file_name;
    //include行号
    private $INCLUDE;
    //if开始标签行号
    private $IF_START;
    //else行号
    private $IF_ELSE;
    //if结束标签行号
    private $IF_END;
    //foreach开始标签行号
    private $FOREACH_START;
    //foreach结束标签行号
    private $FOREACH_END;
    
    public function __construct($file_name) {
        $this->file_name = $file_name;
    }
    
    /**
     * 模板编译
     */
    public function complie() {
        //将文件以数组的形式输出
        $this->template_array = file($this->file_name);
        //查找include
        foreach ($this->template_array as $key => $value) {
            $template_array[$key] = trim($value);
            $mark = substr($template_array[$key], 0,8);
            if ($mark == '{include') 
                $this->INCLUDE[] = $key;
        }
        //include存在则合并包含文件
        if (isset($this->INCLUDE)) {
            $this->pregInclude();
            foreach ($this->template_array as $key => $value) {
                if (is_array($value)) {
                    foreach ($value as $k => $v) {
                        $include_array[] = $v;
                    }
                }
                else {
                    $include_array[] = $value;
                }
            }
        }
        else {
            $include_array = $this->template_array;
        }
        unset($this->template_array);
        unset($template_array);
        foreach ($include_array as $k => $v) {
            $array[$k] = trim($v);
            $mark = substr($array[$k], 0,4);
            switch ($mark) {
                //foreach开始
                case '{for':$this->FOREACH_START[] = $k;
                break;
                //foreach结束
                case '{/fo':$this->FOREACH_END[] = $k;
                break;
                //if开始
                case '{if ':$this->IF_START[] = $k;
                break;
                //else
                case '{els':$this->IF_ELSE[] = $k;
                break;
                //if结束
                case '{/if':$this->IF_END[] = $k;
                break;
            }
        }
        $this->template_array = $include_array;
        unset($include_array);
        /**
         * 转为php标签
         */
        if (isset($this->FOREACH_START)) {
            $this->pregForeachStart();
            $this->pregEnd($this->FOREACH_END);
        }
        if (isset($this->IF_START)) {
            $this->pregIfStart();
            $this->pregEnd($this->IF_END);
        }
        if (isset($this->IF_ELSE)) {
            $this->pregElse();
        }
        /**
         * 写入文件
         */
        $template_string = $this->pregString();
        $complie_file = basename($this->file_name); //产生缟译后的文件名
        $result = file_put_contents($this->compile_dir.'/view/'.$complie_file, $template_string);
        if (is_int($result)) 
            return $template_string;
        else return false;
    }
    /**
     * 合并include文件
     * @param string $key    :0
     * @param string $value :{include file="/xx/xx.phtml"}
     */
    private function pregInclude() {
        foreach ($this->INCLUDE as $value) {
            $tmp = explode("\"", $this->template_array[$value]);
            $path = "/yby/site/YAE/application/views$tmp[1]";
            if (!file_exists($path)) exit('文件不存在');
            $this->template_array[$value] = file($path);
        }
    }
    /**
     * 替换foreach开始标签
     * @param unknown $key
     * @param unknown $value
     */
    private function pregForeachStart() {
        foreach ($this->FOREACH_START as $line) {
            $value = $this->template_array[$line];
            /**
             * 分解foreach条件 "{foreach key=k value=data}"
             * $foreach_condition[0] = "{foreach" 
             * $foreach_condition[1] = "key=k"
             * $foreach_condition[2] = "data=$value}"
             */
            $foreach_condition = explode(' ', trim($value));
            $foreach_condition_data = rtrim($foreach_condition[2],'}');
            /**
             * $data = "data"
                * $val = "$value"
             */
            list($data,$val) = explode('=', $foreach_condition_data);
            /**
             * $key = "key"
             * $k = "k"
             */
            list($key,$k) = explode('=', $foreach_condition[1]);
            $replace = "<?php foreach($val as $".$k." => $"."$data) {?>";
            $this->template_array[$line] = $replace; 
        }
    }
    /**
     * 替换if开始标签
     * @param unknown $key
     * @param unknown $value
     */
    private function pregIfStart() {
        //$line 行号
        foreach ($this->IF_START as $line) {
            $value = $this->template_array[$line];
            /**
             * $if_condition = "$data.status == 0" or "$value == null" or "isset($value)"
             */
            $if_condition = substr(trim($value), 4);
            $if_condition = rtrim($if_condition,'}');
            $if_condition = explode(' ', $if_condition);
            $count = count($if_condition);
            switch ($count) {
                case 1:
                    $replace = "<?php if(".$if_condition[0].") { ?>";
                break;
                case 2:
                break;
                case 3:
                    $if_condition_data = explode('.', $if_condition[0]);
                    $num = count($if_condition_data);
                    $data = $if_condition_data[0];
                    for ($i = 1; $i < $num; $i++) {
                        $data .= "['$if_condition_data[$i]']";
                    }
                    $replace = "<?php if(".$data.$if_condition[1].$if_condition[2].") { ?>";
                break;
            }
            $this->template_array[$line] = $replace;
        }
    }
    /**
     * 替换结束标签
     * @param unknown $key
     */
    private function pregEnd($value) {
        foreach ($value as $line) {
            $replace = "<?php } ?>";
            $this->template_array[$line] = $replace;
        }
    }
    /**
     * 替换else
     * @param unknown $key
     */
    private function pregElse() {
        foreach ($this->IF_ELSE as $line) {
            /**
             * $if_condition[0] :"{else}" or "{elseif *** == ***}" or "{elseif isset(***)}"
             */
            $if_condition = trim($this->template_array[$line]);
            $if_condition = trim($if_condition,'{}');
            $if_condition = explode(' ', $if_condition);
            $count = count($if_condition);
            switch ($count) {
                case 1:
                    $replace = "<?php }else{ ?>";
                    break;
                case 2:
                    $replace = "<?php }elseif($if_condition[1]) { ?>";
                    break;
                case 4:
                    $if_condition_data = explode('.', $if_condition[1]);
                    $num = count($if_condition_data);
                    $data = $if_condition_data[0];
                    for ($i = 1; $i < $num; $i++) {
                        $data .= "['$if_condition_data[$i]']";
                    }
                    $replace = "<?php }elseif($data $if_condition[2] $if_condition[3]) { ?>";
                    break;
            }
            $this->template_array[$line] = $replace;
        }
    }

    /**
     * 直接输出字符串
     */
    private function pregString() {
        $template_string = implode('', $this->template_array);
        /**
         * $matches[0][$i] : "{$data.app_name}"
         */
        preg_match_all("/\{(\\$(\b\w+\b\.)+\b\w+\b)\}|\{(\\$\b\w+\b)\}/", $template_string, $matches);
        if (!empty($matches[0])) {
            foreach ($matches[0] as $key => $val) {
                $value = trim($val,'{}');
                $data = explode('.', $value);
                $count = count($data);
                $result = $data[0];
                for ($i = 1; $i < $count; $i++) {
                    $result .= "['$data[$i]']";
                }
                $replace = "<?php echo $result;?>";
                $template_string = str_replace($val, $replace, $template_string);
            }
        }
        return $template_string;
    }
    
    public function __destruct() {
        unset($this->template_array);
    }
}




© 著作权归作者所有

共有 人打赏支持
voyage1314
粉丝 7
博文 9
码字总数 6947
作品 0
杨浦
程序员
加载中

评论(6)

overlords
overlords

引用来自“邓攀”的评论

php为啥需要模板引擎,本身就是一个模板引擎。

真心觉得没意思,php本身就是混血的,中间再来一个无聊
哈哈__哈哈
哈哈__哈哈

引用来自“voyage1314”的评论

引用来自“邓攀”的评论

php为啥需要模板引擎,本身就是一个模板引擎。

那不懂php语法的前端如何去写逻辑

什么逻辑,逻辑肯定都是后端去写啊。。跟前段没关系,
哈哈__哈哈
哈哈__哈哈

引用来自“voyage1314”的评论

引用来自“邓攀”的评论

php为啥需要模板引擎,本身就是一个模板引擎。

那不懂php语法的前端如何去写逻辑

我觉得一个mvc的即可,比如我用zend framework就在view写那些拼接字符串的工作,再搞一个smarty就有点慢而且不值得了
voyage1314
voyage1314

引用来自“邓攀”的评论

php为啥需要模板引擎,本身就是一个模板引擎。

那不懂php语法的前端如何去写逻辑
哈哈__哈哈
哈哈__哈哈
php为啥需要模板引擎,本身就是一个模板引擎。
月影又无痕
月影又无痕
就别用这种东西误导初学者了吧
构建mvc框架学习

做了那么久PHP开发,开始尝试去做一个简单的mvc框架。 一、首先确定目录结构 由于不太想弄得太复杂的结构,因此,将所有的目录存放于libs中,项目根目录只留一个index.php以及config.php,形...

AlpherJang ⋅ 2016/03/03 ⋅ 0

除了smarty还有啥比较靠谱的php模板引擎

smarty太臃肿,想找一个比较轻巧的模板引擎,执行效率高点的,文件数量不超过10个。

leo108 ⋅ 2013/08/17 ⋅ 8

PHP应用框架--SpeedPHP

SpeedPHP是一款全功能的国产PHP框架应用系统,速度飞快,上手容易,是最适合初学者的PHP框架,以“快速开发、快速学习、快速执行”为理念,带你轻松进入PHP高手的行列。 SpeedPHP 3正式版发布...

SpeedPHP ⋅ 2009/12/07 ⋅ 2

基于 PHP 的企业内容管理系统--MyfCMS

闵益飞内容管理系统英文缩写MyfCMS,采用PHP5+MySQL作为技术基础进行开发。MyfCMS的模板引擎使用了当前最流行的smarty模板引擎,MVC框架采用了自己研发的MyfMVC框架(特轻量级的PHPMVC框架,...

feiyue ⋅ 2012/05/21 ⋅ 0

PHP 模板引擎SMARTY 原理

一、MVC需要模板 MVC最早是在SmallTalk语言的开发过程中总结出的一种设计模式,MVC分别代表了"模型"、"视图"和"控制",目的就是让不同的开发角色在大中型项目中各司其职。在网络应用程序的开...

酒肉穿肠过 ⋅ 2013/09/25 ⋅ 0

Node.js 模板引擎--lcNode

lcNode简介 lcNode是针对node.js的模板引擎,语法介于jsp与smarty之间。 1、目录 当前为完整的node.js测试目录,核心模块为node_modules/laocheng/ index.jstemplate/compile/node_modules/...

老成有木有 ⋅ 2016/12/18 ⋅ 0

(PHP学习笔记)工厂类在MVC框架中的运用

在基本的MVC框架模型中,会引用到数据库和模板文件。但是不同的开发者会选择不同的数据库以及模板引擎。因为在实际开发的过程中,有可能会更换数据库或者是模板引擎,如果针对每个数据库以及...

w1sw ⋅ 2016/08/29 ⋅ 0

osadmin 开源管理后台 v2.0.0 发布

增加自定义模块图标 重大升级:osadmin使用的模板引擎smarty从2.x升级到3.x,目前使用的是3.1.15. 从1.x升级到2.x基本需要全部覆盖,smarty2和smarty3的语法等功能不太相同,smarty3更强大。...

somewhereyu ⋅ 2013/10/21 ⋅ 20

模板引擎--List Template

Lite 缩写自List Template,是一个由简单的控制指令集和一个表达式解析引擎组成的简单模板引擎。 模板语言所解析的中间格式,由数组、字符串、和整数三种数据类型组成。数组就是这里唯一的复...

匿名 ⋅ 2009/04/07 ⋅ 0

PHP沉思录-第三篇-Smarty-左轻侯-《程序员》2007年10月号

创建时间:2007-10-31 21:23:11 最后修改时间:2007-10-31 21:23:11 PHP沉思录之三:Smarty   左轻侯   2007.8.11       在任何Web应用中,如何将程序代码和界面设计,或者说,将逻辑...

一配 ⋅ 2015/10/16 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

关于“幂等”操作

一个幂等(idempotent)操作的特点是其任意多次执行所产生的影响均与一次执行的影响相同. 开发中, 我们经常考虑幂等操作的场景有“接口调用”、“MQ消费”、“自动任务”等 接口调用, 可能出现...

零二一七 ⋅ 11分钟前 ⋅ 0

Dubbo服务服务暴露之ProxyFactory Invoker

Dubbo服务暴露过程中有涉及到调用ProxyFactory 中方法获取Invoker对象的过程,现在我们来深究下源码,来看下这个过程是在做些什么,返回的Invoker 对象是什么,我们来看一下代码的切入点: ...

哲别0 ⋅ 26分钟前 ⋅ 0

GP两种连接方式性能测试

GP两种连接方式性能测试 Pivotal import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; public class GPQueryStrin......

仔仔1993 ⋅ 30分钟前 ⋅ 0

jsonrpc-4j代码解析

解析文件 AutoJsonRpcServiceImplExporter JsonServiceExporter AutoJsonRpcServiceImplExporter 路径:com.googlecode.jsonrpc4j.spring.AutoJsonRpcServiceImplExporter AutoJsonRpcServi......

郭恩洲_OSC博客 ⋅ 52分钟前 ⋅ 0

百度搜索

from selenium import webdriver import time brower=webdriver.Firefox() brower.get('http://www.baidu.com') input=brower.find_element_by_id('kw') input.send_keys('中南大学') time.s......

南桥北木 ⋅ 59分钟前 ⋅ 0

tomcat 日志记录器

1、日志记录器是记录消息的组件 日志记录器需要与某个servlet 容器相关联 2、Logger 接口 共定义了5种日志级别:FATAL、ERROR、WARNING、INFORMATION、DEBUGGER setVerbosity 设置级别 setC...

职业搬砖20年 ⋅ 今天 ⋅ 0

Thrift RPC实战(三) Thrift序列化机制

1.Thrift基础架构 Thrift是一个客户端和服务端的架构体系,数据通过socket传输; 具有自己内部定义的传输协议规范(TProtocol)和传输数据标准(TTransports); 通过IDL脚本对传输数据的数据结构...

lemonLove ⋅ 今天 ⋅ 0

网站建设就要像2018世界杯的俄罗斯队大杀四方[图]

今天心情不错,因为昨天晚上观看了世界杯比赛,尤其是对俄罗斯队的大杀四方感到十分霸气侧漏啊,因此我联想到了自己的博客网站,我的博客是去年年底上线的,一直想建设一个关于读书和读后感作...

原创小博客 ⋅ 今天 ⋅ 0

linux 信号机制

signal(SIGPIPE, SIG_IGN); TCP是全双工的信道, 可以看作两条单工信道, TCP连接两端的两个端点各负责一条. 当对端调用close时, 虽然本意是关闭整个两条信道, 但本端只是收到FIN包. 按照TCP协...

xxdd ⋅ 今天 ⋅ 0

my.cnf, my-small.cnf, my-medium.cnf, my-large.cnf

1. my-small.cnf # Example MySQL config file for small systems.## This is for a system with little memory (<= 64M) where MySQL is only used# from time to time and it's importa......

周云台 ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部