PHP基于MySQL数据库实现对象持久层的方法

本文实例讲述了PHP基于MySQL数据库实现对象持久层的方法。分享给大家供大家参考。具体如下:

心血来潮,做了一下PHP的对象到数据库的简单持久层。

不常用PHP,对PHP也不熟,关于PHP反射的大部分内容都是现学的。

目前功能比较弱,只是完成一些简单的工作,对象之间的关系还没法映射,并且对象的成员只能支持string或者integer两种类型的。

成员变量的值也没有转义一下。。。

下面就贴一下代码:

首先是数据库的相关定义,该文件定义了数据库的连接属性:

<?php
/*
 * Filename: config.php
 * Created on 2012-9-29
 * Created by RobinTang
 * To change the template for this generated file go to
 * Window - Preferences - PHPeclipse - PHP - Code Templates
 */
  // About database
  define('DBHOST', 'localhost'); // 数据库服务器
  define('DBNAME', 'db_wdid'); // 数据库名称
  define('DBUSER', 'root'); // 登陆用户名
  define('DBPSWD', 'trb'); // 登录密码
?>

下面是数据库访问的简单封装:

<?php
/*
 * Filename: database.php
 * Created on 2012-9-29
 * Created by RobinTang
 * To change the template for this generated file go to
 * Window - Preferences - PHPeclipse - PHP - Code Templates
 */
  include_once("config.php");
  $debug = false;
  $g_out = false;
  function out($s){
    global $g_out;
    $g_out .= $s;
    $g_out .= "\r\n";
  }
  function db_openconnect(){
    $con = mysql_connect(DBHOST, DBUSER, DBPSWD); 

    if(!mysql_set_charset("utf8", $con)){
      out("set mysql encoding fail");
    }
    if (!$con){
      out('Could not connect: ' . mysql_error());
    }
    else{
      if(!mysql_select_db(DBNAME, $con)){
        $dbn = DBNAME;
        out("Could select database '$dbn' : " . mysql_error());
      }
      $sql = "set time_zone = '+8:00';";
      if(!db_onlyquery($sql, $con)){
        out("select timezone fail!" . mysql_error());
      }
    }
    return $con;
  }
  function db_colseconnect($con){
    mysql_close($con);
  }
  function db_onlyquery($sql, $con){
    $r = mysql_query($sql, $con);
    if(!$r){
      out("query '$sql' :fail");
      return false;
    }
    else{
      return $r;
    }
  }
  function db_query($sql){
    $con = db_openconnect();
    $r = db_onlyquery($sql, $con);
    $res = false;
    if($r){
      $res = true;
    }
    db_colseconnect($con);
    return $r;
  }
  function db_query_effect_rows($sql){
    $con = db_openconnect();
    $r = db_onlyquery($sql, $con);
    $res = false;
    if($r){
      $res = mysql_affected_rows($con);
      if($res==0){
        $res = -1;
      }
    }
    else{
      $res = false;
    }
    db_colseconnect($con);
    return $res;
  }
  function db_getresult($sql){
    $con = db_openconnect();
    $r = db_onlyquery($sql, $con);
    $res = false;
    if($r && $arr = mysql_fetch_row($r)){
      $res = $arr[0];
    }
    db_colseconnect($con);
    return $res;
  }
  function db_getarray($sql){
    $con = db_openconnect();
    $r = db_onlyquery($sql, $con);
    $ret = false;
    if($r){
      $row = false;
      $len = 0;
      $ret = Array();
      $i = 0;
      while($arr = mysql_fetch_row($r)){
        if($row == false || $len==0){
          $row = Array();
          $len = count($arr);
          for($i=0;$i<$len;++$i){
            $key = mysql_field_name($r, $i);
            array_push($row, $key);
          }
        }
        $itm = Array();
        for($i=0;$i<$len;++$i){
          $itm[$row[$i]]=$arr[$i];
        }
        array_push($ret, $itm);
      }
    }
    db_colseconnect($con);
    return $ret;
  }
?>

其实上面的两个文件都是之前写好的,持久层的东西是下面的:

<?php
/*
 * Filename: sinorm.php
 * Created on 2012-11-4
 * Created by RobinTang
 * To change the template for this generated file go to
 * Window - Preferences - PHPeclipse - PHP - Code Templates
 */
  include_once("database.php"); 

  function SinORM_ExecSql($sql) {
    return db_query($sql);
  }
  function SinORM_ExecArray($sql) {
    return db_getarray($sql);
  }
  function SinORM_ExecResult($sql){
    return db_getresult($sql);
  }
  function SinORM_GetClassPropertys($class) {
    $r = new ReflectionClass($class);
    if (!$r->hasProperty('tablename')) {
      throw new Exception("Class '$class' has no [tablename] property");
    }
    $table = $r->getStaticPropertyValue('tablename');
    if (!$r->hasProperty('id')) {
      throw new Exception("Class '$class' has no [id] property");
    }
    $mpts = Array ();
    $pts = $r->getProperties(ReflectionProperty :: IS_PUBLIC);
    foreach ($pts as $pt) {
      if (!$pt->isStatic()) {
        array_push($mpts, $pt);
      }
    }
    return Array (
      $table,
      $mpts
    );
  }
  function SinORM_GetPropertyString($pts, $class, $obj = false, $noid = false) {
    if (is_null($pts)) {
      list ($tb, $pts) = SinORM_GetClassPropertys($class);
    }
    $s = false;
    $v = false;
    $l = false;
    foreach ($pts as $pt) {
      $name = $pt->name;
      if ($noid == false || $name != 'id') {
        if ($l) {
          $s = $s . ',';
        }
        $s = $s . $name; 

        if ($obj) {
          if ($l) {
            $v = $v . ',';
          }
          $val = $pt->getValue($obj);
          if (is_null($val))
            $v = $v . 'null';
          if (is_string($val))
            $v = $v . "'$val'";
          else
            $v = $v . $val;
        }
        $l = true;
      }
    }
    return Array (
      $s,
      $v
    );
  }
  function SinORM_GetTableName($class){
    $r = new ReflectionClass($class);
    if (!$r->hasProperty('tablename')) {
      throw new Exception("Class '$class' has no [tablename] property");
    }
    $table = $r->getStaticPropertyValue('tablename');
    if (!$r->hasProperty('id')) {
      throw new Exception("Class '$class' has no [id] property");
    }
    return $table;
  }
  function SinORM_ResetORM($class) {
    list ($tb, $pts) = SinORM_GetClassPropertys($class);
    $sql = "CREATE TABLE `$tb` (`id` int NOT NULL AUTO_INCREMENT";
    $r = new ReflectionClass($class);
    $obj = $r->newInstance();
    foreach ($pts as $pt) {
      $val = $pt->getValue($obj);
      $name = $pt->name;
      if ($name != 'id') {
        $sql = $sql . ',';
      } else {
        continue;
      }
      if (is_null($val))
        throw new Exception($class . '->' . "name must have a default value");
      if (is_string($val))
        $sql = $sql . "`$name` text NULL";
      else
        $sql = $sql . "`$name` int NULL";
    }
    $sql = $sql . ",PRIMARY KEY (`id`));";
    $dsql = "DROP TABLE IF EXISTS `$tb`;";
    return SinORM_ExecSql($dsql) && SinORM_ExecSql($sql);
  }
  function SinORM_SaveObject($obj) {
    $class = get_class($obj);
    list ($tb, $pts) = SinORM_GetClassPropertys($class);
    list ($names, $vals) = SinORM_GetPropertyString($pts, $class, $obj, true);
    $sql = "INSERT INTO `$tb`($names) values($vals)";
    if(SinORM_ExecSql($sql)){
      $q = "SELECT `id` FROM `$tb` ORDER BY `id` DESC LIMIT 1;";
      $id = SinORM_ExecResult($q);
      if($id){
        $obj->id = $id;
      }
    }
    return false;
  }
  function SinORM_GetObjects($class) {
    list ($tb, $pts) = SinORM_GetClassPropertys($class);
    $sql = "SELECT * from `$tb`;";
    $ary = SinORM_ExecArray($sql);
    $res = false;
    if (is_array($ary)) {
      $res = Array ();
      $ref = new ReflectionClass($class);
      foreach ($ary as $a) {
        $obj = $ref->newInstance();
        foreach ($pts as $pt) {
          $name = $pt->name;
          $olv = $pt->getValue($obj);
          $val = $a[$name];
          if (is_string($olv))
            $pt->setValue($obj, $val);
          else
            $pt->setValue($obj, intval($val));
        }
        array_push($res, $obj);
      }
    } else {
      echo 'no';
    }
    return $res;
  }
  function SinORM_GetObject($class, $id) {
    list ($tb, $pts) = SinORM_GetClassPropertys($class);
    $sql = "SELECT * from `$tb` where `id`=$id;";
    $ary = SinORM_ExecArray($sql);
    $res = null;
    if (is_array($ary) && count($ary) > 0) {
      $res = Array ();
      $ref = new ReflectionClass($class);
      $a = $ary[0];
      $obj = $ref->newInstance();
      foreach ($pts as $pt) {
        $name = $pt->name;
        $olv = $pt->getValue($obj);
        $val = $a[$name];
        if (is_string($olv))
          $pt->setValue($obj, $val);
        else
          $pt->setValue($obj, intval($val));
      }
      return $obj;
    }
    return null;
  }
  function SinORM_Update($obj) {
    $class = get_class($obj);
    list ($tb, $pts) = SinORM_GetClassPropertys($class);
    $sql = "UPDATE `$tb` SET ";
    $l = false;
    foreach ($pts as $pt) {
      $name = $pt->name;
      $val = $pt->getValue($obj);
      if ($name == 'id')
        continue;
      if ($l)
        $sql = $sql . ',';
      if (is_string($val))
        $sql = $sql . "$name='$val'";
      else
        $sql = $sql . "$name=$val";
      $l = true;
    }
    $sql = $sql . " WHERE `id`=$obj->id;";
    return SinORM_ExecSql($sql);
  }
  function SinORM_SaveOrUpdate($obj) {
    if (SinORM_GetObject(get_class($obj), $obj->id) == null) {
      SinORM_SaveObject($obj);
    } else {
      SinORM_Update($obj);
    }
  }
  function SinORM_DeleteObject($obj){
    $class = get_class($obj);
    $tb = SinORM_GetTableName($class);
    $sql = "DELETE FROM `$tb` WHERE `id`=$obj->id;";
    return SinORM_ExecSql($sql);
  }
  function SinORM_DeleteAll($class){
    $tb = SinORM_GetTableName($class);
    $sql = "DELETE FROM `$tb`;";
    return SinORM_ExecSql($sql);
  }
?>

下面是使用的例子:

<?php
/*
 * Filename: demo.php
 * Created on 2012-11-4
 * Created by RobinTang
 * To change the template for this generated file go to
 * Window - Preferences - PHPeclipse - PHP - Code Templates
 */
  include_once("sinorm.php");
  // 下面是一个持久对象的类的定义
  // 每个持久对象类都必须有一个叫做$tablename静态成员,它表示数据库中存储对象的表名
  // 类的每个成员都必须初始化,也就是必须给它一个初始值
  // 成员变量只能为字符串或者整型,而且请定义成public的,只有public的成员变量会被映射
  class User{
    public static $tablename = 't_user';  // 静态变量,对象的表名,必须的
    public $id = 0; // 对象ID,对应表中的主键,必须的,而且必须初始化为0 

    public $name = ''; // 姓名,必须初始化
    public $age = 0; // 年龄,必须初始化
    public $email = ''; // 必须初始化
  } 

  // 注意:下面的语句一定要在定义好类之后运行一下,修改了类也需要运行一下,它完成创建表的工作
  // SinORM_ResetORM('User'); // 这一句只是一开始执行一次,执行之后就会自动在数据库中建立User对应的表 

  $user1 = new User();  // 创建一个对象
  $user1->name = 'TRB';
  $user1->age = 22;
  $user1->email = 'trbbadboy@qq.com';
  SinORM_SaveObject($user1); // 把对象保存到数据库中 

  // 保存之后会自动给id的
  $id = $user1->id;
  echo $id . '<br/>'; 

  $user2 = SinORM_GetObject('User', $id); // 通过ID从数据库创建一个对象
  echo $user2->name . '<br/>'; 

  $user1->name = 'trb'; // 改变一下
  SinORM_Update($user1); // 更新到数据库 

  $user3 = SinORM_GetObject('User', $id); // 重新读出
  echo $user3->name . '<br/>';
?>

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

(0)

相关推荐

  • php简单操作mysql数据库的类

    本文实例讲述了php简单操作mysql数据库的类.分享给大家供大家参考.具体如下: <?php /** * Database class * * @version: 2.2 * @revised: 27 may 2007 * **/ class Database { var $host; var $name; var $user; var $pass; var $prefix; var $linkId; function Database($mysql) { foreach($mysql as

  • 初识通用数据库操作类——前端easyui-datagrid,form(php)

    初识通用数据库操作类--前端easyui-datagrid,form(php),实现代码比较简单,具体实现步骤请看下文. 实现功能: 左端datagrid显示简略信息,右侧显示选中行详细信息,数据库增删改 (1)点击选中行,右侧显示详细信息,其中[新增].[修改].[删除]按钮可用,[保存]按钮禁用 (2)点击[新增]按钮,[修改],[删除]按钮禁用,[保存]按钮启用 (3)点击[修改]按钮,[新增],[删除]按钮禁用 难点:通用数据库操作类中insert方法跟update方法 最终效果图: 前

  • php实现将Session写入数据库

    使用session_set_save_handler()函数,将Session的内容写入数据库 <?php /* *@author Fahy *数据库为mysql, *数据库名为session,表名为session, *表中字段包括PHPSESSID,update_time,client_ip,data */ class Session{ private static $handler = null; private static $ip = null; private static $life

  • PHP实现上传文件并存进数据库的方法

    本文实例讲述了PHP实现上传文件并存进数据库的方法.分享给大家供大家参考.具体如下: show_add.php文件如下: <?php if(!isset($_REQUEST['id']) or $_REQUEST['id']=="") die("error: id none"); $id = $_REQUEST['id']; //定位记录,读出 $conn=mysql_connect("localhost","root"

  • php将csv文件导入到mysql数据库的方法

    本文实例讲述了php将csv文件导入到mysql数据库的方法.分享给大家供大家参考.具体分析如下: 本程序实现数据导入原理是先把csv文件上传到服务器,然后再通过php的fopen与fgetcsv文件把数据保存到数组,然后再用while把数据一条条插入到mysql数据库,代码如下: 复制代码 代码如下: <?php $fname = $_files['myfile']['name']; $do = copy($_files['myfile']['tmp_name'],$fname); if ($

  • php页面,mysql数据库转utf-8乱码,utf-8编码问题总结

    示例一: PHP页面转UTF-8编码问题 1.在代码开始出加入一行: header("Content-Type: text/html;charset=utf-8"); 2.PHP文件编码问题 点击编辑器的菜单:"文件"->"另存为",可以看到当前文件的编码,确保文件编码为:UTF-8,如果是ANSI,需要将编码改成:UTF-8. 3.PHP文件头BOM问题: PHP文件一定不可以有BOM标签,否则,会出现session不能使用的情况,并有类

  • php基于session实现数据库交互的类实例

    本文实例讲述了php基于session实现数据库交互的类.分享给大家供大家参考.具体如下: <?php /** * session 数据库存储类 */ class Session { private static $session_id = 0; private static $session_data = array(); private static $is_update = FALSE; private static $is_del = FALSE; private static $is_

  • 1亿条数据如何分表100张到Mysql数据库中(PHP)

    下面通过创建100张表来演示下1亿条数据的分表过程,具体请看下文代码. 当数据量猛增的时候,大家都会选择库表散列等等方式去优化数据读写速度.笔者做了一个简单的尝试,1亿条数据,分100张表.具体实现过程如下: 首先创建100张表: $i=0; while($i<=99){ echo "$newNumber \r\n"; $sql="CREATE TABLE `code_".$i."` ( `full_code` char(10) NOT NULL,

  • php实现mysql数据库分表分段备份

    分卷导出思路:统计sql语句变量的长度,按1个字符当成1 字节比较,如果大于设定分卷大小,则写入一个sql文件(我也不知道这样统计是否稳当,这也是借鉴其他的人的). 分卷导入思路:按行读取sql文件,将每一行当作完整的sql语句存到数组再循环执行插入数据库就可以了,但是在创建表语句分了多行,这个需要单独处理(就这个花了我好长时间的): <?php //宋正河 转载请注明出处 set_time_limit(0); header('content-type:text/html;charset=utf

  • PHP使用ODBC连接数据库的方法

    本文实例讲述了PHP使用ODBC连接数据库的方法.分享给大家供大家参考.具体实现方法如下: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en

  • 常见PHP数据库解决方案分析介绍

    我们在使用PHP连接数据库的时候会遇到很多问题,文章这里揭露PHP应用程序中出现的常见数据库问题 -- 包括数据库模式设计.数据库访问和使用数据库的业务逻辑代码 -- 以及它们的解决方案.如果只有一种方式使用数据库是正确的.   PHP数据库问题:直接使用MySQL 一个常见问题是较老的 PHP 代码直接使用 mysql_ 函数来访问数据库.清单 1 展示了如何直接访问数据库. 清单 1. Access/get.php <?php function get_user_id( $name ) {

  • PHP将Excel导入数据库及数据库数据导出至Excel的方法

    本文实例讲述了PHP将Excel导入数据库及数据库数据导出至Excel的方法.分享给大家供大家参考.具体实现方法如下: 一.导入 导入需要使用能读取Excel的组件,网上也有比较好的组件,这里分享我使用的:下载  提取码:vxyn.(注意两个文件有引用关系) <?php //传入要导入的Excel的文件名 function import_to_DB($filename) { require_once'reader.php'; $data = new Spreadsheet_Excel_Reade

  • php将图片保存入mysql数据库失败的解决方法

    本文实例分析了php将图片保存入mysql数据库失败的解决方法.分享给大家供大家参考.具体分析如下: 图片保存数据库并不是一个明智的做法,我们多半是把图片保存到服务器,然后把图片地址保存到数据库,这样我们每次只要读出图片地址就可以显示了,但下面我还是来介绍一个图片保存到mysql数据库的问题解决办法,代码如下: 复制代码 代码如下: require 'class/db.php'; $fileName = "a1.jpg"; $fp = fopen($fileName, "r&

随机推荐