>  기사  >  백엔드 개발  >  Quentin Zerva의 DBO

Quentin Zerva의 DBO

WBOY
WBOY원래의
2016-07-25 09:10:09837검색
"Web 2.0 Development in Practice"의 저자인 Quentin Zervaas는 책에서 간단한 PHP 데이터 액세스 개체를 언급했습니다.
  1. /**
  2. * DatabaseObject
  3. *
  4. * 데이터베이스 테이블의 데이터를 쉽게 조작하는 데 사용되는 추상 클래스
  5. * 간단한 로드/저장/삭제 방법을 통해
  6. */
  7. 추상 클래스 DatabaseObject
  8. {
  9. const TYPE_TIMESTAMP = 1;
  10. const TYPE_BOOLEAN = 2;
  11. protected static $types = array(self::TYPE_TIMESTAMP, self::TYPE_BOOLEAN);
  12. private $_id = null;
  13. private $_properties = array();
  14. protected $_db = null;
  15. protected $_table = '';
  16. protected $_idField = '';
  17. 공용 함수 __construct(Zend_Db_Adapter_Abstract $db, $ 테이블, $idField)
  18. {
  19. $this->_db = $db;
  20. $this->_table = $table;
  21. $this->_idField = $idField;
  22. }
  23. 공용 함수 로드($id, $field = null)
  24. {
  25. if (strlen($field) == 0)
  26. $field = $this->_idField ;
  27. if ($field == $this->_idField) {
  28. $id = (int) $id;
  29. if ($id <= 0)
  30. return false ;
  31. }
  32. $query = sprintf('%s에서 %s 선택, 여기서 %s = ?',
  33. Join(', ', $this->getSelectFields()),
  34. $this->_table,
  35. $field);
  36. $query = $this->_db->quoteInto($query, $id);
  37. return $this->_load($query);
  38. }
  39. 보호 함수 getSelectFields($prefix = '')
  40. {
  41. $fields = array($prefix . $this->_idField);
  42. foreach ($this->_properties as $k => $v)
  43. $fields[] = $prefix . $k;
  44. return $fields;
  45. }
  46. 보호 함수 _load($query)
  47. {
  48. $result = $this->_db->query ($query);
  49. $row = $result->fetch();
  50. if (!$row)
  51. return false;
  52. $this->_init($row );
  53. $this->postLoad();
  54. return true;
  55. }
  56. 공개 함수 _init($row)
  57. {
  58. foreach ($this->_properties as $k => $v) {
  59. $val = $row[$k];
  60. 스위치($v['type']) {
  61. case self::TYPE_TIMESTAMP:
  62. if (!is_null($val))
  63. $val = strtotime($val);
  64. break;
  65. case self::TYPE_BOOLEAN:
  66. $val = (bool) $val;
  67. break;
  68. }
  69. $this->_properties[$k]['value'] = $val;
  70. }
  71. $this ->_id = (int) $row[$this->_idField];
  72. }
  73. 공개 함수 save($useTransactions = true)
  74. {
  75. $update = $this->isSaved();
  76. if ($useTransactions)
  77. $this->_db->beginTransaction();
  78. if ($update)
  79. $commit = $this->preUpdate();
  80. else
  81. $commit = $this->preInsert();
  82. if (!$commit) {
  83. if ( $useTransactions)
  84. $this->_db->rollback();
  85. return false;
  86. }
  87. $row = array();
  88. foreach( $this->_properties as $k => $v) {
  89. if ($update && !$v['updated'])
  90. 계속;
  91. 스위치 ($v['type']) {
  92. 케이스 자체:: TYPE_TIMESTAMP:
  93. if (!is_null($v['value'])) {
  94. if ($this->_db instanceof Zend_Db_Adapter_Pdo_Pgsql)
  95. $v['value'] = date('Y-m-d H :i:sO', $v['value']);
  96. else
  97. $v['value'] = date('Y-m-d H:i:s', $v['value']);
  98. }
  99. break;
  100. case self::TYPE_BOOLEAN:
  101. $v['value'] = (int) ((bool) $v['value']);
  102. break;
  103. }
  104. $row[$k] = $v['value'];
  105. }
  106. if (count($row) > 0) {
  107. // 삽입/업데이트 수행
  108. if ($update) {
  109. $this->_db->update($this->_table, $row, sprintf('%s = %d ', $this->_idField, $this->getId()));
  110. }
  111. else {
  112. $this->_db->insert($this->_table, $row);
  113. $this->_id = $this->_db->lastInsertId ($this->_table, $this->_idField);
  114. }
  115. }
  116. // 내부 ID 업데이트
  117. if ($commit) {
  118. if ($update)
  119. $commit = $this->postUpdate();
  120. else
  121. $commit = $this->postInsert();
  122. }
  123. if ($useTransactions) {
  124. if ($commit)
  125. $this->_db->commit();
  126. else
  127. $this->_db->rollback();
  128. }
  129. return $commit;
  130. }
  131. 공개 함수 delete($useTransactions = true)
  132. {
  133. if (!$this->isSaved() )
  134. false 반환;
  135. if ($useTransactions)
  136. $this->_db->beginTransaction();
  137. $commit = $this->preDelete( );
  138. if ($commit) {
  139. $this->_db->delete($this->_table, sprintf('%s = %d', $this-> _idField, $this->getId()));
  140. }
  141. else {
  142. if ($useTransactions)
  143. $this->_db->rollback();
  144. return false;
  145. }
  146. $commit = $this->postDelete();
  147. $this->_id = null;
  148. if ($useTransactions) {
  149. if ($commit)
  150. $this->_db->commit();
  151. else
  152. $this->_db->rollback();
  153. }
  154. return $commit;
  155. }
  156. 공개 함수 isSaved()
  157. {
  158. return $this->getId() > 0;
  159. }
  160. 공용 함수 getId()
  161. {
  162. return (int) $this->_id;
  163. }
  164. 공용 함수 getDb()
  165. {
  166. return $this->_db;
  167. }
  168. 공개 함수 __set($name, $value)
  169. {
  170. if (array_key_exists($name, $ this->_properties)) {
  171. $this->_properties[$name]['value'] = $value;
  172. $this->_properties[$name]['updated'] = true ;
  173. true 반환;
  174. }
  175. false 반환;
  176. }
  177. 공개 함수 __get($name)
  178. {
  179. return array_key_exists($name, $this->_properties) ? $this->_properties[$name]['value'] : null;
  180. }
  181. 보호 함수 add($field, $default = null, $type = null)
  182. {
  183. $this->_properties[$field] = array('value' => $default,
  184. 'type' => in_array($type, self::$types) ? $type : null,
  185. 'updated' => false);
  186. }
  187. 보호 함수 preInsert()
  188. {
  189. return true;
  190. }
  191. 보호 함수 postInsert ()
  192. {
  193. true 반환;
  194. }
  195. 보호 함수 preUpdate()
  196. {
  197. true 반환;
  198. }
  199. 보호 함수 postUpdate ()
  200. {
  201. true 반환;
  202. }
  203. 보호 함수 preDelete()
  204. {
  205. true 반환;
  206. }
  207. 보호 함수 postDelete ()
  208. {
  209. true 반환;
  210. }
  211. 보호 함수 postLoad()
  212. {
  213. true 반환;
  214. }
  215. 공개 정적 함수 BuildMultiple($db, $class, $data)
  216. {
  217. $ret = array();
  218. if (!class_exists($class))
  219. throw new Exception('정의되지 않은 클래스 지정됨: ' . $class);
  220. $testObj = new $class($db);
  221. if (!$testObj instanceof DatabaseObject)
  222. throw new Exception('클래스는 DatabaseObject에서 확장되지 않습니다.' );
  223. foreach ($data as $row) {
  224. $obj = new $class($db);
  225. $obj->_init($row);
  226. $ret[$obj->getId()] = $obj;
  227. }
  228. return $ret;
  229. }
  230. }
제조대码
  1. class DatabaseObject_User 확장 DatabaseObject
  2. {
  3. static $userTypes = array('member' => 'Member',
  4. ' 관리자' => '관리자');
  5. 공개 $profile = null;
  6. 공개 $_newPassword = null;
  7. 공개 함수 __construct($db)
  8. {
  9. parent::__construct($db, 'users', 'user_id');
  10. $this->add('username');
  11. $this->add('password') ;
  12. $this->add('user_type', 'member');
  13. $this->add('ts_created', time(), self::TYPE_TIMESTAMP);
  14. $this- >add('ts_last_login', null, self::TYPE_TIMESTAMP);
  15. $this->profile = new Profile_User($db);
  16. }
  17. 보호 함수 preInsert( )
  18. {
  19. $this->_newPassword = Text_Password::create(8);
  20. $this->password = $this->_newPassword;
  21. return true;
  22. }
  23. 보호된 함수 postLoad()
  24. {
  25. $this->profile->setUserId($this->getId());
  26. $this->profile-> ;load();
  27. }
  28. 보호 함수 postInsert()
  29. {
  30. $this->profile->setUserId($this->getId());
  31. $this->profile->save(false);
  32. $this->sendEmail('user-register.tpl');
  33. return true;
  34. }
  35. 보호 함수 postUpdate()
  36. {
  37. $this->profile->save(false);
  38. true 반환;
  39. }
  40. 보호 함수 preDelete()
  41. {
  42. $this->profile->delete();
  43. true를 반환합니다.
  44. }
  45. 공개 함수 sendEmail($tpl)
  46. {
  47. $templater = new Templater();
  48. $templater->user = $this;
  49. // 이메일 본문 가져오기
  50. $body = $templater->render('email /' . $tpl);
  51. // 첫 번째 줄에서 제목 추출
  52. list($subject, $body) = preg_split('/r|n/', $body, 2);
  53. // 이제 이메일을 설정하고 보냅니다.
  54. $mail = new Zend_Mail();
  55. // '받는 사람' 줄에 받는 사람 주소와 사용자의 전체 이름을 설정합니다
  56. $mail->addTo($this->profile->email,
  57. Trim($this->profile->first_name . ' ' .
  58. $this->profile-> last_name));
  59. // 구성에서 관리자 'from' 세부정보 가져오기
  60. $mail->setFrom(Zend_Registry::get('config')->email->from- >email,
  61. Zend_Registry::get('config')->email->from->name);
  62. // 제목과 본문을 설정하고 메일을 보냅니다
  63. $mail->setSubject(trim($subject));
  64. $mail->setBodyText(trim($body));
  65. $mail->send();
  66. }
  67. 공개 함수 createAuthIdentity()
  68. {
  69. $identity = new stdClass;
  70. $identity->user_id = $this->getId();
  71. $identity->username = $this->username;
  72. $identity->user_type = $this->user_type;
  73. $identity->first_name = $this->profile->first_name;
  74. $identity ->last_name = $this->profile->last_name;
  75. $identity->email = $this->profile->email;
  76. return $identity;
  77. }
  78. 공개 함수 loginSuccess()
  79. {
  80. $this->ts_last_login = time();
  81. unset($this->profile->new_password);
  82. unset($this->profile->new_password_ts);
  83. unset($this->profile->new_password_key);
  84. $this->save();
  85. $ message = sprintf('%s 사용자 %s의 성공적인 로그인 시도',
  86. $_SERVER['REMOTE_ADDR'],
  87. $this->username);
  88. $logger = Zend_Registry:: get('logger');
  89. $logger->notice($message);
  90. }
  91. 정적 공개 함수 LoginFailure($username, $code = '')
  92. {
  93. 스위치($code) {
  94. 케이스 Zend_Auth_Result::FAILURE_IDENTITY_NOT_FOUND:
  95. $reason = '알 수 없는 사용자 이름';
  96. break;
  97. case Zend_Auth_Result::FAILURE_IDENTITY_AMBIGUOUS:
  98. $reason = '이 사용자 이름으로 여러 사용자를 찾았습니다.';
  99. break;
  100. case Zend_Auth_Result::FAILURE_CREDENTIAL_INVALID:
  101. $reason = ' 잘못된 비밀번호';
  102. break;
  103. 기본값:
  104. $reason = '';
  105. }
  106. $message = sprintf('%s 사용자 %s의 로그인 시도 실패',
  107. $_SERVER['REMOTE_ADDR'],
  108. $username);
  109. if (strlen($reason) > 0)
  110. $message .= sprintf(' (%s)' , $reason);
  111. $logger = Zend_Registry::get('logger');
  112. $logger->warn($message);
  113. }
  114. 공개 함수 fetchPassword()
  115. {
  116. if (!$this->isSaved())
  117. return false;
  118. // 새 비밀번호 속성 생성
  119. $this->_newPassword = Text_Password::create(8);
  120. $this->profile->new_password = md5($this->_newPassword);
  121. $this->profile->new_password_ts = time();
  122. $this->profile->new_password_key = md5(uniqid() .
  123. $this->getId() .
  124. $this->_newPassword);
  125. / / 프로필에 새 비밀번호를 저장하고 이메일을 보냅니다
  126. $this->profile->save();
  127. $this->sendEmail('user-fetch-password.tpl');
  128. return true;
  129. }
  130. public function verifyNewPassword($key)
  131. {
  132. // 유효한 비밀번호 재설정 데이터가 설정되었는지 확인
  133. if (!isset($ this->프로필->new_password)
  134. || !isset($this->profile->new_password_ts)
  135. || !isset($this->profile->new_password_key)) {
  136. return false;
  137. }
  138. // 하루 안에 비밀번호가 확인되는지 확인
  139. if (time() - $this->profile->new_password_ts > 86400)
  140. return false;
  141. // 키가 올바른지 확인
  142. if ($this-> profile->new_password_key != $key)
  143. return false;
  144. // 모든 것이 유효합니다. 이제 새 비밀번호를 사용하도록 계정을 업데이트하세요
  145. // 다음과 같이 로컬 설정자를 우회합니다. new_password는 이미 md5입니다
  146. parent::__set('password', $this->profile->new_password);
  147. unset($this->profile->new_password);
  148. unset($this->profile->new_password_ts);
  149. unset($this->profile->new_password_key);
  150. // 마지막으로 업데이트된 사용자 기록을 저장하고 업데이트된 프로필
  151. return $this->save();
  152. }
  153. 공개 함수 usernameExists($username)
  154. {
  155. $query = sprintf('select count(*) %s의 숫자로, 여기서 사용자 이름 = ?',
  156. $this->_table);
  157. $result = $this->_db->fetchOne($query, $username);
  158. $result > 반환 0;
  159. }
  160. 정적 공개 함수 IsValidUsername($username)
  161. {
  162. $validator = new Zend_Validate_Alnum();
  163. return $validator->isValid($username);
  164. }
  165. 공개 함수 __set($name, $value)
  166. {
  167. 스위치($name) {
  168. case 'password':
  169. $value = md5($ value);
  170. break;
  171. case 'user_type':
  172. if (!array_key_exists($value, self::$userTypes))
  173. $value = 'member';
  174. break;
  175. }
  176. return parent::__set($name, $value);
  177. }
  178. }
  179. ?>
复代码


성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.