📄 abstract.php
字号:
<?php/** * Zend Framework * * LICENSE * * This source file is subject to the new BSD license that is bundled * with this package in the file LICENSE.txt. * It is also available through the world-wide-web at this URL: * http://framework.zend.com/license/new-bsd * If you did not receive a copy of the license and are unable to * obtain it through the world-wide-web, please send an email * to license@zend.com so we can send you a copy immediately. * * @category Zend * @package Zend_Db * @subpackage Table * @copyright Copyright (c) 2005-2007 Zend Technologies USA Inc. (http://www.zend.com) * @license http://framework.zend.com/license/new-bsd New BSD License * @version $Id: Abstract.php 163 2008-01-14 04:40:16Z matt $ *//** * @see Zend_Db */require_once 'Zend/Db.php';/** * @see Zend_Loader */require_once 'Zend/Loader.php';/** * @category Zend * @package Zend_Db * @subpackage Table * @copyright Copyright (c) 2005-2007 Zend Technologies USA Inc. (http://www.zend.com) * @license http://framework.zend.com/license/new-bsd New BSD License */abstract class Zend_Db_Table_Row_Abstract{ /** * The data for each column in the row (column_name => value). * The keys must match the physical names of columns in the * table for which this row is defined. * * @var array */ protected $_data = array(); /** * This is set to a copy of $_data when the data is fetched from * a database, specified as a new tuple in the constructor, or * when dirty data is posted to the database with save(). * * @var array */ protected $_cleanData = array(); /** * Zend_Db_Table_Abstract parent class or instance. * * @var Zend_Db_Table_Abstract */ protected $_table = null; /** * Connected is true if we have a reference to a live * Zend_Db_Table_Abstract object. * This is false after the Rowset has been deserialized. * * @var boolean */ protected $_connected = true; /** * Name of the class of the Zend_Db_Table_Abstract object. * * @var string */ protected $_tableClass = null; /** * Primary row key(s). * * @var array */ protected $_primary; /** * Constructor. * * Supported params for $config are:- * - table = class name or object of type Zend_Db_Table_Abstract * - data = values of columns in this row. * * @param array $config OPTIONAL Array of user-specified config options. * @return void * @throws Zend_Db_Table_Row_Exception */ public function __construct(array $config = array()) { if (isset($config['table']) && $config['table'] instanceof Zend_Db_Table_Abstract) { $this->_table = $config['table']; $this->_tableClass = get_class($this->_table); } if (isset($config['data'])) { if (!is_array($config['data'])) { require_once 'Zend/Db/Table/Row/Exception.php'; throw new Zend_Db_Table_Row_Exception('Data must be an array'); } $this->_data = $config['data']; } if (isset($config['stored']) && $config['stored'] === true) { $this->_cleanData = $this->_data; } // Retrieve primary keys from table schema if ($table = $this->_getTable()) { $info = $table->info(); $this->_primary = (array) $info['primary']; } } /** * Transform a column name from the user-specified form * to the physical form used in the database. * You can override this method in a custom Row class * to implement column name mappings, for example inflection. * * @param string $columnName Column name given. * @return string The column name after transformation applied (none by default). * @throws Zend_Db_Table_Row_Exception if the $columnName is not a string. */ protected function _transformColumn($columnName) { if (!is_string($columnName)) { require_once 'Zend/Db/Table/Row/Exception.php'; throw new Zend_Db_Table_Row_Exception('Specified column is not a string'); } // Perform no transformation by default return $columnName; } /** * Retrieve row field value * * @param string $columnName The user-specified column name. * @return string The corresponding column value. * @throws Zend_Db_Table_Row_Exception if the $columnName is not a column in the row. */ public function __get($columnName) { $columnName = $this->_transformColumn($columnName); if (!array_key_exists($columnName, $this->_data)) { require_once 'Zend/Db/Table/Row/Exception.php'; throw new Zend_Db_Table_Row_Exception("Specified column \"$columnName\" is not in the row"); } return $this->_data[$columnName]; } /** * Set row field value * * @param string $columnName The column key. * @param mixed $value The value for the property. * @return void * @throws Zend_Db_Table_Row_Exception */ public function __set($columnName, $value) { $columnName = $this->_transformColumn($columnName); if (!array_key_exists($columnName, $this->_data)) { require_once 'Zend/Db/Table/Row/Exception.php'; throw new Zend_Db_Table_Row_Exception("Specified column \"$columnName\" is not in the row"); } $this->_data[$columnName] = $value; } /** * Test existence of row field * * @param string $columnName The column key. * @return boolean */ public function __isset($columnName) { $columnName = $this->_transformColumn($columnName); return array_key_exists($columnName, $this->_data); } /** * Store table, primary key and data in serialized object * * @return array */ public function __sleep() { return array('_tableClass', '_primary', '_data', '_cleanData'); } /** * Setup to do on wakeup. * A de-serialized Row should not be assumed to have access to a live * database connection, so set _connected = false. * * @return void */ public function __wakeup() { $this->_connected = false; } /** * Returns the table object, or null if this is disconnected row * * @return Zend_Db_Table_Abstract|null */ public function getTable() { return $this->_table; } /** * Set the table object, to re-establish a live connection * to the database for a Row that has been de-serialized. * * @param Zend_Db_Table_Abstract $table * @return boolean * @throws Zend_Db_Table_Row_Exception */ public function setTable(Zend_Db_Table_Abstract $table) { if ($table == null) { $this->_table = null; $this->_connected = false; return false; } $tableClass = get_class($table); if (! $table instanceof $this->_tableClass) { require_once 'Zend/Db/Table/Row/Exception.php'; throw new Zend_Db_Table_Row_Exception("The specified Table is of class $tableClass, expecting class to be instance of $this->_tableClass"); } $this->_table = $table; $this->_tableClass = $tableClass; $info = $this->_table->info(); if ($info['cols'] != array_keys($this->_data)) { require_once 'Zend/Db/Table/Row/Exception.php'; throw new Zend_Db_Table_Row_Exception('The specified Table does not have the same columns as the Row'); } if (! array_intersect((array) $this->_primary, $info['primary']) == (array) $this->_primary) { require_once 'Zend/Db/Table/Row/Exception.php'; throw new Zend_Db_Table_Row_Exception("The specified Table '$tableClass' does not have the same primary key as the Row"); } $this->_connected = true; return true; } /** * Query the class name of the Table object for which this * Row was created. * * @return string */ public function getTableClass() { return $this->_tableClass; } /** * Saves the properties to the database. * * This performs an intelligent insert/update, and reloads the * properties with fresh data from the table on success. * * @return mixed The primary key value(s), as an associative array if the * key is compound, or a scalar if the key is single-column. */ public function save() { /** * If the _cleanData array is empty, * this is an INSERT of a new row. * Otherwise it is an UPDATE. */ if (empty($this->_cleanData)) { return $this->_doInsert(); } else { return $this->_doUpdate(); } } /** * @return mixed The primary key value(s), as an associative array if the * key is compound, or a scalar if the key is single-column. */ protected function _doInsert() { /** * Run pre-INSERT logic */ $this->_insert(); /** * Execute the INSERT (this may throw an exception) */ $primaryKey = $this->_getTable()->insert($this->_data); /** * Normalize the result to an array indexed by primary key column(s). * The table insert() method may return a scalar. */ if (is_array($primaryKey)) { $newPrimaryKey = $primaryKey; } else { $newPrimaryKey = array(current((array)$this->_primary) => $primaryKey); } /** * Save the new primary key value in _data. The primary key may have * been generated by a sequence or auto-increment mechanism, and this * merge should be done before the _postInsert() method is run, so the * new values are available for logging, etc. */ $this->_data = array_merge($this->_data, $newPrimaryKey); /** * Run post-INSERT logic */ $this->_postInsert(); /** * Update the _cleanData to reflect that the data has been inserted. */ $this->_refresh(); return $primaryKey; } /** * @return mixed The primary key value(s), as an associative array if the * key is compound, or a scalar if the key is single-column. */ protected function _doUpdate() { /** * Get expressions for a WHERE clause * based on the primary key value(s). */ $where = $this->_getWhereQuery(false); /** * Run pre-UPDATE logic */ $this->_update(); /** * Compare the data to the clean data to discover * which columns have been changed. */ $diffData = array_diff_assoc($this->_data, $this->_cleanData); /** * Were any of the changed columns part of the primary key? */ $pkDiffData = array_intersect_key($diffData, array_flip((array)$this->_primary)); /** * Execute cascading updates against dependent tables. * Do this only if primary key value(s) were changed. */ if (count($pkDiffData) > 0) { $depTables = $this->_getTable()->getDependentTables(); if (!empty($depTables)) { $db = $this->_getTable()->getAdapter(); $pkNew = $this->_getPrimaryKey(true); $pkOld = $this->_getPrimaryKey(false); $thisClass = get_class($this); foreach ($depTables as $tableClass) { try { Zend_Loader::loadClass($tableClass); } catch (Zend_Exception $e) { require_once 'Zend/Db/Table/Row/Exception.php'; throw new Zend_Db_Table_Row_Exception($e->getMessage()); } $t = new $tableClass(array('db' => $db)); $t->_cascadeUpdate($this->getTableClass(), $pkOld, $pkNew); } } } /** * Execute the UPDATE (this may throw an exception) * Do this only if data values were changed. * Use the $diffData variable, so the UPDATE statement * includes SET terms only for data values that changed. */ $result = 0; if (count($diffData) > 0) { $result = $this->_getTable()->update($diffData, $where); } /** * Run post-UPDATE logic. Do this before the _refresh() * so the _postUpdate() function can tell the difference * between changed data and clean (pre-changed) data. */ $this->_postUpdate(); /** * Refresh the data just in case triggers in the RDBMS changed * any columns. Also this resets the _cleanData. */ $this->_refresh(); /** * Return the primary key value(s) as an array * if the key is compound or a scalar if the key * is a scalar. */ $primaryKey = $this->_getPrimaryKey(true); if (count($primaryKey) == 1) { return current($primaryKey); } else { return $primaryKey; } } /** * Deletes existing rows. * * @return int The number of rows deleted. */ public function delete() { $where = $this->_getWhereQuery(); /** * Execute pre-DELETE logic */ $this->_delete();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -