PHP基于MySQL数据库实现对象持久层的方法
本文实例讲述了PHP基于MySQL数据库实现对象持久层的方法。分享给大家供大家参考。具体如下:
心血来潮,做了一下PHP的对象到数据库的简单持久层。
不常用PHP,对PHP也不熟,关于PHP反射的大部分内容都是现学的。
目前功能比较弱,只是完成一些简单的工作,对象之间的关系还没法映射,并且对象的成员只能支持string或者integer两种类型的。
成员变量的值也没有转义一下。。。
下面就贴一下代码:
首先是数据库的相关定义,该文件定义了数据库的连接属性:
<?php
/*
*Filename:config.php
*Createdon2012-9-29
*CreatedbyRobinTang
*Tochangethetemplateforthisgeneratedfilegoto
*Window-Preferences-PHPeclipse-PHP-CodeTemplates
*/
//Aboutdatabase
define('DBHOST','localhost');//数据库服务器
define('DBNAME','db_wdid');//数据库名称
define('DBUSER','root');//登陆用户名
define('DBPSWD','trb');//登录密码
?>
下面是数据库访问的简单封装:
<?php
/*
*Filename:database.php
*Createdon2012-9-29
*CreatedbyRobinTang
*Tochangethetemplateforthisgeneratedfilegoto
*Window-Preferences-PHPeclipse-PHP-CodeTemplates
*/
include_once("config.php");
$debug=false;
$g_out=false;
functionout($s){
global$g_out;
$g_out.=$s;
$g_out.="\r\n";
}
functiondb_openconnect(){
$con=mysql_connect(DBHOST,DBUSER,DBPSWD);
if(!mysql_set_charset("utf8",$con)){
out("setmysqlencodingfail");
}
if(!$con){
out('Couldnotconnect:'.mysql_error());
}
else{
if(!mysql_select_db(DBNAME,$con)){
$dbn=DBNAME;
out("Couldselectdatabase'$dbn':".mysql_error());
}
$sql="settime_zone='+8:00';";
if(!db_onlyquery($sql,$con)){
out("selecttimezonefail!".mysql_error());
}
}
return$con;
}
functiondb_colseconnect($con){
mysql_close($con);
}
functiondb_onlyquery($sql,$con){
$r=mysql_query($sql,$con);
if(!$r){
out("query'$sql':fail");
returnfalse;
}
else{
return$r;
}
}
functiondb_query($sql){
$con=db_openconnect();
$r=db_onlyquery($sql,$con);
$res=false;
if($r){
$res=true;
}
db_colseconnect($con);
return$r;
}
functiondb_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;
}
functiondb_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;
}
functiondb_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
*Createdon2012-11-4
*CreatedbyRobinTang
*Tochangethetemplateforthisgeneratedfilegoto
*Window-Preferences-PHPeclipse-PHP-CodeTemplates
*/
include_once("database.php");
functionSinORM_ExecSql($sql){
returndb_query($sql);
}
functionSinORM_ExecArray($sql){
returndb_getarray($sql);
}
functionSinORM_ExecResult($sql){
returndb_getresult($sql);
}
functionSinORM_GetClassPropertys($class){
$r=newReflectionClass($class);
if(!$r->hasProperty('tablename')){
thrownewException("Class'$class'hasno[tablename]property");
}
$table=$r->getStaticPropertyValue('tablename');
if(!$r->hasProperty('id')){
thrownewException("Class'$class'hasno[id]property");
}
$mpts=Array();
$pts=$r->getProperties(ReflectionProperty::IS_PUBLIC);
foreach($ptsas$pt){
if(!$pt->isStatic()){
array_push($mpts,$pt);
}
}
returnArray(
$table,
$mpts
);
}
functionSinORM_GetPropertyString($pts,$class,$obj=false,$noid=false){
if(is_null($pts)){
list($tb,$pts)=SinORM_GetClassPropertys($class);
}
$s=false;
$v=false;
$l=false;
foreach($ptsas$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;
}
}
returnArray(
$s,
$v
);
}
functionSinORM_GetTableName($class){
$r=newReflectionClass($class);
if(!$r->hasProperty('tablename')){
thrownewException("Class'$class'hasno[tablename]property");
}
$table=$r->getStaticPropertyValue('tablename');
if(!$r->hasProperty('id')){
thrownewException("Class'$class'hasno[id]property");
}
return$table;
}
functionSinORM_ResetORM($class){
list($tb,$pts)=SinORM_GetClassPropertys($class);
$sql="CREATETABLE`$tb`(`id`intNOTNULLAUTO_INCREMENT";
$r=newReflectionClass($class);
$obj=$r->newInstance();
foreach($ptsas$pt){
$val=$pt->getValue($obj);
$name=$pt->name;
if($name!='id'){
$sql=$sql.',';
}else{
continue;
}
if(is_null($val))
thrownewException($class.'->'."namemusthaveadefaultvalue");
if(is_string($val))
$sql=$sql."`$name`textNULL";
else
$sql=$sql."`$name`intNULL";
}
$sql=$sql.",PRIMARYKEY(`id`));";
$dsql="DROPTABLEIFEXISTS`$tb`;";
returnSinORM_ExecSql($dsql)&&SinORM_ExecSql($sql);
}
functionSinORM_SaveObject($obj){
$class=get_class($obj);
list($tb,$pts)=SinORM_GetClassPropertys($class);
list($names,$vals)=SinORM_GetPropertyString($pts,$class,$obj,true);
$sql="INSERTINTO`$tb`($names)values($vals)";
if(SinORM_ExecSql($sql)){
$q="SELECT`id`FROM`$tb`ORDERBY`id`DESCLIMIT1;";
$id=SinORM_ExecResult($q);
if($id){
$obj->id=$id;
}
}
returnfalse;
}
functionSinORM_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=newReflectionClass($class);
foreach($aryas$a){
$obj=$ref->newInstance();
foreach($ptsas$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;
}
functionSinORM_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=newReflectionClass($class);
$a=$ary[0];
$obj=$ref->newInstance();
foreach($ptsas$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;
}
returnnull;
}
functionSinORM_Update($obj){
$class=get_class($obj);
list($tb,$pts)=SinORM_GetClassPropertys($class);
$sql="UPDATE`$tb`SET";
$l=false;
foreach($ptsas$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;";
returnSinORM_ExecSql($sql);
}
functionSinORM_SaveOrUpdate($obj){
if(SinORM_GetObject(get_class($obj),$obj->id)==null){
SinORM_SaveObject($obj);
}else{
SinORM_Update($obj);
}
}
functionSinORM_DeleteObject($obj){
$class=get_class($obj);
$tb=SinORM_GetTableName($class);
$sql="DELETEFROM`$tb`WHERE`id`=$obj->id;";
returnSinORM_ExecSql($sql);
}
functionSinORM_DeleteAll($class){
$tb=SinORM_GetTableName($class);
$sql="DELETEFROM`$tb`;";
returnSinORM_ExecSql($sql);
}
?>
下面是使用的例子:
<?php
/*
*Filename:demo.php
*Createdon2012-11-4
*CreatedbyRobinTang
*Tochangethetemplateforthisgeneratedfilegoto
*Window-Preferences-PHPeclipse-PHP-CodeTemplates
*/
include_once("sinorm.php");
//下面是一个持久对象的类的定义
//每个持久对象类都必须有一个叫做$tablename静态成员,它表示数据库中存储对象的表名
//类的每个成员都必须初始化,也就是必须给它一个初始值
//成员变量只能为字符串或者整型,而且请定义成public的,只有public的成员变量会被映射
classUser{
publicstatic$tablename='t_user';//静态变量,对象的表名,必须的
public$id=0;//对象ID,对应表中的主键,必须的,而且必须初始化为0
public$name='';//姓名,必须初始化
public$age=0;//年龄,必须初始化
public$email='';//必须初始化
}
//注意:下面的语句一定要在定义好类之后运行一下,修改了类也需要运行一下,它完成创建表的工作
//SinORM_ResetORM('User');//这一句只是一开始执行一次,执行之后就会自动在数据库中建立User对应的表
$user1=newUser();//创建一个对象
$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程序设计有所帮助。