对于系统的n层结构:(PHP)一般来说比较常见的是三层和四层结构,说一下我对四层结构的理解吧,因为我从来都是这样用的~~最底层,一般来说是数据库,我称之为数据层或信息层,这层没什么好说的吧上一层,放置的是描述类,在EJB里称为EntityBean(实体Bean),这是直接跟数据库打交道的一层,这就不像EJB了,不过也可以做一个数据库操作类(以下简称db.inc),这一层只跟db.inc打交道,也就是不写SQL语句,所有的SQL语句,也就是跟数据库直接打交道的地方都在db.inc中。再上层,放置的是控制类,在EJB里称为SessionBean(此Session非彼Session哈),感觉并不完全一样,但是差不太多。控制类的作用顾名思义了,即是用特定的方式(除了add/update/delete/SetData)来操作某个描述类,所以实际上它很有可能就只是一个函数库。比如我有个用户的描述类user.inc(不用解释这个是什么吧),我又有个用户的控制类user_control.inc,在该控制类中,我很有可能就有这么一个function:GetUserIDByAge($Age),这个函数的功能一看也就明白,把年龄是$Age的用户的ID查询出来,一般是作为一个数组返回,里面包含的就是年龄是$Age的所有用户的UserID,当然得到了UserID自然也就得到了该用户的一切数据(SetData())。最上层,也就是浏览者看见的一层,我称之为表现层,这层自然就有很多的HTML代码了,当然也内嵌了不少php代码,不用说也应该想到大多都是new一个实例,然后调用它的某个方法来达到某个目的了。“数据库主动关闭”?你是指什么?自动关闭数据库连接?这个要看你是用什么数据库了。失败处理?PHP不是JAVA,没有try catch finally的,最多就是靠函数的返回值来判断某个操作是否成功完成。

解决方案 »

  1.   

    提议很好,大家共同努力吧。我就在试呀。看看我的贴:
    http://www.csdn.net/expert/topic/413/413967.shtm
      

  2.   

    说的好
    可能我没有描述清楚
    因为任何一个数据操作都有可能不成功?
    在php里也应该有try catch finally之类的东西吧用吗?
    数据库主动关比如是mysql
    我在数据执行完后mysql_close上面的四层结构还是不懂
    描述好象都是java数据层就是数据库(可能理解错了)
    上一层:数据操作类(不写sql,sql是再上一层传递过来的吗?)
    再上一层:控制类(除了add/update/delete/SetData)( sql语句从哪里传递过来?)
            有没有个例子简单的留言本也可以(分层)
      

  3.   

    我是的确没有听说过php有异常处理呀~~~但是大多数关系到数据处理,特别是数据库的函数~~~它都会在操作失败的时候返回false的。只要你不用pconnect,服务器会在状态终止的时候,同时终止你连接数据库使用的进程。不是在描述java呀~~我只是在拿java做比较~~~如果你明白java的话,准确的说是ejb,那就一目了然了嘛~~数据层在绝大多数情况下都是数据库,因为大多数网站的程序都是使用数据库的嘛~~~但是也不排除有文本驱动的程序啊~~~它的所有数据都保存在服务器端的某个文件夹中的n多文件中~~~还有~~逗号分隔文件(*.csv)就是最简单的数据库呀~~~:)是这样,数据库操作类中间是没有sql语句的,他会有一个query($sql)方法。而描述类里面的每个方法都会有sql语句,但是你可以不使用php自带的数据库操作函数库来向数据库提交这些sql语句,而是通过你的db.inc的query($sql)方法,这样做的原因是可重用性和可维护性高。因为你想,要是哪天你们老板赶时髦,明明就一留言板,但非要让你用oracle,你是希望只把db.inc里的query($sql)方法改成oracle的那一套函数呢?还是希望把你做的程序挨着翻一遍,看到有mysql_query($sql)的地方通通改一遍呢?控制类是一样的,每个方法也都有自己的sql语句,也是用db.inc来提交查询。而在最外层,比如你说的留言本吧,首页上自然要show全部的主题(暂不考虑分页的问题),这样在你的MessageControl.inc中,自然就应该有个GetAllMessageID(),他返回一个包含所有留言ID的array,然后你自然要对这个array的长度进行循环,循环内获取当前索引指向的某一个ID,然后靠这个ID和你的描述类来获取这个ID对应的其他数据(Message->SetData())不知道我有没有讲得够明白了~~:P
      

  4.   

    有点明白了我不是php有异常处理而是想知道php是否需要类是于java的异常处理(java不懂ejb只听过)
    因为有时候得保证程序相对的稳定可能是没的看明白(上面说了所有还不能一目了然)数据操作类就是用方法来传递sql是这样吧(不知道用不传递来描述是否正确)在哪有程序层次分的比较明显的php程序
    想看一下刚才看了一下这是帖子题目是编码规范(可能题目没有想清楚)
      

  5.   

    这篇帖子的名称好象应该是关于php的多层结构设计~~:)我觉得自己封装php的异常处理类不是很现实,它不像java,每个操作都会抛出一个专门(至少是相对专门)的Exception,比如数据库的操作失败就肯定有个SQLException被抛出来,你可以用catch (SQLException e)来获取这个异常对象,当然既然是对象,就可以用e.getMessage()之类的方法来获取详细的异常(出错)信息~~~怎么尽在说java~~~分特~~~php中~~通通抛一个boolean出来~~~怎么做??我贴一个我自己做着玩的吧~~<?
    //数据库操作类 网上到处有下
    class DBOperate { 
    var $Host = "localhost"; 
    var $Database = "glasscity"; 
    var $User = "root"; 
    var $Password = ""; var $Link_ID = 0; 
    var $Query_ID = 0; 
    var $Record = array(); 
    var $Row; 
    var $obj;var $Errno = 0; 
    var $Error = ""; var $Auto_free = 0; ## Set this to 1 for automatic mysql_free_result() 
    var $Auto_commit = 0; ## set this to 1 to automatically commit results var $debugmode = 0;function DBOperate()
    {
    $this->connect();
    }function connect() { 
    if ( 0 == $this->Link_ID ) { 
    $this->Link_ID=mysql_pconnect($this->Host, $this->User, $this->Password); 
    if (!$this->Link_ID) { 
    $this->halt("Link-ID == false, pconnect failed"); 

    if (!mysql_query(sprintf("use %s",$this->Database),$this->Link_ID)) { 
    $this->halt("cannot use database ".$this->Database); 


    } function query($Query_String) { 
    $this->connect(); if ($this->debugmode) 
    printf("Debug: query = %s<br>\n", $Query_String); $this->Query_ID = mysql_query($Query_String,$this->Link_ID); 
    $this->Row = 0; 
    $this->Errno = mysql_errno(); 
    $this->Error = mysql_error(); 
    if (!$this->Query_ID) { 
    $this->halt("Invalid SQL: ".$Query_String); 
    } return $this->Query_ID; 
    } function FetchObject($result='$this->Query_ID'){
    $this->obj = mysql_fetch_object($result);
    }function next_record() { 
    $this->Record = mysql_fetch_array($this->Query_ID); 
    $this->Row += 1; 
    $this->Errno = mysql_errno(); 
    $this->Error = mysql_error(); $stat = is_array($this->Record); 
    if (!$stat && $this->Auto_free) { 
    mysql_free_result($this->Query_ID); 
    $this->Query_ID = 0; 

    return $this->Record; 
    } function seek($pos) { 
    $status = mysql_data_seek($this->Query_ID, $pos); 
    if ($status) 
    $this->Row = $pos; 
    return; 
    } function metadata($table) { 
    $count = 0; 
    $id = 0; 
    $res = array(); $this->connect(); 
    $id = @mysql_list_fields($this->Database, $table); 
    if ($id < 0) { 
    $this->Errno = mysql_errno(); 
    $this->Error = mysql_error(); 
    $this->halt("Metadata query failed."); 

    $count = mysql_num_fields($id); for ($i=0; $i<$count; $i++) { 
    $res[$i]["table"] = mysql_field_table ($id, $i); 
    $res[$i]["name"] = mysql_field_name ($id, $i); 
    $res[$i]["type"] = mysql_field_type ($id, $i); 
    $res[$i]["len"] = mysql_field_len ($id, $i); 
    $res[$i]["flags"] = mysql_field_flags ($id, $i); 
    $res["meta"][$res[$i]["name"]] = $i; 
    $res["num_fields"]= $count; 
    } mysql_free_result($id); 
    return $res; 
    } function affected_rows() { 
    return mysql_affected_rows($this->Link_ID); 
    } function num_rows() { 
    return mysql_num_rows($this->Query_ID); 
    } function num_fields() { 
    return mysql_num_fields($this->Query_ID); 
    } function nf() { 
    return $this->num_rows(); 
    } function np() { 
    print $this->num_rows(); 
    } function f($Name) { 
    return $this->Record[$Name]; 
    } function p($Name) { 
    print $this->Record[$Name]; 
    } function halt($msg) { 
    printf("</td></tr></table><b>Database error:</b> %s<br>\n", $msg); 
    printf("<b>MySQL Error</b>: %s (%s)<br>\n", 
    $this->Errno, 
    $this->Error); 
    die("Session halted."); 

    } class SQL extends DBOperate { 
    var $Host = "localhost"; 
    var $Database = ""; 
    var $User = ""; 
    var $Password = ""; function free_result() { 
    return @mysql_free_result($this->Query_ID); 
    } function rollback() { 
    return 1; 
    } function commit() { 
    return 1; 
    } function autocommit($onezero) { 
    return 1; 
    } function insert_id($col="",$tbl="",$qual="") { 
    return mysql_insert_id($this->Query_ID); 


    ?> <?
    //用户描述类 可以看出库结构吧
    class user
    {
    var $UserID;
    var $Password;
    var $PassQue;
    var $PassAns;
    var $NickName;
    var $Sex;
    var $Email;
    var $MarriageState;
    var $Birthday;
    var $Country;
    var $Province;
    var $Phone;
    var $Mobile;
    var $Address;
    var $PostCode;
    var $Work;
    var $Craft;
    var $IncomingLevel;
    var $Knowledge;
    var $NetPlace;
    var $HowToKnow;
    var $Interesting;
    var $Identity;
    var $HopeBlaze;
    var $TableName; function user()
    {
    $this->TableName = "user";
    } function Add()
    {
    $link = new DBOperate;
    $sql = "insert into ".$this->TableName." values (";
    $sql .="'',";
    $sql .="'".$this->Password."',";
    $sql .="'".$this->PassQue."',";
    $sql .="'".$this->PassAns."',";
    $sql .="'".$this->NickName."',";
    $sql .="'".$this->Sex."',";
    $sql .="'".$this->Email."',";
    $sql .="'".$this->MarriageState."',";
    $sql .="'".$this->Birthday."',";
    $sql .="'".$this->Country."',";
    $sql .="'".$this->Province."',";
    $sql .="'".$this->Phone."',";
    $sql .="'".$this->Mobile."',";
    $sql .="'".$this->Address."',";
    $sql .="'".$this->PostCode."',";
    $sql .="'".$this->Work."',";
    $sql .="'".$this->Craft."',";
    $sql .="'".$this->IncomingLevel."',";
    $sql .="'".$this->Knowledge."',";
    $sql .="'".$this->NetPlace."',";
    $sql .="'".$this->HowToKnow."',";
    $sql .="'".$this->Interesting."',";
    $sql .="'".$this->Identity."',";
    $sql .="'".$this->HopeBlaze."')";
    $link->query($sql);
    } function SetData($UserID)
    {
    $link = new DBOperate;
    $sql = "select * from user where UserID = '".$UserID."'";
    $link->query($sql);
    $User = $link->next_record(); $this->UserID = $User["UserID"];
    $this->Password = $User["Password"];
    $this->PassQue = $User["PassQue"];
    $this->PassAns = $User["PassAns"];
    $this->NickName = $User["NickName"];
    $this->Sex = $User["Sex"];
    $this->Email = $User["Email"];
    $this->MarriageState = $User["MarriageState"];
    $this->Birthday = $User["Birthday"];
    $this->Country = $User["Country"];
    $this->Province = $User["Province"];
    $this->Phone = $User["Phone"];
    $this->Mobile = $User["Mobile"];
    $this->Address = $User["Address"];
    $this->PostCode = $User["PostCode"];
    $this->Work = $User["Work"];
    $this->Craft = $User["Craft"];
    $this->IncomingLevel = $User["IncomingLevel"];
    $this->Knowledge = $User["Knowledge"];
    $this->NetPlace = $User["NetPlace"];
    $this->HowToKnow = $User["HowToKnow"];
    $this->Interesting = $User["Interesting"];
    $this->Identity = $User["Identity"];
    $this->HopeBlaze = $User["HopeBlaze"];
    }
    ?><?
    //用户控制类 省略了不少 不过一个你就应该看得明白是怎么用的
    function GetUserIDByProvince($Province)
    {
    $link = new DBOperate;
    $result = array(); $sql = "select ID from ". $this->TableName ." where Province = '".$Province."'";
    $link->query($sql);
    for ($i=0;$i<$link->num_rows();$i++)
    {
    $Goods = $link->next_record();
    $result[] = $Goods["ID"];
    }
    return $result;
    }
    ?>
      

  6.   

    在PHP中应该说只是很肤浅的应用吧`~
      

  7.   

    可能
    php中分的太不明显了
    java中好象明显点
    加分了