所谓的代码分离 其实只是一种思路,既然是一种思路 那就意味着他是有需求的 没有需求就没有解决方案 没有方案就不存在思路。

在这之前,我们制作 PHP 程序页面的时候。都是 HTML 和 PHP 混合写在一起的。

这产生了什么样的问题,主要有两个:

1、代码太长不便阅读,一个流程往往跨了N行代码,可能之后还需要几个括号结束都不记得了。。
2、不便于编辑网页,我们制作网页的时候。往往是先用 DW 等工具,设计好页面之后,再往里面添加 PHP 代码。但是很多时候,有些 HTML 需要 PHP 输出。这个时候,这些代码就不便于返回 DW 编辑样式。
简单来说就是 修改页面样式困难,所以我们的代码只有php多好 这样代码的行数就明显减少 html代码在另一边, 也能方面的调回dw等工具重新编辑。
 比如说:表单页和 PHP 页是分开的。为什么不写在一起呢。
如果写在一起的话。可能会存在一个问题。比如网页一打开。就会马上执行写入操作。而这个时候表单还没有提交。提交以后。也不需要再显示表单页了。于是就有了判断。
 if($_POST) {
   //处理提交后的数据
} else {
   //显示表单
用 if 把程序分成两个流程。

 在显示表单的时候。中间得插上一段长长的 HTML 代码。 写好的代码,重新读起来相当不便。
 有时候自己都找不到后面的 } 写在哪一行了。 这个时候。代码分离的方案。就有用武之地了。
 我们先来说一下。HTML 和 PHP 分别的工作内容。要了解它们的工作本质。才能准确的分离它们。 我们知道,最终输出到网页上的,是 PHP 执行之后的结果。而且是输出的结果。  这个逻辑。意味着一个事情:所有 HTML 代码都是用于输出的。 那 PHP 代码做什么的。计算,流程控制。 于是呢,就有程序员开始这么想。把 HTML 分离开来。需要显示它的时候。再用 include 函数把 HTML 包含进来。 
 像刚才的表单提交。我们可以这样写

if($_POST) {

} else {
    include("post.htm");

 PHP 代码和 HTML 分开了。 在需要的时候,再显示 HTML  这就是最原始的代码分离方案。 这里产生一个问题,像我们制作文章页面的时候。需要在 HTML 里大量输出变量

 光是这样 include  一个 HTML 文件进来是做不到的。 这里,就得利用一下“包含”的特性了。 包含。是指把另一个文件的代码,调到当前位置来执行。 如果这个文件里面就有 echo $a; 这样的写法。而当前的程序中。 $a 是有赋值的。 那么。调进来以后。$a  的值会被输出。 于是,我们的 HTML 页,我可以存为 PHP 页。只在需要的地方,echo 变量。

 就有这么一种写法

<html>
<body>
<?PHP echo $a; ?>
</body>
</html> 为了方便 HTML 代码能重新回到 DW 里编辑。在这里的 echo 不含任何代码。用很小的 PHP 代码块。嵌入 HTML 码中。 这些小的代码块。基本上都只有 echo,完全不干涉 HTML 代码。 这样做的同时。提出了一个新的要求。这个被包含的页面里面。定义过的变量。需要事先知道。 这个特性。到现在各种模板引擎流行的年代。依然没有改变。这个将要被包含用于输出的页面。。我们就称为:模板 ,之后,我们只要写很纯的 PHP 程序就可以了。事先准备好这些变量,并赋好值。 然后,在我们程序执行将要结束的时候,需要输出页面时。包含这个 模板文件 进来。它就能帮我们把所有变量输出了。 这就是最基本的 代码分离 实现的手法。我们来试写一个模板文件。之前说过。模板文件要能方便的在 DW 等工具里编辑,我就用 DW 制作一个模板文件。

 好了,假设,这是我们期望输出的样子。 这是读以前做的留言本用的 这里需要一个循环。我填写上输出变量。

代码如下:

<html>
<head>
<title>测试用模板</title>
</head>
<body>
<table border="1" width="600" >
<tr>
<td width="40">ID</td>
<td width="100">姓名</td>
<td>联系方式</td>
</tr>
<?PHP foreach($list as $v) { ?>
<tr>
<td><?PHP echo $v['id']; ?></td>
<td><?PHP echo $v['name']; ?></td>
<td><?PHP echo $v['link']; ?></td>
</tr>
<?PHP } ?>
</table>
</body>
</html>

 这种编写方使得这个PHP 程序放到 DW 等可视化工具里编辑时。还能完整的看到原来的网页效果。 我们只要记住。这个模板需要一个名为 $list 的数组变量就可以了。

<?PHP

$link = mysql_connect("localhost", "root", "qsdmt0409");
mysql_select_db("test");
mysql_query("set names gbk"); $sql = "select * from `gbook`";
$rs = mysql_query($sql); $list = array();
while($line = mysql_fetch_assoc($rs)) {
$list[] = $line;
} include("tpl.php"); ?>

  这是使用模板的PHP程序。中间那里。读取数据的时候。我并没有使用输出。而是赋值到一个名为 $list 的数组变量里。读取结束后,使用 include 包含这个模板文件。 显示效果如下

 如果需要显示不同的网页样式。只要加载不同的模板文件就可以了。 代码分离的特点。就是要求:需要知道模板上都有什么样的变量名。它要一个什么样的数据结构。

 模板使得我们的 PHP 代码精简了不少。可以集中精力去思考 PHP 应该做的事情。 也让写好的 PHP 程序更易读易改。 但是,这里还存在一些小问题。 我们的 PHP 程序往往代码很长。里面用过的变量有时候有上百个之多。 可能会出现一种情况。就是这个变量。在之后被修改过了。自己却没发现。 这种情况。叫“变量名污染”。有些变量。我们只是希望在 PHP 中使用,并不希望它显示到模板里。但有些变量。可能由于流程比较复杂。不小心重新赋值了。 
 那么,我们可以封装这样的一个自定义函数。

function tpl( $name ) {
    include($name . ".php");
}

 这样一来,的确内外变量就不冲突了。新的问题又来了,那我们希望赋值的变量如何送进去? 几种可实现的方法。第一个是通过某种全局变量。送进去。 预定义变量,都是全局变量。它们都可以穿透自定义函数。但是大多数预定义变量都有自己的用途。 $GLOBALS 这个预定义变量则没有问题。但是,预定义变量都是数组。模板中需要的是一个准确的变量。 可以使用 foreach 来遍历数组读取索引和值,取索引重新组成一个新的变量,赋值为它当前值。foreach($GLOBALS as $k=>$v) $$k=$v;
 function tpl( $name ) {
    foreach($GLOBALS as $k=>$v) $$k=$v;
    include($name . ".php");
}

<?PHP

function tpl( $name ) {
foreach($GLOBALS as $k=>$v) $$k=$v;
include($name . ".php");
} $link = mysql_connect("localhost", "root", "qsdmt0409");
mysql_select_db("test");
mysql_query("set names gbk"); $sql = "select * from `gbook`";
$rs = mysql_query($sql); $list = array();
while($line = mysql_fetch_assoc($rs)) {
$list[] = $line;
}
$GLOBALS['list'] = $list;
tpl('tpl');
?>

$GLOBALS['list'] = $list;

在这里,我们把我们准备好的数据。存放到 全局变量 中。 然后,在自定义函数里,通过这个全局变量,还原出变量。

但是,考虑到预定义变量。常常用于其他用途。这里还是放弃了这种做法。

 我们可以使用自定义变量。然后通过自定义函数的参数传进去。
 function tpl( $name, $data ) {
    foreach($data as $k=>$v) $$k=$v;
    include($name . ".php");
 $list = array();
while($line = mysql_fetch_assoc($rs)) {
    $list[] = $line;
}
$data = array();
$data['list'] = $list;

tpl('tpl', $data);

 还有另一种方法。就是把变量放到另一个自定义函数中保存起来。需要的时候再读出来。 
静态变量可以做到这一点。

function set_var($name = NULL, $value = NULL) {
static $data = array();
if(is_null($name)) return $data;
$data[$name] = $value;
}

 我定义一个这样的函数。里面声明 $data 是一个静态变量。 静态变量,使用它的值不会消失。而会被一直保留到 PHP 运行结束。 重复运行这个函数。里面的静态变量值,不会被重新赋值。 如果变量名未指定。则返回数组。。否则 给数组新定义一个索引。并赋值为指定的值。

<?PHP

function set_var($name = NULL, $value = NULL) {
static $data = array();
if(is_null($name)) return $data;
$data[$name] = $value;
} function tpl( $name) {
$data = set_var();
foreach($data as $k=>$v) $$k=$v;
include($name . ".php");
} $link = mysql_connect("localhost", "root", "qsdmt0409");
mysql_select_db("test");
mysql_query("set names gbk"); $sql = "select * from `gbook`";
$rs = mysql_query($sql); $list = array();
while($line = mysql_fetch_assoc($rs)) {
$list[] = $line;
}
set_var('list', $list); tpl('tpl');
?>

  

 现在代码如上。 使用 set_var 函数。把要显示的变量,记忆到另一个世界中。然后。在读取模板之前。把变量重新读回来。并恢复成普通的变量。当然。之前用一个变量来记忆也是一个办法。但是始终是占用了程序的变量。

 我们可以试试看。多赋值几个。

 <h1><?PHP echo $title; ?></h1>
<hr />

 set_var('title', '这里是大标题');
tpl('tpl'); 
为了省事,我把它们封装成一个类。
class tpl {
public function set_var($name = NULL, $value = NULL) {
static $data = array();
if(is_null($name)) return $data;
$data[$name] = $value;
} public function p( $name) {
$data = $this->set_var();
foreach($data as $k=>$v) $$k=$v;
include($name . ".php");
}
}

  

$tpl = new tpl();

$link = mysql_connect("localhost", "root", "qsdmt0409");
mysql_select_db("test");
mysql_query("set names gbk"); $sql = "select * from `gbook`";
$rs = mysql_query($sql); $list = array();
while($line = mysql_fetch_assoc($rs)) {
$list[] = $line;
} $tpl->set_var('list', $list);
$tpl->set_var('title', '这里是大标题'); $tpl->p('tpl');

  现在,使用模板成了这样子。准备好要赋值的数据。赋值到指定的标记上。 只在最后  方法时,才调用模板并显示。现在看看,如果代码写成这样。给我们来带了多少好处。

 代码中不再含有 HTML 码,清晰简单了许多。 我们可以专心写我们的 PHP。只要准备好要输出的变量就可以了。 set_var 会帮我们把这些值。复制到另一个世界中保存的。

 这个变量名你之后用来做别的也没关系了。不担心变量名污染。 模板文件,可以轻松的调回可视化编辑器重新回炉加工。 如果你的数据,全部都是从数据库等方面读出来的。 这样会使得我们的 PHP 代码中,不再夹有中文或特殊字符。清一色的 ASCII 码。 这使得 PHP 程序不用再意它本身是什么编码构成,这使得 PHP 程序不用再意它本身是什么编码构成,之前编写代码,之所以在意文件编码。是因为我们的代码中夹着大量的要输出的内容。 这些要输出的内容,是有编码的。 当你的代码中,只有 PHP 的时候,不用再意 PHP 程序本身的编码。使用模板。因为是执行到最后才一次输出。使得我们在编写过程中。不再考虑一些特殊函数。。使用前不能有输出的规则。例如 setcookie header  ,使用模板的程序。整页都没有一个输出。。只有最后那里才有。 而且负责输出的代码。只有一行。。目前使用得最多的模板类。要属 smarty 模板类了。 

PHP代码分离的更多相关文章

  1. 转载-使用 Feed4JUnit 进行数据与代码分离的 Java 单元测试

    JUnit 是被广泛应用的 Java 单元测试框架,但是它没有很好的提供参数化测试的支持,很多测试人员不得不把测试数据写在程序里或者通过其它方法实现数据与代码的分离,在后续的修改和维护上有诸多限制和不 ...

  2. 使用Underscore.js的template将Backbone.js的js代码和html代码分离

    这段时间在学习Require.js和Backbone.js的过程中,发现有些项目里的HTML代码都是写在View的js代码里面的,渲染的时候需要对Collection进行循环,再将HTML代码拼接上去 ...

  3. Webpack 代码分离

    Webpack 代码分离 代码分离是 webpack 中最引人注目的特性之一. 你可以把你的代码分离到不同的 bundle 中,然后你就可以去按需加载这些文件. 总的来说, webpack 分离可以分 ...

  4. webpack代码分离 ensure 看了还不懂,你打我(转)

    webpack异步加载的原理 webpack ensure相信大家都听过.有人称它为异步加载,也有人说做代码切割,那这 个家伙到底是用来干嘛的?其实说白了,它就是把js模块给独立导出一个.js文件的, ...

  5. jenkins+jacoco+ant自动化代码和应用服务代码分离场景获取远程服务的覆盖率

    前提 自动化代码和应用服务代码分离.jenkins和tomcat服务器分离 思想 1.在tomcat启动javaagent监听. 2.运用其他job_B已部署的应用服务代码 3.拉取自动化代码,开始测 ...

  6. react-router之代码分离

    概念 无需用户下载整个应用之后才能访问访问它.即边访问边下载.因此我们设计一个组件<Bundle>当用户导航到它是来动态加载组件. import loadSomething from 'b ...

  7. 史上最全的CSS hack方式一览 jQuery 图片轮播的代码分离 JQuery中的动画 C#中Trim()、TrimStart()、TrimEnd()的用法 marquee 标签的使用详情 js鼠标事件 js添加遮罩层 页面上通过地址栏传值时出现乱码的两种解决方法 ref和out的区别在c#中 总结

    史上最全的CSS hack方式一览 2013年09月28日 15:57:08 阅读数:175473 做前端多年,虽然不是经常需要hack,但是我们经常会遇到各浏览器表现不一致的情况.基于此,某些情况我 ...

  8. Webpack4 splitChunks配置,代码分离逻辑

    博客不知道啥时候写的了,一直在草稿箱没写完,突然感觉今年过去大半了,又没怎么写博客.写写完,有始有终 1.代码分离升级 原来项目代码分离是通过下面的配置,基于bundle-loader插件,通过rou ...

  9. Java&Selenium自动化测试实现页面元素、页面对象及测试代码分离

    一.摘要 本篇博文将介绍自动化测试实现页面元素.页面对象及测试代码分离在自动化框架中的实现 二.解析页面元素定位信息 首先,将页面元素与实际的代码分离,首先我们将页面元素定位信息和定位表达式保存在属性 ...

随机推荐

  1. jni cocos2d-x移植到android:helloworld

    前面搭建好了android开发环境 jni开发环境,那么就来用一用目前火热的cocos2d的游戏引擎吧 所需资料: cocos2d :下载地址  http://www.oschina.net/p/co ...

  2. 利用Linq对集合元素合并、去重复处理

    本文转载:http://www.cnblogs.com/yjmyzz/archive/2012/12/18/2823170.html 今天写代码时,需要对一个数组对象中按一定规则合并.去重处理,不想再 ...

  3. Can't connect to MySQL server on localhost (10061)解决方法

    出现这种错误的原因是由于MySQL的服务被关闭的原因,重新启动一下服务就可以了,启动服务的操作如下: 右键[计算机]-[管理]

  4. 监听器 listener 样例

    1. 在web.xml 添加 <listener>    <listener-class>listener.TestListener</listener-class> ...

  5. 【Android】数据库的简单应用——升级数据库

    假如我们已经创建好了一个数据库,随着功能需求的增加,想在数据库中再添加一个表,如果直接在之前的代码中插入一个表,会发现创建表失败,这是因为该数据库已经存在.该如何解决呢? 1.卸载程序,重新编译安装. ...

  6. linux64下安装swftools

    在文档转换器中,需要在linux上安装swftools,经历了一番曲折过程终于安装成功.swftools安装包从http://www.swftools.org/download.html上面下载. 在 ...

  7. 4G上网卡NIDS拨号之Rmnet驱动

    4G上网卡一般为双对外通讯口,一个是串口.一个是USB. 但是基于串口的常用波特率为115200,速度过于底下,所以大多使用USB. 1)一般来说常用ppp拨号方式,ppp拨号方式分为应用层pppd与 ...

  8. 解决如下json格式的字符串不能使用DataContractJsonSerializer序列化和反序列化 分类: JSON 2015-01-28 14:26 72人阅读 评论(0) 收藏

    可以解决如下json格式的字符串不能使用DataContractJsonSerializer反序列化 {     "ss": "sss",     " ...

  9. c#中var关键字用法

    Technorati 标签: C# 转载自csdn:http://blog.csdn.net/robingaoxb/article/details/6175533   var关键字是C# 3.0开始新 ...

  10. c语言_链表实例讲解(两个经典例子)

    建立一个学生成绩的线性链表,对其实现插入,删除,输出,最后销毁. demo1 // lianbiao.cpp : Defines the entry point for the console app ...