这篇文章主要介绍了PHP基于MySQL数据库实现对象持久层的方法,实例分析了php实现持久层的相关技巧,需要的朋友可以参考下
本文实例讲述了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程序设计有所帮助。
新闻热点
疑难解答