Heim Backend-Entwicklung PHP-Tutorial Quentin Zervaas's DBO

Quentin Zervaas's DBO

Jul 25, 2016 am 09:10 AM

《Web 2.0 开发实战》一书的作者,Quentin Zervaas 在书中提到的一个简易PHP数据访问对象。
  1. /**
  2. * DatabaseObject
  3. *
  4. * Abstract class used to easily manipulate data in a database table
  5. * via simple load/save/delete methods
  6. */
  7. abstract class 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. public function __construct(Zend_Db_Adapter_Abstract $db, $table, $idField)
  18. {
  19. $this->_db = $db;
  20. $this->_table = $table;
  21. $this->_idField = $idField;
  22. }
  23. public function load($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 return false;
  30. }
  31. $query = sprintf('select %s from %s where %s = ?',
  32. join(', ', $this->getSelectFields()),
  33. $this->_table,
  34. $field);
  35. $query = $this->_db->quoteInto($query, $id);
  36. return $this->_load($query);
  37. }
  38. protected function getSelectFields($prefix = '')
  39. {
  40. $fields = array($prefix . $this->_idField);
  41. foreach ($this->_properties as $k => $v)
  42. $fields[] = $prefix . $k;
  43. return $fields;
  44. }
  45. protected function _load($query)
  46. {
  47. $result = $this->_db->query($query);
  48. $row = $result->fetch();
  49. if (!$row)
  50. return false;
  51. $this->_init($row);
  52. $this->postLoad();
  53. return true;
  54. }
  55. public function _init($row)
  56. {
  57. foreach ($this->_properties as $k => $v) {
  58. $val = $row[$k];
  59. switch ($v['type']) {
  60. case self::TYPE_TIMESTAMP:
  61. if (!is_null($val))
  62. $val = strtotime($val);
  63. break;
  64. case self::TYPE_BOOLEAN:
  65. $val = (bool) $val;
  66. break;
  67. }
  68. $this->_properties[$k]['value'] = $val;
  69. }
  70. $this->_id = (int) $row[$this->_idField];
  71. }
  72. public function save($useTransactions = true)
  73. {
  74. $update = $this->isSaved();
  75. if ($useTransactions)
  76. $this->_db->beginTransaction();
  77. if ($update)
  78. $commit = $this->preUpdate();
  79. else
  80. $commit = $this->preInsert();
  81. if (!$commit) {
  82. if ($useTransactions)
  83. $this->_db->rollback();
  84. return false;
  85. }
  86. $row = array();
  87. foreach ($this->_properties as $k => $v) {
  88. if ($update && !$v['updated'])
  89. continue;
  90. switch ($v['type']) {
  91. case self::TYPE_TIMESTAMP:
  92. if (!is_null($v['value'])) {
  93. if ($this->_db instanceof Zend_Db_Adapter_Pdo_Pgsql)
  94. $v['value'] = date('Y-m-d H:i:sO', $v['value']);
  95. else
  96. $v['value'] = date('Y-m-d H:i:s', $v['value']);
  97. }
  98. break;
  99. case self::TYPE_BOOLEAN:
  100. $v['value'] = (int) ((bool) $v['value']);
  101. break;
  102. }
  103. $row[$k] = $v['value'];
  104. }
  105. if (count($row) > 0) {
  106. // perform insert/update
  107. if ($update) {
  108. $this->_db->update($this->_table, $row, sprintf('%s = %d', $this->_idField, $this->getId()));
  109. }
  110. else {
  111. $this->_db->insert($this->_table, $row);
  112. $this->_id = $this->_db->lastInsertId($this->_table, $this->_idField);
  113. }
  114. }
  115. // update internal id
  116. if ($commit) {
  117. if ($update)
  118. $commit = $this->postUpdate();
  119. else
  120. $commit = $this->postInsert();
  121. }
  122. if ($useTransactions) {
  123. if ($commit)
  124. $this->_db->commit();
  125. else
  126. $this->_db->rollback();
  127. }
  128. return $commit;
  129. }
  130. public function delete($useTransactions = true)
  131. {
  132. if (!$this->isSaved())
  133. return false;
  134. if ($useTransactions)
  135. $this->_db->beginTransaction();
  136. $commit = $this->preDelete();
  137. if ($commit) {
  138. $this->_db->delete($this->_table, sprintf('%s = %d', $this->_idField, $this->getId()));
  139. }
  140. else {
  141. if ($useTransactions)
  142. $this->_db->rollback();
  143. return false;
  144. }
  145. $commit = $this->postDelete();
  146. $this->_id = null;
  147. if ($useTransactions) {
  148. if ($commit)
  149. $this->_db->commit();
  150. else
  151. $this->_db->rollback();
  152. }
  153. return $commit;
  154. }
  155. public function isSaved()
  156. {
  157. return $this->getId() > 0;
  158. }
  159. public function getId()
  160. {
  161. return (int) $this->_id;
  162. }
  163. public function getDb()
  164. {
  165. return $this->_db;
  166. }
  167. public function __set($name, $value)
  168. {
  169. if (array_key_exists($name, $this->_properties)) {
  170. $this->_properties[$name]['value'] = $value;
  171. $this->_properties[$name]['updated'] = true;
  172. return true;
  173. }
  174. return false;
  175. }
  176. public function __get($name)
  177. {
  178. return array_key_exists($name, $this->_properties) ? $this->_properties[$name]['value'] : null;
  179. }
  180. protected function add($field, $default = null, $type = null)
  181. {
  182. $this->_properties[$field] = array('value' => $default,
  183. 'type' => in_array($type, self::$types) ? $type : null,
  184. 'updated' => false);
  185. }
  186. protected function preInsert()
  187. {
  188. return true;
  189. }
  190. protected function postInsert()
  191. {
  192. return true;
  193. }
  194. protected function preUpdate()
  195. {
  196. return true;
  197. }
  198. protected function postUpdate()
  199. {
  200. return true;
  201. }
  202. protected function preDelete()
  203. {
  204. return true;
  205. }
  206. protected function postDelete()
  207. {
  208. return true;
  209. }
  210. protected function postLoad()
  211. {
  212. return true;
  213. }
  214. public static function BuildMultiple($db, $class, $data)
  215. {
  216. $ret = array();
  217. if (!class_exists($class))
  218. throw new Exception('Undefined class specified: ' . $class);
  219. $testObj = new $class($db);
  220. if (!$testObj instanceof DatabaseObject)
  221. throw new Exception('Class does not extend from DatabaseObject');
  222. foreach ($data as $row) {
  223. $obj = new $class($db);
  224. $obj->_init($row);
  225. $ret[$obj->getId()] = $obj;
  226. }
  227. return $ret;
  228. }
  229. }
复制代码
  1. class DatabaseObject_User extends DatabaseObject
  2. {
  3. static $userTypes = array('member' => 'Member',
  4. 'administrator' => 'Administrator');
  5. public $profile = null;
  6. public $_newPassword = null;
  7. public function __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. protected function preInsert()
  18. {
  19. $this->_newPassword = Text_Password::create(8);
  20. $this->password = $this->_newPassword;
  21. return true;
  22. }
  23. protected function postLoad()
  24. {
  25. $this->profile->setUserId($this->getId());
  26. $this->profile->load();
  27. }
  28. protected function postInsert()
  29. {
  30. $this->profile->setUserId($this->getId());
  31. $this->profile->save(false);
  32. $this->sendEmail('user-register.tpl');
  33. return true;
  34. }
  35. protected function postUpdate()
  36. {
  37. $this->profile->save(false);
  38. return true;
  39. }
  40. protected function preDelete()
  41. {
  42. $this->profile->delete();
  43. return true;
  44. }
  45. public function sendEmail($tpl)
  46. {
  47. $templater = new Templater();
  48. $templater->user = $this;
  49. // fetch the e-mail body
  50. $body = $templater->render('email/' . $tpl);
  51. // extract the subject from the first line
  52. list($subject, $body) = preg_split('/\r|\n/', $body, 2);
  53. // now set up and send the e-mail
  54. $mail = new Zend_Mail();
  55. // set the to address and the user's full name in the 'to' line
  56. $mail->addTo($this->profile->email,
  57. trim($this->profile->first_name . ' ' .
  58. $this->profile->last_name));
  59. // get the admin 'from' details from the config
  60. $mail->setFrom(Zend_Registry::get('config')->email->from->email,
  61. Zend_Registry::get('config')->email->from->name);
  62. // set the subject and body and send the mail
  63. $mail->setSubject(trim($subject));
  64. $mail->setBodyText(trim($body));
  65. $mail->send();
  66. }
  67. public function 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. public function 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('Successful login attempt from %s user %s',
  86. $_SERVER['REMOTE_ADDR'],
  87. $this->username);
  88. $logger = Zend_Registry::get('logger');
  89. $logger->notice($message);
  90. }
  91. static public function LoginFailure($username, $code = '')
  92. {
  93. switch ($code) {
  94. case Zend_Auth_Result::FAILURE_IDENTITY_NOT_FOUND:
  95. $reason = 'Unknown username';
  96. break;
  97. case Zend_Auth_Result::FAILURE_IDENTITY_AMBIGUOUS:
  98. $reason = 'Multiple users found with this username';
  99. break;
  100. case Zend_Auth_Result::FAILURE_CREDENTIAL_INVALID:
  101. $reason = 'Invalid password';
  102. break;
  103. default:
  104. $reason = '';
  105. }
  106. $message = sprintf('Failed login attempt from %s user %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. public function fetchPassword()
  115. {
  116. if (!$this->isSaved())
  117. return false;
  118. // generate new password properties
  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. // save new password to profile and send e-mail
  126. $this->profile->save();
  127. $this->sendEmail('user-fetch-password.tpl');
  128. return true;
  129. }
  130. public function confirmNewPassword($key)
  131. {
  132. // check that valid password reset data is set
  133. if (!isset($this->profile->new_password)
  134. || !isset($this->profile->new_password_ts)
  135. || !isset($this->profile->new_password_key)) {
  136. return false;
  137. }
  138. // check if the password is being confirm within a day
  139. if (time() - $this->profile->new_password_ts > 86400)
  140. return false;
  141. // check that the key is correct
  142. if ($this->profile->new_password_key != $key)
  143. return false;
  144. // everything is valid, now update the account to use the new password
  145. // bypass the local setter as new_password is already an 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. // finally, save the updated user record and the updated profile
  151. return $this->save();
  152. }
  153. public function usernameExists($username)
  154. {
  155. $query = sprintf('select count(*) as num from %s where username = ?',
  156. $this->_table);
  157. $result = $this->_db->fetchOne($query, $username);
  158. return $result > 0;
  159. }
  160. static public function IsValidUsername($username)
  161. {
  162. $validator = new Zend_Validate_Alnum();
  163. return $validator->isValid($username);
  164. }
  165. public function __set($name, $value)
  166. {
  167. switch ($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. ?>
复制代码


Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn

Heiße KI -Werkzeuge

Undresser.AI Undress

Undresser.AI Undress

KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover

AI Clothes Remover

Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool

Undress AI Tool

Ausziehbilder kostenlos

Clothoff.io

Clothoff.io

KI-Kleiderentferner

AI Hentai Generator

AI Hentai Generator

Erstellen Sie kostenlos Ai Hentai.

Heißer Artikel

R.E.P.O. Energiekristalle erklärten und was sie tun (gelber Kristall)
3 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Beste grafische Einstellungen
3 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. So reparieren Sie Audio, wenn Sie niemanden hören können
3 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌

Heiße Werkzeuge

Notepad++7.3.1

Notepad++7.3.1

Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version

SublimeText3 chinesische Version

Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1

Senden Sie Studio 13.0.1

Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6

Dreamweaver CS6

Visuelle Webentwicklungstools

SublimeText3 Mac-Version

SublimeText3 Mac-Version

Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Arbeiten mit Flash -Sitzungsdaten in Laravel Arbeiten mit Flash -Sitzungsdaten in Laravel Mar 12, 2025 pm 05:08 PM

Laravel vereinfacht die Behandlung von temporären Sitzungsdaten mithilfe seiner intuitiven Flash -Methoden. Dies ist perfekt zum Anzeigen von kurzen Nachrichten, Warnungen oder Benachrichtigungen in Ihrer Anwendung. Die Daten bestehen nur für die nachfolgende Anfrage standardmäßig: $ Anfrage-

PHP -Protokollierung: Best Practices für die PHP -Protokollanalyse PHP -Protokollierung: Best Practices für die PHP -Protokollanalyse Mar 10, 2025 pm 02:32 PM

Die PHP -Protokollierung ist für die Überwachung und Debugie von Webanwendungen von wesentlicher Bedeutung sowie für das Erfassen kritischer Ereignisse, Fehler und Laufzeitverhalten. Es bietet wertvolle Einblicke in die Systemleistung, hilft bei der Identifizierung von Problemen und unterstützt eine schnellere Fehlerbehebung

Curl in PHP: So verwenden Sie die PHP -Curl -Erweiterung in REST -APIs Curl in PHP: So verwenden Sie die PHP -Curl -Erweiterung in REST -APIs Mar 14, 2025 am 11:42 AM

Die PHP Client -URL -Erweiterung (CURL) ist ein leistungsstarkes Tool für Entwickler, das eine nahtlose Interaktion mit Remote -Servern und REST -APIs ermöglicht. Durch die Nutzung von Libcurl, einer angesehenen Bibliothek mit Multi-Protokoll-Dateien, erleichtert PHP Curl effiziente Execu

Vereinfachte HTTP -Reaktion verspottet in Laravel -Tests Vereinfachte HTTP -Reaktion verspottet in Laravel -Tests Mar 12, 2025 pm 05:09 PM

Laravel bietet eine kurze HTTP -Antwortsimulationssyntax und vereinfache HTTP -Interaktionstests. Dieser Ansatz reduziert die Code -Redundanz erheblich, während Ihre Testsimulation intuitiver wird. Die grundlegende Implementierung bietet eine Vielzahl von Verknüpfungen zum Antworttyp: Verwenden Sie Illuminate \ Support \ facades \ http; Http :: fake ([ 'Google.com' => 'Hallo Welt',, 'github.com' => ['foo' => 'bar'], 'Forge.laravel.com' =>

12 Beste PHP -Chat -Skripte auf Codecanyon 12 Beste PHP -Chat -Skripte auf Codecanyon Mar 13, 2025 pm 12:08 PM

Möchten Sie den dringlichsten Problemen Ihrer Kunden in Echtzeit und Sofortlösungen anbieten? Mit Live-Chat können Sie Echtzeitgespräche mit Kunden führen und ihre Probleme sofort lösen. Sie ermöglichen es Ihnen, Ihrem Brauch einen schnelleren Service zu bieten

Erklären Sie das Konzept der späten statischen Bindung in PHP. Erklären Sie das Konzept der späten statischen Bindung in PHP. Mar 21, 2025 pm 01:33 PM

In Artikel wird die in PHP 5.3 eingeführte LSB -Bindung (LSB) erörtert, die die Laufzeitauflösung der statischen Methode ermöglicht, um eine flexiblere Vererbung zu erfordern. Die praktischen Anwendungen und potenziellen Perfo von LSB

Anpassung/Erweiterung von Frameworks: So fügen Sie benutzerdefinierte Funktionen hinzu. Anpassung/Erweiterung von Frameworks: So fügen Sie benutzerdefinierte Funktionen hinzu. Mar 28, 2025 pm 05:12 PM

In dem Artikel werden Frameworks hinzugefügt, das sich auf das Verständnis der Architektur, das Identifizieren von Erweiterungspunkten und Best Practices für die Integration und Debuggierung hinzufügen.

See all articles