andyyuduo 发表于 2016-11-20 10:00:22

PHP简单的ORM实现(postgresql)

  用户表简单操作,简单orm实现原理:
  postgresql:system_user表如下:
  /*
  Navicat Premium Data Transfer
  Source Server         : 本地
  Source Server Type    : PostgreSQL
  Source Server Version : 90404
  Source Host           : 127.0.0.1
  Source Database       : dbname
  Source Schema         : public
  Target Server Type    : PostgreSQL
  Target Server Version : 90404
  File Encoding         : utf-8
  Date: 08/21/2015 16:33:36 PM
  */
  -- ----------------------------
  --  Table structure for system_user
  -- ----------------------------
  DROP TABLE IF EXISTS "public"."system_user";
  CREATE TABLE "public"."system_user" (
  "id" int4 NOT NULL DEFAULT nextval('system_user_id_seq'::regclass),
  "first_name" varchar(64) COLLATE "default",
  "last_name" varchar(128) COLLATE "default",
  "username" varchar(32) COLLATE "default",
  "md5_pw" varchar(32) COLLATE "default",
  "email_address" varchar(128) COLLATE "default",
  "date_last_login" date,
  "date_account_created" date,
  "time_last_login" time(6),
  "time_account_created" time(6)
  )
  WITH (OIDS=FALSE);
  ALTER TABLE "public"."system_user" OWNER TO "username";
  -- ----------------------------
  --  Records of system_user
  -- ----------------------------
  BEGIN;
  INSERT INTO "public"."system_user" VALUES ('9', 'Tim', 'Nowicki', '', null, '', '2015-08-21', '2015-08-21', '16:01:42', '16:01:46');
  INSERT INTO "public"."system_user" VALUES ('11', 'Tim', 'Nowicki', '', null, '', '2015-08-21', '2015-08-21', '16:04:11', '16:04:13');
  INSERT INTO "public"."system_user" VALUES ('12', 'Tim', 'Nowicki', '', null, '', '2015-08-21', '2015-08-21', '16:05:15', '16:06:02');
  INSERT INTO "public"."system_user" VALUES ('13', 'Tim', 'LinLIIII', null, null, null, '2015-08-21', '2015-08-21', null, null);
  INSERT INTO "public"."system_user" VALUES ('14', 'Lin', 'Nowicki', null, null, null, null, '2015-08-21', null, null);
  INSERT INTO "public"."system_user" VALUES ('15', 'Lin', 'Nowicki', null, null, null, null, '2015-08-21', null, null);
  COMMIT;
  -- ----------------------------
  --  Primary key structure for table system_user
  -- ----------------------------
  ALTER TABLE "public"."system_user" ADD PRIMARY KEY ("id") NOT DEFERRABLE INITIALLY IMMEDIATE;
  1,简单的orm实现
  用户类(User2.php)
  <?php
  /* 
  * To change this license header, choose License Headers in Project Properties.
  * To change this template file, choose Tools | Templates
  * and open the template in the editor.
  */
  class User{
  private $ID;
  private $objPDO;
  private $strTableName;
  private $arRelationMap;
  private $blForDeletion;
  private $FirstName;
  private $LastName;
  private $Username;
  private $Password;
  private $EmailAddress;
  private $DateLastLogin;
  private $TimeLastLogin;
  private $DateAccountCreated;
  private $TimeAccountCreated;
  public function __construct(PDO $objPDO,$id = NULL) {
  $this->strTableName = "system_user";
  $this->arRelationMap = [
  "id"                    => "ID",
  "first_name"            => "FirstName",
  "last_name"             => "LastName",
  "username"              => "Username",
  "md5_pw"                => "password",
  "email_address"         => "EmailAddress",
  "date_last_login"       => "DateLastLogin",
  "time_last_login"       => "TimeLastLogin",
  "date_account_created"  => "DateAccountCreated",
  "time_account_created"  => "TimeAccountCreated"
  ];
  $this->objPDO = $objPDO;
  if(isset($id)){
  $this->ID = $id;
  $strQuery = "SELECT ";
  foreach ($this->arRelationMap as $key => $value) {
  $strQuery .= "\"".$key."\",";
  }
  $strQuery = substr($strQuery, 0, strlen($strQuery)-1);
  $strQuery .=" FROM ".$this->strTableName." WHERE \"id\" = :eid";
  $objStatement = $this->objPDO->prepare($strQuery);
  $objStatement->bindParam(':eid', $this->ID, PDO::PARAM_INT);
  $objStatement->execute();
  $arRow = $objStatement->fetch(PDO::FETCH_ASSOC);
  foreach ($arRow as $key => $value) {
  $strMember = $this->arRelationMap[$key];
  if(property_exists($this, $strMember)){
  if(is_numeric($value)){
  eval('$this->'.$strMember .' = '.$value.';');
  }else{
  eval('$this->'.$strMember.' = "'.$value.'";');
  }
  }
  }
  }
  }
  public function Save(){
  if(isset($this->ID)){
  $strQuery = 'UPDATE "'.$this->strTableName.'" SET ';
  foreach ($this->arRelationMap as $key => $value) {
  eval('$actualVal = &$this->'.$value.';');
  if(isset($actualVal)){
  $strQuery .= '"' .$key. "\" = :$value,";
  }
  }
  $strQuery = substr($strQuery, 0,strlen($strQuery)-1);
  $strQuery .=' WHERE "id"=:eid';
  unset($objStatement);
  $objStatement = $this->objPDO->prepare($strQuery);
  $objStatement->bindValue(':eid', $this->ID,  PDO::PARAM_INT);
  foreach ($this->arRelationMap as $key => $value) {
  eval('$actualVal = &$this->'.$value.';');
  if(isset($actualVal)) {
  if(is_int($actualVal)){
  $objStatement->bindValue(':'.$value, $this->$value, PDO::PARAM_INT);
  }elseif($actualVal == NULL){
  //postgresql:if some column type is null,update will cause error,u need insert null,not ''
  $objStatement->bindValue(':'.$value, NULL, PDO::PARAM_STR);
  }else{
  $objStatement->bindValue(':'.$value, $this->$value, PDO::PARAM_STR);
  }
  }
  }
  $objStatement->execute();
  echo '更新成功';exit;
  }else{
  $strValueList = "";
  $strQuery = 'INSERT INTO "'.$this->strTableName.'" (';
  foreach ($this->arRelationMap as $key => $value) {
  eval('$actualVal = &$this->'.$value.';');
  if(isset($actualVal)){
  $strQuery .= '"' .$key. '",';
  $strValueList .= ":$value,";
  }
  }
  $strQuery = substr($strQuery, 0, strlen($strQuery)-1);
  $strValueList = substr($strValueList, 0, strlen($strValueList)-1);
  $strQuery .= ") VALUES (";
  $strQuery .= $strValueList;
  $strQuery .= ")";
  unset($objStatement);
  $objStatement = $this->objPDO->prepare($strQuery);
  foreach ($this->arRelationMap as $key => $value) {
  eval('$actualVal = &$this->'.$value.';');
  if(isset($actualVal)){
  if(is_int($actualVal) || $actualVal == NULL){
  $objStatement->bindValue(':'.$value, $actualVal, PDO::PARAM_INT);
  }else{
  $objStatement->bindValue(':'.$value, $actualVal, PDO::PARAM_STR);
  }
  }
  }
  $objStatement->execute();
  $this->ID = $this->objPDO->lastInsertId($this->strTableName."_id_seq");
  }
  }
  public function MarkFordeletion(){
  $this->blForDeletion = true;
  }
  public function __destruct() {
  if(isset($this->ID)){
  if($this->blForDeletion == true){
  $strQuery = 'DELETE FROM "'.$this->strTableName.'" WHERE "id" =:eid';
  $objStatement = $this->objPDO->prepare($strQuery);
  $objStatement->bindValue(':eid', $this->ID,  PDO::PARAM_INT);
  $objStatement->execute();
  echo '删除成功';exit;
  }
  }
  }
  public function __call($strFunction, $arArguments) {
  $strMethodType = substr($strFunction, 0,3);
  $strMethodMember = substr($strFunction, 3);
  switch ($strMethodType) {
  case 'set':
  return ($this->SetAccessor($strMethodMember, $arArguments));
  break;
  case 'get':
  return ($this->GetAccessor($strMethodMember));
  }
  return (false);
  }
  private function SetAccessor($strMember,$strNewValue){
  if(property_exists($this, $strMember)){
  if(is_numeric($strNewValue)){
  eval('$this->'.$strMember.' = '.$strNewValue.';');
  }else{
  eval('$this->'.$strMember.' = "'.$strNewValue.'";');
  }
  }else{
  return (false);
  }
  }
  private function GetAccessor($strMember){
  if(property_exists($this, $strMember)){
  eval('$strRetVal = $this->'.$strMember.';');
  return ($strRetVal);
  }else{
  return (false);
  }
  }
  }
  2,postgresql连接(PdoFactory.php):
  <?php
  /* 
  * To change this license header, choose License Headers in Project Properties.
  * To change this template file, choose Tools | Templates
  * and open the template in the editor.
  */
  class PdoFactory extends PDO{
  public static function getPDO($osn,$username, $passwd, $options){
  try { 
  $pdo = new PDO($osn,$username, $passwd, $options); 
  $pdo->setAttribute(PDO::ATTR_PERSISTENT, true);  // 设置数据库连接为持久连接  
  $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);  // 设置抛出错误  
  } catch (PDOException $e) { 
  exit('数据库连接失败,错误信息:'. $e->getMessage()); 
  } 
  return $pdo;
  }
  }
  测试:
  1插入用户数据:
  <?php
  /* 
  * To change this license header, choose License Headers in Project Properties.
  * To change this template file, choose Tools | Templates
  * and open the template in the editor.
  */
  require_once 'PdoFactory.php';
  require_once 'User2.php';
  //$dsn = 'mysql:host=127.0.0.1;dbname=tesst;port=3306';
  //host=127.0.0.1 port=5432 dbname=dbname user=username password=123456
  $dsn ="pgsql:dbname=dbname;host=127.0.0.1;port=5432";
  $objPdo = PdoFactory::getPDO($dsn,'username','123456',[]);
  $objUser = new User($objPdo);
  //print_r($objUser);
  $objUser->setFirstName('Lin');
  $objUser->setLastName('Nowicki');
  $objUser->setDateAccountCreated(date('Y-m-d'));
  echo $objUser->getFirstName();
  echo '<br />';
  echo $objUser->getLastName();
  echo '<br />';
  print 'Saving...<br/>';
  $objUser->Save();
  print "ID in dateBase is ". $objUser->getID()."<br />";
  执行结果:
  Lin
Nowicki
Saving...
ID in dateBase is 16
  2,更新用户数据:
  require_once 'PdoFactory.php';
  require_once 'User2.php';
  //$dsn = 'mysql:host=127.0.0.1;dbname=tesst;port=3306';
  //host=127.0.0.1 port=5432 dbname=dbname user=username password=123456
  $dsn ="pgsql:dbname=dbname;host=127.0.0.1;port=5432";
  $objPdo = PdoFactory::getPDO($dsn,'username','123456',[]);
  $objUser = new User($objPdo,16);
  $objUser->setFirstName("Tim");
  $objUser->setLastName("LinLIIII");
  $objUser->Save();
  产生结果:
  更新成功
  3,删除用户数据:
  require_once 'PdoFactory.php';
  require_once 'User2.php';
  //$dsn = 'mysql:host=127.0.0.1;dbname=tesst;port=3306';
  //host=127.0.0.1 port=5432 dbname=dbname user=username password=123456
  $dsn ="pgsql:dbname=dbname;host=127.0.0.1;port=5432";
  $objPdo = PdoFactory::getPDO($dsn,'username','123456',[]);
  $objUser = new User($objPdo,16);
  $objUser->MarkFordeletion();
  执行结果:
  删除成功
页: [1]
查看完整版本: PHP简单的ORM实现(postgresql)