gaohan 发表于 2015-8-27 09:14:32

PHP分层架构简单示例(1.业务逻辑类)

  对于一些大型项目,分层可以分离代码关注点,可以让不同的技术人员协同开发,对代码的更改和维护也具有极大的优势,此后也可以方便的更换组件,不用推到整个项目,比如常见的更换数据库的场景。分层的项目一般多采用.NET或Java技术,而对于PHP比较少一些,可能由于PHP的大型项目偏少以及PHP一般不做后端的方向,这篇文章简单的写一个PHP分层的示例。
  定义一个最简单的业务场景,发布博客,为了简单化,我们认为博客的数据表只有主键Id、标题、内容和发布时间。对于这个数据表,我们先抽象出最简单业务逻辑类。


View Code


<?php
class Blog
{
    private $Id; //主键
    private $Title; //标题
    private $Content;   //内容
    private $PubTime;//发布时间
}
?>
  由于要对上述的一些字段做一些校验,我们对上述字段私有,再设置一些公开访问来操作这些字段,为了更好的提示验证过程中的错误,我们设置一个错误验证数组,来存储相应的错误,后边可以根据相应的要求来显示错误。



<?php
class Blog
{
    private $Id; //主键
    private $Title; //标题
    private $Content;   //内容
    private $PubTime;//发布时间
    public $errors=array();//错误数组
    //对ID的封装
    function GetId()
    {
      return $this->Id;
    }
    function SetId($id)
    {
      try {
            if (empty($id))
                throw new Exception("ID不能为空");
            if (!is_int($id))
                throw new Exception("ID应为数字");
            if ($id <= 0)
                throw new Exception("ID应为正数");
            $this->Id = $id;
      }catch (Exception $e)
      {
            $this->errors['Id']=$e->getMessage();
      }   
    }
    //对Title的封装
    function GetTitle()
    {
      return $this->Title;
    }
    function SetTitle($title)
    {
      try {
            if (empty($title))
                throw new Exception("标题不可为空");
            if (!is_string($title))
                throw new Exception("标题应为字符串");
            if (strlen($title)>60)
                throw new Exception("标题请小于20个汉字!");
            $this->Title = $title;
      }catch (Exception $e)
      {
            $this->errors['Title']=$e->getMessage();
      }
    }
    //对Content的封装
    function GetContent()
    {
      return $this->Content;
    }
    function SetContent($content)
    {
      try {
            if(empty($content))
                throw new Exception("内容不能为空");
            $this->Content = $content;
      }catch (Exception $e)
      {
            $this->errors['Content']=$e->getMessage();
      }
    }
    //对PubTime的封装
    function GetPubTime()
    {
      return $this->PubTime;
    }
    function SetPubTime($pubTime)
    {
      try {
            if (empty($pubTime))
                throw new Exception("时间不能为空");
            $this->PubTime = $pubTime;
      }catch (Exception $e)
      {
            $this->errors['PubTime']=$e->getMessage();
      }
    }
}?>
  到这里一步,该对这个类加一些业务操作方法,这里我们只用最简单的增加一篇博客,修改一篇和查看一篇博客的操作方法,对于Blog类扩充后代码为:


View Code


<?php
class Blog
{
    private $Id; //主键
    private $Title; //标题
    private $Content;   //内容
    private $PubTime;//发布时间
    public $errors=array();//错误数组
    //对ID的封装
    function GetId()
    {
      return $this->Id;
    }
    function SetId($id)
    {
      try {
            if (empty($id))
                throw new Exception("ID不能为空");
            if (!is_int($id))
                throw new Exception("ID应为数字");
            if ($id <= 0)
                throw new Exception("ID应为正数");
            $this->Id = $id;
      }catch (Exception $e)
      {
            $this->errors['Id']=$e->getMessage();
      }   
    }
    //对Title的封装
    function GetTitle()
    {
      return $this->Title;
    }
    function SetTitle($title)
    {
      try {
            if (empty($title))
                throw new Exception("标题不可为空");
            if (!is_string($title))
                throw new Exception("标题应为字符串");
            if (strlen($title)>60)
                throw new Exception("标题请小于20个汉字!");
            $this->Title = $title;
      }catch (Exception $e)
      {
            $this->errors['Title']=$e->getMessage();
      }
    }
    //对Content的封装
    function GetContent()
    {
      return $this->Content;
    }
    function SetContent($content)
    {
      try {
            if(empty($content))
                throw new Exception("内容不能为空");
            $this->Content = $content;
      }catch (Exception $e)
      {
            $this->errors['Content']=$e->getMessage();
      }
    }
    //对PubTime的封装
    function GetPubTime()
    {
      return $this->PubTime;
    }
    function SetPubTime($pubTime)
    {
      try {
            if (empty($pubTime))
                throw new Exception("时间不能为空");
            $this->PubTime = $pubTime;
      }catch (Exception $e)
      {
            $this->errors['PubTime']=$e->getMessage();
      }
    }
    //增加
    public function AddOne($title, $content, $pubTime, $newsClassId)
    {
      $news = new News();
      $news->SetTitle($title);
      $news->SetContent($content);
      $news->SetPubTime($pubTime);
      $news->SetNewsClassId($newsClassId);
      return $news->Save();
    }
   //修改
    public function UpdateOne($id, $title, $content, $pubTime, $newsClassId)
    {
      $news = new News();
      $news->SetId($id);
      $news->SetTitle($title);
      $news->SetContent($content);
      $news->SetPubTime($pubTime);
      $news->SetNewsClassId($newsClassId);
      return $news->Save();
    }
   //和数据库交互
    private function Save()
    {
      //和数据库交互前检查错误
      Error::CheckErrors($this->errors);
      //BlogData为相应的数据访问类
      $BlogData = new BlogData();
      if ($this->Id > 0)   //根据是否有Id判断是增加博客还是修改
      {
            return $BlogData->UpdateOne($this);
      }else
      {
            $this->SetPubTime(date("Y-m-d H:i:s"));//将发布时间设为现在
            return $newsData->InsertOne($this);
      }
    }
    public function GetOne($id)
    {
      try
      {
            if(!preg_match('/^+$/',$id))
                   throw new Exception("Id必须为整数");
               $BlogData = new BlogData();
               $result= $BlogData->GetOne($id);
             if(empty($result))
            {
                //若没有找到,跳转到未找到页面
                header('404.html');
            }
            else
            {
                //找到的话返回结果
                return $result;
            }
         }
      catch (Exception $e)
      {
            $this->errors[]="<li>".$e->getMessage()."</li>";
            Error::CheckErrors($this->errors);
      }
    }

}
?>
  

  可以看到,增加和修改方法都是在构造一个Blog对象,在构造的过程中一些业务逻辑就会被字段规则给验证,而错误会被记录在$errors数组中,对于AddOne()和UpdateOne()方法,最终都调用了本类的一个Save()方法。而Save()则根据当前Blog对象是否有Id这个字段有值来选择是调用数据访问类的增加还是更新方法,可以减少耦合。
     在入库之前,我们应该保证非法数据不能入库,这时$errors数组就可以用上,我们可以根据它是否为空来决定数据是否写入数据库中,这里调用这段代码:



Error::CheckErrors($this->errors);
  

Error是一个处理错误类,代码如下

View Code


<?php
class Error
{   
//构建静态方法,若有错误,显示错误,后续程序中断
    static public function CheckErrors($errors)
    {
      if(!empty($errors))
      {   
         //将所有错误信息输出
            $finalerror=NULL;
            foreach($errors as $error)
            {   
                $finalerror=$finalerror.strip_tags($error)."\\r\\n";                                          
            }
            $len = strlen($finalerror);
            $finalerror = substr($finalerror,0,$len-4);
            echo"<script>alert('".$finalerror."');</script>";
            //当错误不为空时,程序中断
            exit(0);
      }
    }
}
?>
这个做的比较简单,若有错误就弹出相应的警告框,程序终止,不太友善,可以根据相应的需求来改善。
到这里,简单的业务逻辑类就算完成,下一步我们将构造相应的数据访问类。


  

  


  
页: [1]
查看完整版本: PHP分层架构简单示例(1.业务逻辑类)