«
创造世界上最简单的 PHP 开发模式(2)

时间:2008-5-31    作者:Deri    分类: 分享


    <p>  <a href="http://file.ddvip.com/2006_04/1144467305_ddvip_4307.rar">本文示例源代码或素材下载</a></p>

   <p>  七:文章列表察看页面实现和模板处理(万里长征的最后一步)</p><p>  先来看看页面list1的实现,在list1里面分页用了一个page.js文件,这个文件是自己给自己写的一个js分页的函数,挺好用的</p><p>  <code>---------------page.js---------------<br />//--------共 20 条记录,当前 86/99 页 [1]... [82] [83] [84] [85] [86] [87] [88] [89] [90] ...[99] GO-------------------<br />//recordCount = 20;<br />//show = 20<br />//pageShow = 11;<br />//pageCount = 100;<br />//pageNow = 86;<br />//pageStr = "?page=_page_";<br />//document.write(showListPage(recordCount, show, pageCount, pageNow, pageStr));<br />function showListPage(recordCount, show, pageShow, pageCount, pageNow, pageStr){<br />  
    if(pageCount<1) pageCount =0;<br />  
    if(pageNow<1) pageNow = 0;<br />  
    str = '共 <B>'+recordCount+'</B> 条记录,当前 <B>'+pageNow+'/'+pageCount+'</B> 页 ';<br />if(pageCount<=pageShow){<br />    
      startHave = false;<br />    
      endHave = false;<br />    
      startNum = 1;<br />    
      endNum = pageCount;<br />  
      } else if(pageNow-1 <= pageShow/2){<br />    
      startHave = false;<br />    
      endHave = true;<br />    
      startNum = 1;<br />    
      endNum = pageShow-1;<br />  
      } else if(pageCount-pageNow <= pageShow/2){<br />    
      startHave = true;<br />    
      endHave = false;<br />    
      startNum = pageCount - pageShow + 2;<br />    
      endNum = pageCount;<br />  
      } else {<br />    
      startHave = true;<br />    
      endHave = true;<br />    
      startNum = pageNow - Math.floor((pageShow-2)/2);<br />    
      endNum = startNum + pageShow - 3;<br />  
      }<br />if(startHave){<br />    
        startStr = " [<A href='"+pageStr.replace("_page_",1)+"'>1</A>]... ";<br />    
        str += startStr;<br />  
        }<br />for(i=startNum; i<=endNum; i++){<br />    
          if(pageNow==i)<br />    
          str += "[" + i + "]";<br />    
          else<br />    
          str += " [<A href='" + pageStr.replace("_page_",i) + "'>" + i + "</A>] ";<br />  
          }<br />if(endHave){<br />    
            endStr = " ...[<A href='" + pageStr.replace("_page_",pageCount) + "'>" + pageCount + "</A>] ";<br />    
            str += endStr;<br />  
            }<br />  
            return str;<br />}</code></p>
<p> </p>

          <p>  <code>--------------list1.htm----------------<br /><a href="new.php">添加新文章</a><hr><br /><table><br /><tr><th>php开发文章</th></tr><br /><!-- BEGIN phplist --><br /><tr><td>{id}--<a href="view.php?id={id}">{title}</a></td></tr><br /><!-- END phplist --><br /></table><br /><!-- BEGIN phplist_page --><br /><script src="page.js" language="javascript"></script><br /><script language="javascript"><br />recordCount = {recordCount}; //总记录数<br />show = {pageSize}; //每页显示的记录数量<br />pageShow = 10; //每页显示的分页连接数量<br />pageCount = {pageCount}; //总页数<br />pageNow = {page}; //当前页数<br />pageStr = "?page=_page_"; //页面连接<br />document.write(showListPage(recordCount, show, pageShow, pageCount, pageNow, pageStr));<br /></script><br /><!-- END phplist_page --><br /><hr><br /><table ID="Table1"><br /><tr><th>php开发热点文章</th></tr><br /><!-- BEGIN phphotlist --><br /><tr><td>{id}--<a href="view.php?id={id}">{title}</a></td></tr><br /><!-- END phphotlist --><br /></table><hr><br /><table ID="Table2"><br /><tr><th>asp开发最新文章</th></tr><br /><!-- BEGIN aspnewlist --><br /><tr><td>{id}--<a href="view.php?id={id}">{title}</a></td></tr><br /><!-- END aspnewlist --><br /></table></code></p>
 <p> </p>

    <p>  <code>--------------list1.php----------------<br /><?php<br />require_once "config.inc.php";<br />dbConnect();<br />$data = array();<br />$data[phplist] = getArticleList(1, "id DESC", (int)$_GET[page], 5);<br />$data[phphotlist] = getArticleList(1, "clicks DESC, id DESC", 1, 3);<br />$data[aspnewlist] = getArticleList(2, "id DESC", 1, 3);<br />dbDisconnect();<br />renderTpl('list1.htm', $data);<br />?></code></p><p>  运行的效果怎么样,是不是实现了要求的功能呢。现在我们再做一下改动,在里面加上“asp开发热点文章列表”,实现代码如下</p><p>  <code>--------------list1.htm----------------<br /><a href="new.php">添加新文章</a><hr><br /><table><br /><tr><th>php开发文章</th></tr><br /><!-- BEGIN phplist --><br /><tr><td>{id}--<a href="view.php?id={id}">{title}</a></td></tr><br /><!-- END phplist --><br /></table><br /><!-- BEGIN phplist_page --><br /><script src="page.js" language="javascript"></script><br /><script language="javascript"><br />recordCount = {recordCount}; //总记录数<br />show = {pageSize}; //每页显示的记录数量<br />pageShow = 10; //每页显示的分页连接数量<br />pageCount = {pageCount}; //总页数<br />pageNow = {page}; //当前页数<br />pageStr = "?page=_page_"; //页面连接<br />document.write(showListPage(recordCount, show, pageShow, pageCount, pageNow, pageStr));<br /></script><br /><!-- END phplist_page --><br /><hr><br /><table ID="Table1"><br /><tr><th>php开发热点文章</th></tr><br /><!-- BEGIN phphotlist --><br /><tr><td>{id}--<a href="view.php?id={id}">{title}</a></td></tr><br /><!-- END phphotlist --><br /></table><hr><br /><table ID="Table2"><br /><tr><th>asp开发最新文章</th></tr><br /><!-- BEGIN aspnewlist --><br /><tr><td>{id}--<a href="view.php?id={id}">{title}</a></td></tr><br /><!-- END aspnewlist --><br /></table><br /><table ID="Table3"><br /><tr><th>asp热点文章</th></tr><br /><!-- BEGIN asphotlist --><br /><tr><td>{id}--<a href="view.php?id={id}">{title}</a></td></tr><br /><!-- END asphotlist --><br /></table></code></p>
 <p> </p>

    <p>  <code>--------------list1.php----------------<br /><?php<br />require_once "config.inc.php";<br />dbConnect();<br />$data = array();<br />$data[phplist] = getArticleList(1, "id DESC", (int)$_GET[page], 5);<br />$data[phphotlist] = getArticleList(1, "clicks DESC, id DESC", 1, 3);<br />$data[aspnewlist] = getArticleList(2, "id DESC", 1, 3);<br />$data[asphotlist] = getArticleList(2, "clicks DESC, id DESC", 1, 3);<br />dbDisconnect();<br />renderTpl('list1.htm', $data);<br />?></code> </p>
    <p>  仔细观察一下前后的区别,list1.php里面只是简单的加入了一行的代码,就实现这个改动,感觉怎么样啊?是不是超级简单。</p><p>  其实这种设计模式的好处还不只是这点:</p><p>  1、可以把程序的核心代码隔离开管理,便于以后程序的管理维护</p><p>  2、对于程序的可扩展性也很好,假设list1.php中要加入产品列表,我是不是也可以这么做呢?把对产品的管理也写成统一的数据库操作接口,然后简单的修改模板文件加入产品列表部分,最后在list1.php中加入一行函数调用的代码,就可以实现。</p><p>  3、代码复用,如果您是做中小型企业网站的,那这么做对您的好处是最大的,因为这种类型的网站的设计结构几乎是一样的,您可能只需要更改一下模板的样式,就可以赚到钞票了。</p><p>  这么看来这种模式是不是给您带来了很多的好处呢?</p><p>  <code>-----------lsit2.htm---------------<br /><a href="new.php">添加新文章</a><hr><br /><table ID="Table1"><br /><tr><th>asp开发文章</th></tr><br /><!-- BEGIN asplist --><br /><tr><td>{id}--<a href="view.php?id={id}">{title}</a></td></tr><br /><!-- END asplist --><br /></table><br /><!-- BEGIN asplist_page --><br /><script src="page.js" language="javascript"></script><br /><script language="javascript"><br />recordCount = {recordCount}; //总记录数<br />show = {pageSize}; //每页显示的记录数量<br />pageShow = 10; //每页显示的分页连接数量<br />pageCount = {pageCount}; //总页数<br />pageNow = {page}; //当前页数<br />pageStr = "?page=_page_"; //页面连接<br />document.write(showListPage(recordCount, show, pageShow, pageCount, pageNow, pageStr));<br /></script><br /><!-- END asplist_page --><br /><hr><br /><table ID="Table4"><br /><tr><th>asp热点文章</th></tr><br /><!-- BEGIN asphotlist --><br /><tr><td>{id}--<a href="view.php?id={id}">{title}</a></td></tr><br /><!-- END asphotlist --><br /></table></code></p>
 <p> </p>

    <p>  <code>-----------lsit2.php---------------<br /><?php<br />require_once "config.inc.php";<br />dbConnect();<br />$data = array();<br />$data[asplist] = getArticleList(2, "id DESC", (int)$_GET[page], 5);<br />$data[asphotlist] = getArticleList(2, "clicks DESC, id DESC", 1, 3);<br />dbDisconnect();<br />renderTpl('list2.htm', $data);<br />?></code></p><p>  <code>--------view.htm--------------<br /><!-- BEGIN content --><br />编号:{id}<br>标题:{title}<br>内容:{content}<br /><!-- END content --></code></p>
    <p>  <code>--------view.php------------------<br /><?php<br />require_once "config.inc.php";<br />dbConnect();<br />$data = array();<br />$data[content] = getArticle((int)$_GET[id]);<br />dbDisconnect();<br />renderTpl('view.htm', $data);<br />?></code></p>
    <p>  八:文章添加实现和模板处理(万里长征的再来一步)</p><p>  <code>---------------new.htm-----------<br /><form action="add.php" method="post"><br />标题:<input type="text" size="20"><br><br />内容:<textarea cols="50" rows="4"></textarea><br><br />&nbsp;&nbsp;&nbsp;&nbsp;<input type="submit" value="提交"><br /></form></code></p>
    <p>  <code>---------------new.php------------<br /><?php<br />require_once "config.inc.php";<br />renderTpl('new.htm', array());<br />?></code></p>
 <p> </p>

   <p>  <code>---------------CoreUtil.php--------------<br /><?php<br />function doPostVar(&$data){<br />  
    $keys = array_keys($data);<br />  
    foreach($keys as $key){<br />    
    $data[$key] = addslashes(htmlspecialchars(trim($data[$key])));<br />    
    if($data[$key]==null) $data[$key] = "$key default";<br />  
    }<br />}<br />?></code> </p>
    <p>  <code>---------------add.htm------------<br /><!-- BEGIN success --><br />{content}<br /><!-- END success --></code></p>
    <p>  <code>---------------add.php------------<br /><?php<br />require_once "config.inc.php";<br />dbConnect();<br />$data = action();<br />doPostVar($data);<br />addArticle($data);<br />$result[success][content] = "文章添加成功";<br />dbDisconnect();<br />renderTpl('add.htm', $result);<br />function action(){<br />  
      $data = array();<br />  
      $data[title] = $_POST[title];<br />  
      $data[content] = $_POST[content];<br />  
      $data[datetime] = date('Y-m-d H:i:s');<br />  
      $data[pid] = 1;<br />  
      return $data;<br />}<br />?></code></p><p>  这样一个最最简单的文章的发布系统就完成了,不知道对您有什么收获没有。</p><p>  九、总结</p><p>  程序写完了,大家来总结一下吧,看看实现过程,应该可以说是简单明了吧。</p><p>  1、统一实现数据库访问接口。更改后台数据库结构的时候,只要简单的修改相应的接口函数,其他部分的php代码根本就不用理会。</p>
 <p> </p>

   <p>  2、整个系统php代码和html代码分开管理,php代码前台实现起来也很简单,你也应该已经可以发现了,基本上是在10行代码左右。</p><p>  3、可以任意的扩充功能。用函数对新的功能进行包装后,在具体的前台的查询显示页面中只有加入对相应的函数的简单的调用就可以了,一行代码就搞定了。</p><p>  4、代码复用。通过对功能的包装,减少了大量的不必要的重复代码工作,效率应该是提高了很多吧?</p><p>  5、可以移植性。如果将来做其他的网站,要是遇到了和这个项目相同的实现功能,你可以怎么做呢?把这里的函数和数据库结构copy过去,修改一下新项目的模板,是不是就可一完成这个新的项目了呢?根本就不用考虑修改php代码。</p><p>  6、结构代码清晰。别人可以轻易的和你共同开发一个项目,代码冲突也会减少至最低。</p><p>  当然实际工作中遇到的情况可能比这个例子复杂的多,但是再复杂的任务都是可以拆分的。</p><p>  十、后言</p><p>  不知道大家有没有学过jsp和servlet这样的东西,他们有很多优秀的设计思路,值得我们去研究和copy(说句实在话,有时间的都应该去接触一下java,不是为了学习这门语言而学习,是要学习他的设计模式和优秀的功能实现方式)。jsp至少有两样东西对我们很有用,action和filter。</p><p>  action是主要是处理一些事件逻辑,就像add.php中我们定义的action()函数一样,用来验证和获取表单提交上来的数据。当然这样写的代码量和你以前方法的代码量是一样的,好像没有什么区别,但是它实现了代码的分离,结构是不是比你以前的方法清晰很多呢?</p><p>  filter是一个过滤功能,用来过滤和重新定向网络的访问,对一些非法的请求和错误的请求进行重新的定向。让我们来通过一个后台管理的程序来看看他具体的作用。</p>
 <p> </p>

   <p>  将下面的这个函数copy到你的CoreUtil.php里面,这个函数是一个后台管理登陆的过滤函数,一个是不在本地缓存web页面的函数:</p><p>  <code>function windowNoCache($cache){<br />  
        if(!$cache || headers_sent()) return ;<br />  
        header('Expires: '.date('D,d M Y H:i:s',mktime(0,0,0,1,1,2000)).' GMT');<br />  
        header('Last-Modified:'.gmdate('D,d M Y H:i:s').' GMT');<br />  
        header('Cache-control: private, no-cache,must-revalidate');<br />  
        header('Pragma: no-cache');<br />}<br />function isAdminLogin(){<br />  
        if($_SESSION[relogin]=="ok") return;<br />  
        if($_SESSION[adminuser]!=SYS_ADMIN_NAME){<br />    
        $_SESSION[relogin] = "ok";<br />    
        die("<script language=\"javascript\"> top.location='adminlogin.php'; </script>");<br />  
        }<br />  
        $_SESSION[relogin] = "no";<br />}</code></p><p>  然后在 根目录 底下加上如下的文件</p><p>  <code>------------adminconfig.inc.php------------<br /><?php<br />define('SYS_ADMIN_NAME', 'hello'); //后台管理登陆名<br />define('SYS_ADMIN_PASSWORD', 'hello'); //后台管理登陆密码<br />include 'config.inc.php';<br />windowNoCache(true);<br />isAdminLogin();<br />?></code></p>
 <p> </p>

      <p>  <code>------------adminindex.php----------------<br /><?php<br />require_once "adminconfig.inc.php";<br />renderTpl('adminindex.htm', array());<br />?></code></p><p>  <code>------------adminlogin.php------------------<br /><?php<br />include "adminconfig.inc.php";<br />if($_POST[name]==SYS_ADMIN_NAME && $_POST[code]==SYS_ADMIN_PASSWORD){<br />  
      $_SESSION[adminuser] = SYS_ADMIN_NAME;<br />  
      header("location: adminindex.php");<br />}else{<br />  
      renderTpl('adminlogin.htm', array());<br />}<br />?></code> </p>
      <p>  在 smart/template 目录下面加上如下的文件</p><p>  <code>------------adminlogin.htm------------------<br /><form name="form1" method="post" action=""><br /><input type="text" name="name" size="20" value=""><br /><input type="password" name="code" size="20" value=""><br /><input type="submit" name="Submit" value=" 登 陆 "><br /></form></code></p>
      <p>  <code>------------adminindex.htm----------------<br /><h2>您好欢迎登陆后台管理</h2></code></p>
      <p>  现在访问adminindex.php看看会发生什么事情,然后用adminconfig.inc.php里面设定的用户名密码登陆。这种功能在web的很多地方都可以派上用场,应该是一个好的方法吧。其他的后台访问的页面只要也都加载了adminconfig.inc.php ,就不用再考虑后台访问权限的问题了。</p></p><p>  十一 附录</p><p>  简单的隐藏文件的扩展名,搞晕浏览者,让他不知道你是用什么语言编的程序。</p><p>  就以list1.php为例子吧,</p><p>  1、我们修改list1.php的名称为list1.tmp</p><p>  2、进入命令行窗口(dos窗口),在web的目录下面建立一个文件,文件名是“.htaccess”。</p><p>  3、编辑“.htaccess”文件,输入以下的内容</p><p>  AddType application/x-httpd-php .tmp</p><p>  通过浏览器访问list1.tmp,看看是不是ok了。</p></p>