五、制作功能接口(1)首先对mysql数据库函数进行包装,简化对数据库操作,网上有很多这样的开源的类。但是这里我个人根据自己的需求和习惯,自己对mysql的函数进行了包装,写得好坏就先不管了。这个地方简单的看一下就可以了,不同的包装的类操作是不同的,而且这里的主要目的是理解这套“架构”,不用太扣代码。-------MysqlUtil.php--------
<?phpfunction dbConnect(){
global $cnn;
$cnn = (DB_PCONNECT? mysql_pconnect(DB_HOST, DB_NAME, DB_PASSWORD):
mysql_connect(DB_HOST, DB_NAME, DB_PASSWORD)) or
die('数据库连接错误');
mysql_select_db(DB_NAME, $cnn) or die('数据库选择错误');
mysql_query("SET AUTOCOMMIT=1");
}function &dbQuery($sql){
global $cnn;
$rs = &mysql_query($sql, $cnn);
while($item=mysql_fetch_assoc($rs)){
$data[] = $item;
}
return $data;
}function &dbGetRow($sql){
global $cnn;
$rs = mysql_query($sql) or die('sql语句执行错误');
if(mysql_num_rows($rs)>0)
return mysql_fetch_assoc($rs);
else
return null;
}function dbGetOne($sql, $fildName){
$rs = dbGetRow($sql);
return sizeof($rs)==null? null: (isset($rs[$fildName])? $rs[$fildName]: null);
}function &dbPageQuery($sql, $page=1, $pageSize=20){
if($page===null) return dbQuery($sql);
$countSql = preg_replace('|SELECT.*FROM|i','SELECT COUNT(*) count FROM', $sql);
$n = (int)dbGetOne($countSql, 'count');
$data['pageSize'] = (int)$pageSize<1? 20: (int)$pageSize;
$data['recordCount'] = $n;
$data['pageCount'] = ceil($data['recordCount']/$data['pageSize']);
$data['page'] = $data['pageCount']==0? 0: ((int)$page<1? 1: (int)$page);
$data['page'] = $data['page']>$data['pageCount']? $data['pageCount']:$data['page'];
$data['isFirst'] = $data['page']>1? false: true;
$data['isLast'] = $data['page']<$data['pageCount']? false: true;
$data['start'] = ($data['page']==0)? 0: ($data['page']-1)*$data['pageSize']+1;
$data['end'] = ($data['start']+$data['pageSize']-1);
$data['end'] = $data['end']>$data['recordCount']? $data['recordCount']: $data['end'];
$data['sql'] = $sql.' LIMIT '.($data['start']-1).','.$data['pageSize'];
$data['data'] = &dbQuery($data['sql']);
return $data;
}function dbExecute($sql){
global $cnn;
mysql_query($sql, $cnn) or die('sql语句执行错误');
return mysql_affected_rows($cnn);
}function dbDisconnect(){
global $cnn;
mysql_close($cnn);
}function sqlGetOneById($table, $field, $id){
return "SELECT * FROM $table WHERE $field=$id";
}function sqlMakeInsert($table, $data){
$t1 = $t2 = array();
foreach($data as $key=>$value){
$t1[] = $key;
$t2[] = "'".addslashes($value)."'";
}
return "INSERT INTO $table (".implode(",",$t1).") VALUES(".implode(",",$t2).")";
}function sqlMakeUpdateById($table, $field, $id, $data){
$t1 = array();
foreach($data as $key=>$value){
$t1[] = "$key='".addslashes($value)."'";
}
return "UPDATE $table SET ".implode(",", $t1)." WHERE $field=$id";
}function sqlMakeDelById($table, $field, $id){
return "DELETE FROM $table WHERE $field=$id";
}?>五、制作功能接口(2)下面来正式的看看,我们共要实现的功能进行的包装------------ArticleUtil.php----------------
<?php
//显示文章列表的函数
//getArticleList(文章类别, 排序方法, 当前显示第几页, 每页显示几条)
function getArticleList($catId, $order, $page, $pageSize){
$sql = "SELECT * FROM article WHERE pid=$catId ORDER BY $order";
return dbPageQuery($sql, $page, $pageSize);
}
//查询某个文章的内容
//getArticle(文章编号)
function getArticle($id){
$sqlUpdate = "UPDATE article SET clicks=clicks+1 WHERE id=$id";
dbExecute($sqlUpdate);
$sql = "SELECT * FROM article WHERE art_id=$id";
return dbGetRow($sql);
}
//添加文章
//addArticle(文章内容数组)
function addArticle($data){
$sql = sqlMakeInsert('article', $data);
return dbExecute($sql);
}
?>这段代码是不是就简单多了啊?这就是自己对mysql函数进行包装的好处!
下面来研究一下他们是怎么实现我们的功能的呢。
“php开发文章列表”--------getArticleList(1, "id DESC", $page, 5) 
“asp开发文章列表”--------getArticleList(2, "id DESC", $page, 5)
“php开发热点文章列表”----getArticleList(1, "clicks DESC, id DESC", 1, 3)
“asp开发热点文章列表”----getArticleList(2, "clicks DESC, id DESC", 1, 3)
“asp开发最新文章”--------getArticleList(2, "id DESC", 1, 3)
“添加新文章”-------------addArticle($data)
“察看文章”---------------getArticle($id)
六、对smarttemplate类进行包装(革命尚未成功,同志仍须努力)具体的smarttemplate的使用这里就不讲了,不然口水讲没了,都讲不完。下面这个是具体的对包装函数-------------ParseTpl.php----------------
<?phpfunction renderTpl($viewFile, $data){
$page = new SmartTemplate($viewFile);
foreach($data as $key=>$value){
if(isset($value[data])){
$page->assign($key, $value[data]);
unset($value[data]);
$page->assign($key."_page", $value);
} else {
$page->assign($key, $value);
}
}
$page->output();
}?>七:文章列表察看页面实现和模板处理(万里长征的最后一步)先来看看页面list1的实现,在list1里面分页用了一个page.js文件,这个文件是自己给自己写的一个js分页的函数,挺好用的
---------------page.js---------------
//--------共 20 条记录,当前 86/99 页 [1]... [82] [83] [84] [85] [86] [87] [88] [89] [90] ...[99] GO-------------------
//recordCount = 20;
//show = 20
//pageShow = 11;
//pageCount = 100;
//pageNow = 86;
//pageStr = "?page=_page_";
//document.write(showListPage(recordCount, show, pageCount, pageNow, pageStr));
function showListPage(recordCount, show, pageShow, pageCount, pageNow, pageStr){
if(pageCount<1) pageCount =0;
if(pageNow<1) pageNow = 0;
str = '共 <B>'+recordCount+'</B> 条记录,当前 <B>'+pageNow+'/'+pageCount+'</B> 页 ';if(pageCount<=pageShow){
startHave = false;
endHave = false;
startNum = 1;
endNum = pageCount;
} else if(pageNow-1 <= pageShow/2){
startHave = false;
endHave = true;
startNum = 1;
endNum = pageShow-1;
} else if(pageCount-pageNow <= pageShow/2){
startHave = true;
endHave = false;
startNum = pageCount - pageShow + 2;
endNum = pageCount;
} else {
startHave = true;
endHave = true;
startNum = pageNow - Math.floor((pageShow-2)/2);
endNum = startNum + pageShow - 3;
}if(startHave){
startStr = " [<A href='"+pageStr.replace("_page_",1)+"'>1</A>]... ";
str += startStr;
}for(i=startNum; i<=endNum; i++){
if(pageNow==i)
str += "[" + i + "]";
else
str += " [<A href='" + pageStr.replace("_page_",i) + "'>" + i + "</A>] ";
}if(endHave){
endStr = " ...[<A href='" + pageStr.replace("_page_",pageCount) + "'>" + pageCount + "</A>] ";
str += endStr;
}
return str;
}
--------------list1.htm----------------
<a href="new.php">添加新文章</a><hr>
<table>
<tr><th>php开发文章</th></tr>
<!-- BEGIN phplist -->
<tr><td>{id}--<a href="view.php?id={id}">{title}</a></td></tr>
<!-- END phplist -->
</table>
<!-- BEGIN phplist_page -->
<script src="page.js" language="javascript"></script>
<script language="javascript">
recordCount = {recordCount}; //总记录数
show = {pageSize}; //每页显示的记录数量
pageShow = 10; //每页显示的分页连接数量
pageCount = {pageCount}; //总页数
pageNow = {page}; //当前页数
pageStr = "?page=_page_"; //页面连接
document.write(showListPage(recordCount, show, pageShow, pageCount, pageNow, pageStr));
</script>
<!-- END phplist_page -->
<hr>
<table ID="Table1">
<tr><th>php开发热点文章</th></tr>
<!-- BEGIN phphotlist -->
<tr><td>{id}--<a href="view.php?id={id}">{title}</a></td></tr>
<!-- END phphotlist -->
</table><hr>
<table ID="Table2">
<tr><th>asp开发最新文章</th></tr>
<!-- BEGIN aspnewlist -->
<tr><td>{id}--<a href="view.php?id={id}">{title}</a></td></tr>
<!-- END aspnewlist -->
</table>
--------------list1.php----------------
<?phprequire_once "config.inc.php";dbConnect();
$data = array();
$data[phplist] = getArticleList(1, "id DESC", (int)$_GET[page], 5);
$data[phphotlist] = getArticleList(1, "clicks DESC, id DESC", 1, 3);
$data[aspnewlist] = getArticleList(2, "id DESC", 1, 3);
dbDisconnect();renderTpl('list1.htm', $data);?>

解决方案 »

  1.   

    运行的效果怎么样,是不是实现了要求的功能呢。现在我们再做一下改动,在里面加上“asp开发热点文章列表”,实现代码如下--------------list1.htm----------------
    <a href="new.php">添加新文章</a><hr>
    <table>
    <tr><th>php开发文章</th></tr>
    <!-- BEGIN phplist -->
    <tr><td>{id}--<a href="view.php?id={id}">{title}</a></td></tr>
    <!-- END phplist -->
    </table>
    <!-- BEGIN phplist_page -->
    <script src="page.js" language="javascript"></script>
    <script language="javascript">
    recordCount = {recordCount}; //总记录数
    show = {pageSize}; //每页显示的记录数量
    pageShow = 10; //每页显示的分页连接数量
    pageCount = {pageCount}; //总页数
    pageNow = {page}; //当前页数
    pageStr = "?page=_page_"; //页面连接
    document.write(showListPage(recordCount, show, pageShow, pageCount, pageNow, pageStr));
    </script>
    <!-- END phplist_page -->
    <hr>
    <table ID="Table1">
    <tr><th>php开发热点文章</th></tr>
    <!-- BEGIN phphotlist -->
    <tr><td>{id}--<a href="view.php?id={id}">{title}</a></td></tr>
    <!-- END phphotlist -->
    </table><hr>
    <table ID="Table2">
    <tr><th>asp开发最新文章</th></tr>
    <!-- BEGIN aspnewlist -->
    <tr><td>{id}--<a href="view.php?id={id}">{title}</a></td></tr>
    <!-- END aspnewlist -->
    </table>
    <table ID="Table3">
    <tr><th>asp热点文章</th></tr>
    <!-- BEGIN asphotlist -->
    <tr><td>{id}--<a href="view.php?id={id}">{title}</a></td></tr>
    <!-- END asphotlist -->
    </table>
    --------------list1.php----------------
    <?phprequire_once "config.inc.php";dbConnect();
    $data = array();
    $data[phplist] = getArticleList(1, "id DESC", (int)$_GET[page], 5);
    $data[phphotlist] = getArticleList(1, "clicks DESC, id DESC", 1, 3);
    $data[aspnewlist] = getArticleList(2, "id DESC", 1, 3);
    $data[asphotlist] = getArticleList(2, "clicks DESC, id DESC", 1, 3);
    dbDisconnect();renderTpl('list1.htm', $data);?>仔细观察一下前后的区别,list1.php里面只是简单的加入了一行的代码,就实现这个改动,感觉怎么样啊?是不是超级简单。其实这种设计模式的好处还不只是这点:
    1、可以把程序的核心代码隔离开管理,便于以后程序的管理维护
    2、对于程序的可扩展性也很好,假设list1.php中要加入产品列表,我是不是也可以这么做呢?把对产品的管理也写成统一的数据库操作接口,然后简单的修改模板文件加入产品列表部分,最后在list1.php中加入一行函数调用的代码,就可以实现。
    3、代码复用,如果您是做中小型企业网站的,那这么做对您的好处是最大的,因为这种类型的网站的设计结构几乎是一样的,您可能只需要更改一下模板的样式,就可以赚到钞票了。这么看来这种模式是不是给您带来了很多的好处呢?
    -----------lsit2.htm---------------
    <a href="new.php">添加新文章</a><hr>
    <table ID="Table1">
    <tr><th>asp开发文章</th></tr>
    <!-- BEGIN asplist -->
    <tr><td>{id}--<a href="view.php?id={id}">{title}</a></td></tr>
    <!-- END asplist -->
    </table>
    <!-- BEGIN asplist_page -->
    <script src="page.js" language="javascript"></script>
    <script language="javascript">
    recordCount = {recordCount}; //总记录数
    show = {pageSize}; //每页显示的记录数量
    pageShow = 10; //每页显示的分页连接数量
    pageCount = {pageCount}; //总页数
    pageNow = {page}; //当前页数
    pageStr = "?page=_page_"; //页面连接
    document.write(showListPage(recordCount, show, pageShow, pageCount, pageNow, pageStr));
    </script>
    <!-- END asplist_page -->
    <hr>
    <table ID="Table4">
    <tr><th>asp热点文章</th></tr>
    <!-- BEGIN asphotlist -->
    <tr><td>{id}--<a href="view.php?id={id}">{title}</a></td></tr>
    <!-- END asphotlist -->
    </table>
    -----------lsit2.php---------------
    <?phprequire_once "config.inc.php";dbConnect();
    $data = array();
    $data[asplist] = getArticleList(2, "id DESC", (int)$_GET[page], 5);
    $data[asphotlist] = getArticleList(2, "clicks DESC, id DESC", 1, 3);
    dbDisconnect();renderTpl('list2.htm', $data);?>
    --------view.htm--------------
    <!-- BEGIN content -->
    编号:{id}<br>标题:{title}<br>内容:{content}
    <!-- END content -->
    --------view.php------------------
    <?phprequire_once "config.inc.php";dbConnect();
    $data = array();
    $data[content] = getArticle((int)$_GET[id]);
    dbDisconnect();renderTpl('view.htm', $data);?>八:文章添加实现和模板处理(万里长征的再来一步)---------------new.htm-----------
    <form action="add.php" method="post">
    标题:<input type="text" size="20"><br>
    内容:<textarea cols="50" rows="4"></textarea><br>
    &nbsp;&nbsp;&nbsp;&nbsp;<input type="submit" value="提交">
    </form>
    ---------------new.php------------
    <?phprequire_once "config.inc.php";renderTpl('new.htm', array());?>
    ---------------CoreUtil.php--------------
    <?phpfunction doPostVar(&$data){
    $keys = array_keys($data);
    foreach($keys as $key){
    $data[$key] = addslashes(htmlspecialchars(trim($data[$key])));
    if($data[$key]==null) $data[$key] = "$key default";
    }
    }?>
    ---------------add.htm------------
    <!-- BEGIN success -->
    {content}
    <!-- END success -->
    ---------------add.php------------
    <?phprequire_once "config.inc.php";dbConnect();
    $data = action();
    doPostVar($data);
    addArticle($data);
    $result[success][content] = "文章添加成功";
    dbDisconnect();renderTpl('add.htm', $result);function action(){
    $data = array();
    $data[title] = $_POST[title];
    $data[content] = $_POST[content];
    $data[datetime] = date('Y-m-d H:i:s');
    $data[pid] = 1;
    return $data;
    }?>
    这样一个最最简单的文章的发布系统就完成了,不知道对您有什么收获没有.
      

  2.   

    九、总结
    程序写完了,大家来总结一下吧,看看实现过程,应该可以说是简单明了吧。
    1、统一实现数据库访问接口。更改后台数据库结构的时候,只要简单的修改相应的接口函数,其他部分的php代码根本就不用理会。
    2、整个系统php代码和html代码分开管理,php代码前台实现起来也很简单,你也应该已经可以发现了,基本上是在10行代码左右。
    3、可以任意的扩充功能。用函数对新的功能进行包装后,在具体的前台的查询显示页面中只有加入对相应的函数的简单的调用就可以了,一行代码就搞定了。
    4、代码复用。通过对功能的包装,减少了大量的不必要的重复代码工作,效率应该是提高了很多吧?
    5、可以移植性。如果将来做其他的网站,要是遇到了和这个项目相同的实现功能,你可以怎么做呢?把这里的函数和数据库结构copy过去,修改一下新项目的模板,是不是就可一完成这个新的项目了呢?根本就不用考虑修改php代码。
    6、结构代码清晰。别人可以轻易的和你共同开发一个项目,代码冲突也会减少至最低。当然实际工作中遇到的情况可能比这个例子复杂的多,但是再复杂的任务都是可以拆分的。
    十、后言不知道大家有没有学过jsp和servlet这样的东西,他们有很多优秀的设计思路,值得我们去研究和copy(说句实在话,有时间的都应该去接触一下java,不是为了学习这门语言而学习,是要学习他的设计模式和优秀的功能实现方式)。jsp至少有两样东西对我们很有用,action和filter。action是主要是处理一些事件逻辑,就像add.php中我们定义的action()函数一样,用来验证和获取表单提交上来的数据。当然这样写的代码量和你以前方法的代码量是一样的,好像没有什么区别,但是它实现了代码的分离,结构是不是比你以前的方法清晰很多呢?filter是一个过滤功能,用来过滤和重新定向网络的访问,对一些非法的请求和错误的请求进行重新的定向。让我们来通过一个后台管理的程序来看看他具体的作用。
    将下面的这个函数copy到你的CoreUtil.php里面,这个函数是一个后台管理登陆的过滤函数,一个是不在本地缓存web页面的函数
    function windowNoCache($cache){
    if(!$cache || headers_sent()) return ;
    header('Expires: '.date('D,d M Y H:i:s',mktime(0,0,0,1,1,2000)).' GMT');
    header('Last-Modified:'.gmdate('D,d M Y H:i:s').' GMT');
    header('Cache-control: private, no-cache,must-revalidate');
    header('Pragma: no-cache');
    }
    function isAdminLogin(){
    if($_SESSION[relogin]=="ok") return;
    if($_SESSION[adminuser]!=SYS_ADMIN_NAME){
    $_SESSION[relogin] = "ok";
    die("<script language=\"javascript\">top.location='adminlogin.php';</script>");
    }
    $_SESSION[relogin] = "no";
    }
    然后在 根目录 底下加上如下的文件
    ------------adminconfig.inc.php------------
    <?php
    define('SYS_ADMIN_NAME', 'hello'); //后台管理登陆名
    define('SYS_ADMIN_PASSWORD', 'hello'); //后台管理登陆密码
    include 'config.inc.php';
    windowNoCache(true);
    isAdminLogin();?>
    ------------adminindex.php----------------
    <?phprequire_once "adminconfig.inc.php";renderTpl('adminindex.htm', array());?>
    ------------adminlogin.php------------------
    <?phpinclude "adminconfig.inc.php";if($_POST[name]==SYS_ADMIN_NAME && $_POST[code]==SYS_ADMIN_PASSWORD){
    $_SESSION[adminuser] = SYS_ADMIN_NAME;
    header("location: adminindex.php");
    }else{
    renderTpl('adminlogin.htm', array());
    }?>
    在 smart/template 目录下面加上如下的文件
    ------------adminlogin.htm------------------
    <form name="form1" method="post" action="">
    <input type="text" name="name" size="20" value="">
    <input type="password" name="code" size="20" value="">
    <input type="submit" name="Submit" value=" 登 陆 ">
    </form>
    ------------adminindex.htm----------------
    <h2>您好欢迎登陆后台管理</h2>现在访问adminindex.php看看会发生什么事情,然后用adminconfig.inc.php里面设定的用户名密码登陆。这种功能在web的很多地方都可以派上用场,应该是一个好的方法吧。其他的后台访问的页面只要也都加载了adminconfig.inc.php ,就不用再考虑后台访问权限的问题了。
    十一 附录简单的隐藏文件的扩展名,搞晕浏览者,让他不知道你是用什么语言编的程序。就以list1.php为例子吧,1、我们修改list1.php的名称为list1.tmp
    2、进入命令行窗口(dos窗口),在web的目录下面建立一个文件,文件名是“.htaccess”。
    3、编辑“.htaccess”文件,输入以下的内容AddType application/x-httpd-php .tmp通过浏览器访问list1.tmp,看看是不是ok了。
      

  3.   

    /*******************************************/
    来源 :   http://blog.csdn.net/hahawen/archive/2004/09/13/102557.aspx
    /*******************************************/
      

  4.   

    源码下载地址: http://club.phpe.net/index.php?s=&act=Attach&type=post&id=29432
      

  5.   

    分不多, 不想多说的,这小框架不怎么样,不过hahawen(变态的大龄青年)愿意公开整理自己的工作心得,这一点我是很佩服的,但坦白说,这个框架缺乏系统性、简洁性,熟悉php和j2ee思想模式的人会认同我的看法,如果有人说我在说空话,那骂我吧,我本意是希望看到更好的东西(php应用方面)出现。如果这里面的内容是表示了现时国内php的高级综合水平,我就既开心(从我个人工作竞争考虑)又悲伤(从国内php应用考虑)。希望hahawen(变态的大龄青年)的抛砖引玉,引起更多潜水的高人开开金口,good good study,day day up。
      

  6.   

    to :unixdotnet(concinnity) 误会了,只是给初学者看的,呵呵:>希望在刚搞php不久的同志不要走太多的弯路.上面的系统缺乏系统性,但是绝对不缺乏简洁性,再次严重声明:
    ------我的水品很一般--------
    所以"如果这里面的内容是表示了现时国内php的高级综合水平"这句话是错的,没有如果,只有不可能.呵呵.
    ------我的水品真的很一般--------不过我还是要再提一句, 我正在把我自己的架构象php5转,我自己用的架构远比这个复杂和好用多了,暂时不能公开,给你个WEB-INF/common目录看看SYS_COMMON_PATH.'BaseObject.php5'
    SYS_COMMON_PATH.'Application.php5'
    SYS_COMMON_PATH.'ClassUtil.php5'
    SYS_COMMON_PATH.'Controler.php5'
    SYS_COMMON_PATH.'FileUtil.php5'
    SYS_COMMON_PATH.'HaltUtil.php5'
    SYS_COMMON_PATH.'Manager.php5'
    SYS_COMMON_PATH.'Model.php5'
    SYS_COMMON_PATH.'Mysql.php5'
    SYS_COMMON_PATH.'Request.php5'
    SYS_COMMON_PATH.'View.php5'
    SYS_COMMON_PATH.'SqlBuilder.php5'SYS_COMMON_PATH.'ErrorObject.php5'
    SYS_COMMON_PATH.'ErrorObjects.php5'SYS_COMMON_PATH.'Action.php5'SYS_COMMON_PATH.'Filter.php5'SYS_COMMON_PATH.'Map.php5'
    SYS_COMMON_PATH.'Sitemap.php5'
    SYS_COMMON_PATH.'Blockmap.php5'
    SYS_COMMON_PATH.'Actionmap.php5'
    SYS_COMMON_PATH.'Filtermap.php5'千万别小看国内的phpers, 高手还是有的,而且我还认识几个.
      

  7.   

    To  hahawen(变态的大龄青年):也许我的认识不对,我觉得不应该提供一套完整、强大的东西给初学者,他们自己不实践后归纳总结是不可能提升的,就算框架怎么完美都会让他们知其然而不知其所以然。在上面我对简洁性的说明不清楚,其实我是指关于可代码、结构的重用性,越是精简那么它自身扩展和对其它模块的压力就越小,我真的不觉得上面的内容实现这个需求。你列出来类文件名中有些好像很有意义的,期待你开源日子的到来。
      

  8.   

    我公开一下我的目录root
       include
           common.php  一些每个页子都需处理的东东.
           ADODB 五个文件
           template.php PHPLIB 模板处理
           Common_Function.php  通用的其它函数定义   template
           Golbal.html
           Top.html
           Bottom.html
           Showmessage.html
           6s 目录   一个模块的模板
             6sList.html
             6sAddFrom.html 添加
             6sEdit.html 修改
           Order  目录 另一个模块的模板
             OrderList.html
             OrderAdd.html
             OrderEdit.html
        6s  目录 一个模块的脚本文件
          6sManage.php  里面包括了 Add Edit Delete List 各模板. switch 完成.
        Order 目录 另一个模块的脚本文件
          OrderManage.php  同6s 一样.    index.php 
        login.php
      

  9.   

    个人对于学习的心态---------------------------很久以前我很喜欢写点文字上的东西,有一阵子特喜欢写点别人看不懂的东西,
    并且鄙视一些写的很容易明白的东西.当然,现在的我已经不是这样了.之所以说上面的话,是觉得.每个人在每个特定的时间都会有特定的想法,这,
    无所谓好或者不好.重要的是,以后这段经历能不能给这个人带来帮助.对于PHP的初学者(在下自己也是初学者,而且是极菜的那种),或者说是任何
    不是在学校里能够学到的那种东西的初学者.只要是想学,并没有什么特定的
    模版.
    就拿PHP来说,好象并不存在,怎么怎么学就是正确的学习方法,怎么怎么学就
    不是正确的方法,好象到现在(我是指我个人进CSDN的PHP版开始),大家公认唯
    一相同的方法就是-----看手册,但这也是属于知易行难那种.所以,个人认为-------我觉得不应该提供一套完整、强大的东西给初学者,
    他们自己不实践后归纳总结是不可能提升的------想进步的人总是会拚命找
    方法去进步,不想进步的......打死他,他也就.....比着为个人对于 unixdotnet(concinnity) 的意见提出的一点不同的看法,
    供大家参考.
      

  10.   

    礼尚往来吧,我的框架大概结构,图片地址是:http://webmail.21cn.net:8082/tmp/ccie_gzb:21cn_net/structural.bmp
      

  11.   

    index.php内容如下:<?php
    require_once 'class/core/application.php';
    $application = new Application();
    $application->start();
    $application->process();
    $application->close();
    unset( $application );
    ?>整个框架的所有类、类方法是尽可能地独立、精简,其实就是尽可能地按着java思想、做法来搬过来用php做,可惜php缺乏太多东西了。
      

  12.   

    都是牛人,看不懂。
    我用j2ee作系统的时候,还不乱成一团,什么都没有体现出来,只知道能完成任务,然后让人知道从页面(或是客户端)到底层,那些文件是连成一条线的。
    讨论那些什么模式是你们那些强人做的,我们这些小菜菜就混混生活就行了,然后在台下努力给你们鼓掌。
      

  13.   

    feygesign 啥  赶紧帮我 Test problem
      

  14.   

    模式与我的工作模式不太一样,
    我的数据抽象层只提供了数据库的基本访问,查询.其它分页,处理数据都是放到业务层
    不过这个模式整体的思路还是很清楚的,
    关于精简我想说要想功能多就不可能精简,只能尽量在两者之间衡量一个比例.
    J2EE的模式是比较完善,思路也很清晰,用struts写一个hello,world都要N个目录和文件
    越大的系统框架结构越复杂,如果一个留言板都要一个复杂框架实现的话未免太臃肿了,
    相反如果只用基本的几个页来实现可能效果和结构会更好一些.
      

  15.   

    初学PHP,觉其简,但又不简,来此一观,果有所得...
      

  16.   

    楼上讨论的各牛人,此文最优秀的地方正是因为它被贴了出来呀。无论是引领菜鸟进级,或
    是给对牛人抛砖引玉,都很有效果啦。
     楼上的有些单贴个inc文件,又贴文件目录,或者你的框架是优秀得多,但又能怎样?不
    能带领大家共同进步。
      

  17.   

    在此引用一下haohappy的话
    PHP算是开源文化的一部份,随着Linux在中国的逐步推广和普及,我们相信PHP的发展和应用前景会越来越好。希望国内的PHP同行们多发扬无私精神,多向《PHP & More》投稿,在工作、学习之余,在百忙之中不啬和我们分享技术和经验--为什么不热情一点呢,助人助己难道不是好事吗? 看看国外开源社区的热闹,反观国内PHP技术圈子的寂寥,难免令人叹惜。只有在中国的PHP圈子中形成开放、自由、共享的氛围,大家才能共同进步,才能让PHP在更多的市场应用中发挥作用。
      

  18.   

    看了这帖感触颇深。
    我是一个php初学者(学习php还不到一个月),上面的文章还看不太懂,但让我很兴奋。
    先不谈文章会给我们这些初学者带来多大的好处(我看用照亮php黑暗之路的航灯也不为过啊.
    就谈楼主这种精神,就让我由衷的倾佩。
    这种无私的精神,让我看到了中国php的发展会越来越好。
    也让我坚定了,学好php的信心!
    我会努力的学习,学好php后向楼主一样为phper服务。
    再次,衷心的感谢楼主!
      

  19.   

    鼓励楼主
    php就是自由:)
    但是谈到模式还有点过于大的话题了 设计模式不是这么回事的吧?...
      

  20.   

    hahawen (变态的大龄青年)的经验很值得学习,因为我是业余时间写PHP,本职工作和程序不沾边,所以对设计模式了解甚少,正在看PHP-MVC,但是有好多问题,今天算是明白许多了,感谢楼主!
      

  21.   

    我来泼泼冷水吧,让大家清醒一下吧,
    在这样一个热贴就只有一个人(unixdotnet)有反对声音确实属于不正常的现象首先值得肯定是楼主的这种精神,这样的精神确实不错。
    但是需要指出的是,里面有些的东西还可以,有些东西就不怎么样了。如果说给初学者一个抛砖引玉的话,
    我想说,你的数据库操作居然都没有用 Class 来实现,都没有 OO 的影子
    这样的东西不能够称之为框架,也不能够谈得上模式。这样难免给现在的初学者,或者说某些从其他语言转过来的初学者一个模糊的开始。
      

  22.   

    to: liyujie2000(开心的鱼) 此模式,非彼模式也!oo是好东西,但是拿oo来做小应用,是大才小用 + 浪费时间。用了oo,我怕更多人看不懂
      

  23.   

    想研究框架去
    http://www.phpkitchen.com/index.php?topic=phpFrameworks
    上午大概看了一下,有几个基于OO的框架.像eocene, Yellow Duck等.
    都是open source的,下载下来研究模式还是不错的.
      

  24.   

    对没有接触smarty的初学者还是有一定帮助的