PHP基于面向对象实现的留言本功能实例


Posted in PHP onApril 04, 2018

本文实例讲述了PHP基于面向对象实现的留言本功能。分享给大家供大家参考,具体如下:

要设计一留言本,一切都将以留言本为核心,抓到什么是什么,按流程走下来,即按用户填写信息->留言->展示的流程进行。

现在用面向对象的思维思考这个问题,在面向对象的世界,会想尽办法把肉眼能看见的以及看不见的,但是实际存在的物或者流程抽象出来。既然是留言本,那么就存在留言内容这个实体,这个留言实体(domain)应该包括留言者姓名、E-mail、留言内容等要素,如下面代码所示

//留言实体类
class message
{
  public $name;//留言者姓名
  public $email;//留言者联系方式
  public $content;//留言内容
  public function __set($name,$value)
  {
    $this->$name = $value;
  }
  public function __get($name)
  {
    if(!isset($this->$name))
    {
      $this->$name = NULL;
    }
  }
}

上面的类就是所说的domain,是一个真实存在的、经过抽象的实体模型。然后需要一个留言本模型,这个留言本模型包括留言本的基本属性和基本操作,代码如下所示

class gbookModel
{
  private $bookPath;//留言本文件
  private $data;//留言数据
  public function setBookPath($bookPath)
  {
    $this->bookPath = $bookPath;
  }
  public function getBookPath()
  {
    return $this->bookPath;
  }
  public function open()
  {
  }
  public function close()
  {
  }
  public function read()
  {
    return file_get_contents($this->bookPath);
  }
  //写入留言
  public function write($data)
  {
    $this->data = self::safe($data)->name."&".self::safe($data)->email." said: ".self::safe($data)->content.PHP_EOL;
    return file_put_contents($this->bookPath,$this->data,FILE_APPEND);
  }
  //模拟数据的安全处理,先拆包再打包
  public static function safe($data)
  {
    $reflect = new ReflectionObject($data);
    $props = $reflect->getProperties();
    $messagebox = new stdClass();
    foreach($props as $props)
    {
      $ivar = $props->getName();
      $messagebox->$ivar = trim($props->getValue($data));
    }
    return $messagebox;
  }
  public function delete()
  {
    file_put_contents($this->bookPath,"it's empty now");
  }
}

实际留言的过程可能会更复杂,可能还包括一系列准备操作以及log处理,所以应定义一个类负责数据的逻辑处理,代码如下所示

class leaveModel
{
  public function write(gbookModel $gb, $data)
  {
    $book = $gb->getBookPath();
    $gb->write($data);
    //记录日志
  }
}

最后,通过一个控制器,负责对各种操作的封装,这个控制器是直接面向用户的,所以包括留言本查看、删除、留言等功能。可以形象理解为这个控制器就是留言本所提供的直接面向使用者的功能,封装了操作细节,只需要调用控制器的相应方法即可,代码如下所示

class authorControl
{
  public function message(leaveModel $l, gbookModel $g, message $data)
  {
    //在留言本上留言
    $l->write($g,$data);
  }
  public function view(gbookModel $g)
  {
    //查看留言本内容
    return $g->read();
  }
  public function delete(gbookModel $g)
  {
    $g->delete();
    echo self::view($g);
  }
}

测试代码如下所示

$message = new message;
$message->name = 'chenqionghe';
$message->email = 'cqh@cqh.net';
$message->content = 'chenqionghe is a handson boy.';
$gb = new authorControl();//新建一个留言相关的控制器
$pen = new leaveModel();//拿出笔
$book = new gbookModel();//翻出笔记本
$book->setBookPath("E:\\chenqionghe.txt");
$gb->message($pen,$book,$message);
echo $gb->view($book);
//$gb->delete($book);

这样看起来是不是比面向对象过程要复杂多了?确实是复杂了,代码量增多了,也难理解 。似乎体现不出优点来。但是你思考过以下问题吗?

1.如果让很多人来负责完善这个留言本,一部分实体关系的建立,一部人负责数据操作层的代码,这样是不是更容易分工了呢?

2.如果我要把这个留言本进一步开发,实现记录在数据库中,或者添加分页功能,又该如何呢?

要实现上面的第二问题提出的功能,只需在gookModel类中添加分页方法,代码如下所示

public function readByPage()
{
    $handle = file($this->bookPath);
    $count = count($handle);
    $page = isset($_GET['page']) ? intval($_GET['page']) : 1;
    if($page<1 || $page>$count)
      $page = 1;
    $pnum = 9;
    $begin = ($page-1) * $pnum;
    $end = ($begin+$pnum) > $count ? $count :$begin + $pnum;
    for($i=$begin; $i<$end; $i++)
    {
      echo '<strong>',$i+1,'</strong>',$handle[$i],'<br />';
    }
    for($i=1;$i<ceil($count/$pnum);$i++)
    {
      echo '<a href="?page='.$i.'" rel="external nofollow" rel="external nofollow" >'.$i.'</a>';
    }
}

然后到前端控制器里添加对应的action,代码如下所示

public function viewByPage(gbookModel $g)
{
    return $g->readByPage();
}

运行结果如下

PHP基于面向对象实现的留言本功能实例

只需要这么简单的两步,就可以实现所需要的分页功能,而且已有的方法都不用修改,只需要在相关类中新增方法即可。当然,这个分页在实际点击时是有问题的,因为没有把Action分开,而是通通放在一个页面里。对照着上面的思路,还可以把留言本扩展为MySQL数据库的。

这个程序只体现了非常简单的设计模式,这个程序还有许多要改进的地方,每个程序员心中都有一个自己的OO。项目越大越能体现模块划分、面向对象的好处。

下面是完整的代码

<?php
//留言实体类
class message
{
  public $name;//留言者姓名
  public $email;//留言者联系方式
  public $content;//留言内容
  public function __set($name,$value)
  {
    $this->$name = $value;
  }
  public function __get($name)
  {
    if(!isset($this->$name))
    {
      $this->$name = NULL;
    }
  }
}
/**
 * 留言本模型,负责管理留言本
 * $bookpath:留言本属性
 */
class gbookModel
{
  private $bookPath;//留言本文件
  private $data;//留言数据
  public function setBookPath($bookPath)
  {
    $this->bookPath = $bookPath;
  }
  public function getBookPath()
  {
    return $this->bookPath;
  }
  public function open()
  {
  }
  public function close()
  {
  }
  public function read()
  {
    return file_get_contents($this->bookPath);
  }
  public function readByPage()
  {
    $handle = file($this->bookPath);
    $count = count($handle);
    $page = isset($_GET['page']) ? intval($_GET['page']) : 1;
    if($page<1 || $page>$count)
      $page = 1;
    $pnum = 9;
    $begin = ($page-1) * $pnum;
    $end = ($begin+$pnum) > $count ? $count :$begin + $pnum;
    for($i=$begin; $i<$end; $i++)
    {
      echo '<strong>',$i+1,'</strong>',$handle[$i],'<br />';
    }
    for($i=1;$i<ceil($count/$pnum);$i++)
    {
      echo '<a href="?page='.$i.'" rel="external nofollow" rel="external nofollow" >'.$i.'</a>';
    }
  }
  //写入留言
  public function write($data)
  {
    $this->data = self::safe($data)->name."&".self::safe($data)->email." said: ".self::safe($data)->content.PHP_EOL;
    return file_put_contents($this->bookPath,$this->data,FILE_APPEND);
  }
  //模拟数据的安全处理,先拆包再打包
  public static function safe($data)
  {
    $reflect = new ReflectionObject($data);
    $props = $reflect->getProperties();
    $messagebox = new stdClass();
    foreach($props as $props)
    {
      $ivar = $props->getName();
      $messagebox->$ivar = trim($props->getValue($data));
    }
    return $messagebox;
  }
  public function delete()
  {
    file_put_contents($this->bookPath,"it's empty now");
  }
}
class leaveModel
{
  public function write(gbookModel $gb, $data)
  {
    $book = $gb->getBookPath();
    $gb->write($data);
    //记录日志
  }
}
class authorControl
{
  public function message(leaveModel $l, gbookModel $g, message $data)
  {
    //在留言本上留言
    $l->write($g,$data);
  }
  public function view(gbookModel $g)
  {
    //查看留言本内容
    return $g->read();
  }
  public function viewByPage(gbookModel $g)
  {
    return $g->readByPage();
  }
  public function delete(gbookModel $g)
  {
    $g->delete();
    echo self::view($g);
  }
}
$message = new message;
$message->name = 'chenqionghe';
$message->email = 'cqh@cqh.net';
$message->content = 'chenqionghe is a handson boy.';
$gb = new authorControl();//新建一个留言相关的控制器
$pen = new leaveModel();//拿出笔
$book = new gbookModel();//翻出笔记本
$book->setBookPath("E:\\chenqionghe.txt");
$gb->message($pen,$book,$message);
//echo $gb->view($book);
echo $gb->viewByPage($book);
//$gb->delete($book);

希望本文所述对大家PHP程序设计有所帮助。

PHP 相关文章推荐
php date与gmdate的获取日期的区别
Feb 08 PHP
约瑟夫环问题的PHP实现 使用PHP数组内部指针操作函数
Oct 12 PHP
第4章 数据处理-php正则表达式-郑阿奇(续)
Jul 04 PHP
shopex主机报错误请求解决方案(No such file or directory)
Dec 27 PHP
php 对输入信息的进行安全过滤的函数代码
Jun 29 PHP
php实现的树形结构数据存取类实例
Nov 29 PHP
Yii配置与使用memcached缓存的方法
Jul 13 PHP
php输出含有“#”字符串的方法
Jan 18 PHP
PHP水印类,支持添加图片、文字、填充颜色区域的实现
Feb 04 PHP
原生JS实现Ajax通过GET方式与PHP进行交互操作示例
May 12 PHP
PHP 模拟登陆功能实例详解
Sep 10 PHP
PHP使用openssl扩展实现加解密方法示例
Feb 20 PHP
PHP设计模式之工厂模式定义与用法详解
Apr 03 #PHP
PHP设计模式之原型模式定义与用法详解
Apr 03 #PHP
thinkPHP框架自动填充原理与用法分析
Apr 03 #PHP
PHP设计模式之适配器模式定义与用法详解
Apr 03 #PHP
PHP延迟静态绑定的深入讲解
Apr 02 #PHP
PHP设计模式之装饰器模式定义与用法详解
Apr 02 #PHP
PHP设计模式之状态模式定义与用法详解
Apr 02 #PHP
You might like
日本因肺炎疫情影响,这几部动漫推延播放!
2020/03/03 日漫
两种php调用Java对象的方法
2006/10/09 PHP
php批量更改数据库表前缀实现方法
2013/10/26 PHP
实用的PHP带公钥加密类分享(每次加密结果都不一样哦)
2014/08/20 PHP
php的sso单点登录实现方法
2015/01/08 PHP
Docker搭建自己的PHP开发环境
2018/02/24 PHP
用javascript实现读取txt文档的脚本
2007/07/20 Javascript
javascript iframe中打开文件,并检测iframe存在否
2008/12/28 Javascript
40个有创意的jQuery图片和内容滑动及弹出插件收藏集之三
2012/01/03 Javascript
使用Grunt.js管理你项目的应用说明
2013/04/24 Javascript
JQuery下拉框应用示例介绍
2014/04/23 Javascript
angular.element方法汇总
2015/01/07 Javascript
jQuery+HTML5实现手机摇一摇换衣特效
2015/06/05 Javascript
JavaScript获取客户端IP的方法(新方法)
2016/03/11 Javascript
详解JavaScript权威指南之对象
2016/09/27 Javascript
JS中微信小程序自定义底部弹出框
2016/12/22 Javascript
浅谈vue实现数据监听的函数 Object.defineProperty
2017/06/08 Javascript
Vue组件实例间的直接访问实现代码
2017/08/20 Javascript
浅谈React碰到v-if
2018/11/04 Javascript
vue2.0中set添加属性后视图不能更新的解决办法
2019/02/22 Javascript
[38:32]完美世界DOTA2联赛循环赛 Forest vs DM 第二场 11.06
2020/11/06 DOTA
Python模拟登陆实现代码
2017/06/14 Python
python3.4下django集成使用xadmin后台的方法
2017/08/15 Python
浅谈python中拼接路径os.path.join斜杠的问题
2018/10/23 Python
更新修改后的Python模块方法
2019/03/03 Python
Python参数类型以及常见的坑详解
2019/07/08 Python
sklearn线性逻辑回归和非线性逻辑回归的实现
2020/06/09 Python
Answear匈牙利:来自全球200多个知名时尚品牌
2017/04/21 全球购物
路由表示做什么用的?在linux环境中怎么来配置一条默认路由?
2013/06/07 面试题
经典安踏广告词
2014/03/21 职场文书
2014年单位植树节活动方案
2014/03/23 职场文书
我的中国梦演讲稿小学篇
2014/08/19 职场文书
会议邀请函
2015/01/30 职场文书
商场营业员岗位职责
2015/04/14 职场文书
2015年青年教师工作总结
2015/05/25 职场文书
Nginx反爬虫策略,防止UA抓取网站
2021/03/31 Servers