PHPはオブジェクトの永続層を実現し、データベースはMySQLを使用する


心血を注いで、PHPの対象をデータベースの簡単な持続層にしました.
PHPをあまり使わず、PHPにも詳しくなく、PHP反射に関するほとんどの内容は現学的である.
現在、機能は弱く、簡単な作業を完了するだけで、オブジェクト間の関係はまだマッピングされず、オブジェクトのメンバーはstringまたはintegerの2つのタイプしかサポートされていません.
メンバー変数の値もエスケープしていません..
コードを貼り付けます.
まず、データベースの接続プロパティを定義するデータベースに関する定義です.
<?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
"; } 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; } ?>

実は上の2つの書類はすべて前に書いたもので、持続層のものは下のものです.
<?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 = '[email protected]';
	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/>';
?>