搜索
首页后端开发php教程 自个儿动手写一个简单的php模板引擎

自己动手写一个简单的php模板引擎

模板引擎中最核心的思想是:将模板中的变量编译为php的变量进行输出。

例如:demo.tpl

{$data}
{$title}

那么模板引擎就要将{$data} {$title} 编译为

要实现这个功能使用正则替换就可以了:

$content = '{$data}{$title}';
$pattern = "/\{\\$([a-zA-Z_][a-zA-Z0-9_]*)\}/";
$content = preg_replace($pattern,'<?php echo \$this->tmpValue["$1"]  ?>',$content);
echo $content; // <?php echo $data; ?><?php echo $title; ?>

这就是php模板引擎的核心功能了。下面是我写的一个简单的php模板引擎

首先是tempTool.class.php 它的作用的提供模板引擎需要用到的一些小工具

<?php /**
 * 工具类
 **/
class tempTool
{
	protected $error = array();		//错误信息
	function __construct()
	{
	}
	/** 
         * 生成错误日志数组
         **/
        protected function error($k,$v)
        {
                if(!empty($k) && !empty($v)) {
                        $this->error[$k] = $v;
                }else {
                        exit('tempTool.class.php的error方法收到了不确定的参数错误!');
                }

        }
        /**
         * 获取错误信息
         **/
        public function getError() {
                foreach($this->error as $k=>$v) {
                        echo $k.$v.'<br>';
                }
        }
	
}
?>


然后是template.class.php 它的作用是提供模板引擎应该有的功能

<?php /**
 * 模板引擎类 用语提供模板引擎应该具有的方法
 **/
include_once "tempTool.class.php";
class template extends tempTool{
	private $config = array(
				'tmpDir'=>'template/',		// 模板文件目录
				'cmpDir'=>'compile/',		// 编译文件目录
				'cacheDir'=>'cache/',		// 缓存文件目录
				'tmpSuffix'	=>'.tpl',		// 模板文件后缀
				'cacheSuffix'	=>'.html',		// 缓存文件后缀
				'caching'	=>false			// 是否开启缓存
			);
	private $tmpFile;				// 模板文件
	private $cmpFile;				// 编译文件
	private $cacheFile;				// 缓存文件
	private $tmpValue = array();			// 变量值栈
	public function __construct($config = null)
	{
		// 同步配置
		if(is_array($config)) {
			$this->config = array_merge($this->config,$config);
		}
		// 检查模板编译缓存目录是否存在不存在创建
		if( !$this->checkDir($this->config['tmpDir']) || !$this->checkDir($this->config['cmpDir']) || !$this->checkDir($this->config['cacheDir']) ) {
			exit;
		}
	}

	/**
	 * 检查目录是否存在不存在自动创建
	 **/
	private function checkDir($dir)
	{
		if(!is_dir($dir)) {
			if(!mkdir($dir)) {
				$this->errorLog[] = array('创建文件夹失败:'=>$dir);
				return false;
			}
		}
		return true;
	}

	/**
	 * 像模板中分配变量
	 * 
	 **/
	public function assign($k,$v)
	{
		if(!empty($k) && !empty($v)) {
			$this->tmpValue[$k] = $v;
		}else {
			$this->error('分配变量失败:','分配到模板中变量的key或者value为空!');
		}
	}

	/**
	 * 编译文件
	 **/
	public function display($tmpFile)
	{
		// 获取模板文件
		$tmpFile = $this->config['tmpDir'].$tmpFile.$this->config['tmpSuffix'];
		// 获取编译文件
		$cmpFile = $this->config['cmpDir'].md5($tmpFile.'compile').'.php';
		if(!file_exists($tmpFile)) {
			$this->error('模板文件不存在:',$tmpFile.'不存在');
		}
		// 当编译文件不存在或者是模板文件被修改过了才重新编译
		if(!file_exists($cmpFile) || filemtime($cmpFile) cmp($tmpFile,$cmpFile);
		}
		// 是否开启缓存
		if($this->config['caching']) {
			// 获取缓存文件
			$cacheFile = $this->config['cacheDir'].md5($tmpFile.'cache').$this->config['cacheSuffix'];
			// 当缓存文件不存在或者是模板文件被修改过重新生成缓存文件
			if(!file_exists($cacheFile) || filemtime($cacheFile) error('编译文件生成失败:',$cacheFile);
				}
			}
			//载入缓存文件
            		include $cacheFile;
		}else {
			// 载入编译文件
			include_once $cmpFile;
		}
	}
}


compile.class.php  编译类将模板文件编译为php文件

<?php /**
 * 编译类将模板文件编译为php文件
 **/
include_once "tempTool.class.php";
class compile extends tempTool
{
	private $content; 			// 文件编译后的内容
	/**
	 * 将模板文件编译php文件
	 **/
	function cmp($tmpFile,$cmpFile)
	{
		if(!($content = file_get_contents($tmpFile))){
			$this->error("文件读取失败:",$tmpFile);	
		}
		$pattern = "/\{\\$([a-zA-Z_][a-zA-Z0-9_]*)\}/";
		$this->content = preg_replace($pattern,'<?php echo \$this->tmpValue["$1"]  ?>',$content);
		$this->parse($cmpFile);
		
	}
	/**
	 * 将编译好的内容写入文件
	 **/
	public function parse($cmpFile)
	{
		if(!file_put_contents($cmpFile,$this->content)){
			$this->error('文件写入失败:',$cmpFile);
		}
	}
}
?>

下面进行一下测试:

1. 新建一个 template 文件夹 在里面写 一个模板 demo.tpl

{$data}
{$title}
2.新建一个demo.php

<?php $config = array('caching'=>true);
include_once "template.class.php";
$tmp = new template($config);
$tmp->assign('data','ccc');
$tmp->assign('title','这时测试用例');
$tmp->display('demo');


结果输出 ccc这时测试用例  

可以看一下cache目录和 compile目录下  会生成一个缓存文件 和一个编译文件

这时就成功了

声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
优化PHP代码:减少内存使用和执行时间优化PHP代码:减少内存使用和执行时间May 10, 2025 am 12:04 AM

TOOPTIMIZEPHPCODEFORDUSEMEMORYUSAGEAGEAGEAGEAGEAGEANDEXECUTITIEM,关注台词:1)USEREEREFERESCENCENCINCOPYINSTEADOFCOPYINGINATATASTRUCTURESTROUCTURESTOREDUCEMORYCONSUMPTION.2)杠杆phphppphpphp'sbuilt intimpunctionslikearray_mapforfunctionslikearray_mapforfforfforfforfasterapasterexecution.3)

PHP电子邮件:分步发送指南PHP电子邮件:分步发送指南May 09, 2025 am 12:14 AM

phpisusedforsendendemailsduetoitsignegrationwithservermailservicesand andexternalsmtpproviders,自动化notifications andMarketingCampaigns.1)设置设置yourphpenvironcormentswironmentswithaweberswithawebserverserverserverandphp,确保themailfunctionisenabled.2)useabasicscruct

如何通过PHP发送电子邮件:示例和代码如何通过PHP发送电子邮件:示例和代码May 09, 2025 am 12:13 AM

发送电子邮件的最佳方法是使用PHPMailer库。1)使用mail()函数简单但不可靠,可能导致邮件进入垃圾邮件或无法送达。2)PHPMailer提供更好的控制和可靠性,支持HTML邮件、附件和SMTP认证。3)确保正确配置SMTP设置并使用加密(如STARTTLS或SSL/TLS)以增强安全性。4)对于大量邮件,考虑使用邮件队列系统来优化性能。

高级PHP电子邮件:自定义标题和功能高级PHP电子邮件:自定义标题和功能May 09, 2025 am 12:13 AM

CustomHeadersheadersandAdvancedFeaturesInphpeMailenHanceFunctionalityAndreliability.1)CustomHeadersheadersheadersaddmetadatatatatataatafortrackingandCategorization.2)htmlemailsallowformattingandttinganditive.3)attachmentscanmentscanmentscanbesmentscanbestmentscanbesentscanbesentingslibrarieslibrarieslibrariesliblarikelikephpmailer.4)smtppapapairatienticationaltication enterticationallimpr

使用PHP和SMTP发送电子邮件的指南使用PHP和SMTP发送电子邮件的指南May 09, 2025 am 12:06 AM

使用PHP和SMTP发送邮件可以通过PHPMailer库实现。1)安装并配置PHPMailer,2)设置SMTP服务器细节,3)定义邮件内容,4)发送邮件并处理错误。使用此方法可以确保邮件的可靠性和安全性。

使用PHP发送电子邮件的最佳方法是什么?使用PHP发送电子邮件的最佳方法是什么?May 08, 2025 am 12:21 AM

ThebestapproachforsendingemailsinPHPisusingthePHPMailerlibraryduetoitsreliability,featurerichness,andeaseofuse.PHPMailersupportsSMTP,providesdetailederrorhandling,allowssendingHTMLandplaintextemails,supportsattachments,andenhancessecurity.Foroptimalu

PHP中依赖注入的最佳实践PHP中依赖注入的最佳实践May 08, 2025 am 12:21 AM

使用依赖注入(DI)的原因是它促进了代码的松耦合、可测试性和可维护性。1)使用构造函数注入依赖,2)避免使用服务定位器,3)利用依赖注入容器管理依赖,4)通过注入依赖提高测试性,5)避免过度注入依赖,6)考虑DI对性能的影响。

PHP性能调整技巧和技巧PHP性能调整技巧和技巧May 08, 2025 am 12:20 AM

phperformancetuningiscialbecapeitenhancesspeedandeffice,whatevitalforwebapplications.1)cachingwithapcureduccureducesdatabaseloadprovesrovesponsemetimes.2)优化

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

安全考试浏览器

安全考试浏览器

Safe Exam Browser是一个安全的浏览器环境,用于安全地进行在线考试。该软件将任何计算机变成一个安全的工作站。它控制对任何实用工具的访问,并防止学生使用未经授权的资源。

Dreamweaver Mac版

Dreamweaver Mac版

视觉化网页开发工具

PhpStorm Mac 版本

PhpStorm Mac 版本

最新(2018.2.1 )专业的PHP集成开发工具

WebStorm Mac版

WebStorm Mac版

好用的JavaScript开发工具

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

功能强大的PHP集成开发环境