Zend_Db_Table_Row
Introducción
Zend_Db_Table_Row
is a class that contains an
individual row of a
Zend_Db_Table
object.
When you run a query against a Table class, the result is returned
in a set of
Zend_Db_Table_Row
objects. You
can also use this object to create new rows and add them to the
database
table.
Zend_Db_Table_Row
is an implementation of the
Row Data
Gateway
pattern.
Fetching a Row
Zend_Db_Table_Abstract
provides methods
find()
and
fetchAll()
, which each return an object
of type
Zend_Db_Table_Rowset
, and the method
fetchRow()
, which returns an object of
type
Zend_Db_Table_Row
.
Example of fetching a row
fetchRow($bugs->select()->where('bug_id = ?', 1));
]]>
A
Zend_Db_Table_Rowset
object contains a
collection of
Zend_Db_Table_Row
objects. See
.
Example of reading a row in a rowset
fetchAll($bugs->select()->where('bug_status = ?', 1));
$row = $rowset->current();
]]>
Reading column values from a row
Zend_Db_Table_Row_Abstract
provides
accessor methods so you can reference columns in the row as
object
properties.
Example of reading a column in a row
fetchRow($bugs->select()->where('bug_id = ?', 1));
// Echo the value of the bug_description column
echo $row->bug_description;
]]>
Earlier versions of
Zend_Db_Table_Row
mapped these
column accessors to the database column names using a string
transformation called
inflection
.
Currently,
Zend_Db_Table_Row
does
not implement inflection. Accessed property names need to
match the spelling
of the column names as they appear in
your database.
Retrieving Row Data as an Array
You can access the row's data as an array using the
toArray()
method of the Row object.
This returns an associative array of the column names to
the
column values.
Example of using the toArray() method
fetchRow($bugs->select()->where('bug_id = ?', 1));
// Get the column/value associative array from the Row object
$rowArray = $row->toArray();
// Now use it as a normal array
foreach ($rowArray as $column => $value) {
echo "Column: $column\n";
echo "Value: $value\n";
}
]]>
The array returned from
toArray()
is
not updateable. You can modify values in the array as you can
with any array, but
you cannot save changes to this array to the
database directly.
Fetching data from related tables
The
Zend_Db_Table_Row_Abstract
class
provides methods for fetching rows and rowsets from related
tables. See
for
more information on table relationships.
Writing rows to the database
Changing column values in a row
You can set individual column values using column accessors,
similar to how the
columns are read as object properties in the
example above.
Using a column accessor to set a value changes the column
value of the row object in
your application, but it does not
commit the change to the database yet. You can do
that with the
save()
method.
Example of changing a column in a row
fetchRow($bugs->select()->where('bug_id = ?', 1));
// Change the value of one or more columns
$row->bug_status = 'FIXED';
// UPDATE the row in the database with new values
$row->save();
]]>
Inserting a new row
You can create a new row for a given table with the
createRow()
method of the table
class. You can access fields of this row with the
object-oriented
interface, but the row is not stored in the
database until you call the
save()
method.
Example of creating a new row for a table
createRow();
// Set column values as appropriate for your application
$newRow->bug_description = '...description...';
$newRow->bug_status = 'NEW';
// INSERT the new row to the database
$newRow->save();
]]>
The optional argument to the createRow() method is an
associative array, with which
you can populate fields of the new
row.
Example of populating a new row for a table
'...description...',
'bug_status' => 'NEW'
);
$bugs = new Bugs();
$newRow = $bugs->createRow($data);
// INSERT the new row to the database
$newRow->save();
]]>
The
createRow()
method was
called
fetchNew()
in earlier
releases of
Zend_Db_Table
. You are
encouraged to use the new method name, even though the old
name
continues to work for the sake of backward
compatibility.
Changing values in multiple columns
Zend_Db_Table_Row_Abstract
provides the
setFromArray()
method to enable you
to set several columns in a single row at once, specified in an
associative array that maps the column names to values. You may
find this method
convenient for setting values both for new rows
and for rows you need to update.
Example of using setFromArray() to set values in a new
Row
createRow();
// Data are arranged in an associative array
$data = array(
'bug_description' => '...description...',
'bug_status' => 'NEW'
);
// Set all the column values at once
$newRow->setFromArray($data);
// INSERT the new row to the database
$newRow->save();
]]>
Deleting a row
You can call the
delete()
method on
a Row object. This deletes rows in the database matching the
primary key in
the Row object.
Example of deleting a row
fetchRow('bug_id = 1');
// DELETE this row
$row->delete();
]]>
You do not have to call
save()
to
apply the delete; it is executed against the database
immediately.
Serializing and unserializing rows
It is often convenient to save the contents of a database row to
be used later.
Serialization
is the name for
the operation that converts an object into a form that is easy to
save in
offline storage (for example, a file). Objects of type
Zend_Db_Table_Row_Abstract
are
serializable.
Serializing a Row
Simply use
PHP
's
serialize()
function to create a
string containing a byte-stream representation of the Row object
argument.
Example of serializing a row
fetchRow('bug_id = 1');
// Convert object to serialized form
$serializedRow = serialize($row);
// Now you can write $serializedRow to a file, etc.
]]>
Unserializing Row Data
Use PHP's
unserialize()
function to
restore a string containing a byte-stream representation of an
object. The
function returns the original object.
Note that the Row object returned is in a
disconnected
state. You can read the
Row object and its properties, but you cannot change values
in
the Row or execute other methods that require a database
connection (for example,
queries against related tables).
Example of unserializing a serialized row
bug_description;
]]>
Why do Rows unserialize in a disconnected state?
A serialized object is a string that is readable to
anyone who possesses it. It
could be a security risk to
store parameters such as database account and
password in
plain, unencrypted text in the serialized string. You would
not want
to store such data to a text file that is not
protected, or send it in an email
or other medium that is
easily read by potential attackers. The reader of the
serialized object should not be able to use it to gain
access to your database
without knowing valid credentials.
Reactivating a Row as Live Data
You can reactivate a disconnected Row, using the
setTable()
method. The argument to
this method is a valid object of type
Zend_Db_Table_Abstract
, which you
create. Creating a Table object requires a live connection to
the
database, so by reassociating the Table with the Row, the
Row gains access to the
database. Subsequently, you can change
values in the Row object and save the changes
to the database.
Example of reactivating a row
setTable($bugs);
// Now you can make changes to the row and save them
$rowClone->bug_status = 'FIXED';
$rowClone->save();
]]>
Extending the Row class
Zend_Db_Table_Row
is the default concrete
class that extends
Zend_Db_Table_Row_Abstract
. You can define
your own concrete class for instances of Row by extending
Zend_Db_Table_Row_Abstract
. To use your
new Row class to store results of Table queries, specify the custom
Row
class by name either in the
$_rowClass
protected member of a Table class, or in the array argument of the
constructor of a Table
object.
Specifying a custom Row class
'MyRow'));
]]>
Row initialization
If application-specific logic needs to be initialized when a
row is constructed, you
can select to move your tasks to the
init()
method, which is called
after all row metadata has been processed. This is
recommended
over the
__construct
method if you do
not need to alter the metadata in any programmatic way.
Example usage of init() method
_role = new MyRoleClass();
}
}
]]>
Defining Custom Logic for Insert, Update, and Delete in
Zend_Db_Table_Row
The Row class calls protected methods
_insert()
,
_update()
, and
_delete()
before performing the
corresponding operations
INSERT
,
UPDATE
, and
DELETE
. You can add logic to these
methods in your custom Row subclass.
If you need to do custom logic in a specific table, and the
custom logic must occur
for every operation on that table, it
may make more sense to implement your custom
code in the
insert()
,
update()
and
delete()
methods of your Table
class. However, sometimes it may be necessary to do custom
logic
in the Row class.
Below are some example cases where it might make sense to
implement custom logic in
a Row class instead of in the Table
class:
Example of custom logic in a Row class
The custom logic may not apply in all cases of operations
on the respective
Table. You can provide custom logic on
demand by implementing it in a Row class
and creating an
instance of the Table class with that custom Row class
specified.
Otherwise, the Table uses the default Row class.
You need data operations on this table to record the
operation to a
Zend_Log
object, but
only if the application configuration has enabled this
behavior.
info(Zend_Debug::dump($this->_data,
"INSERT: $this->_tableClass",
false)
);
}
}
// $loggingEnabled is an example property that depends
// on your application configuration
if ($loggingEnabled) {
$bugs = new Bugs(array('rowClass' => 'MyLoggingRow'));
} else {
$bugs = new Bugs();
}
]]>
Example of a Row class that logs insert data for multiple
tables
The custom logic may be common to multiple tables.
Instead of implementing the
same custom logic in every one
of your Table classes, you can implement the code
for such
actions in the definition of a Row class, and use this Row
in each of
your Table classes.
In this example, the logging code is identical in all
table classes.
info(Zend_Debug::dump($this->_data,
"INSERT: $this->_tableClass",
false)
);
}
}
class Bugs extends Zend_Db_Table_Abstract
{
protected $_name = 'bugs';
protected $_rowClass = 'MyLoggingRow';
}
class Products extends Zend_Db_Table_Abstract
{
protected $_name = 'products';
protected $_rowClass = 'MyLoggingRow';
}
]]>
Define Inflection in Zend_Db_Table_Row
Some people prefer that the table class name match a table
name in the
RDBMS
by using a string
transformation called
inflection
.
Zend_Db
classes do not implement
inflection by default. See
for an
explanation of this policy.
If you prefer to use inflection, then you must implement the
transformation yourself,
by overriding the
_transformColumn()
method in a
custom Row class, and using that custom Row class when you
perform queries
against your Table class.
Example of defining an inflection transformation
This allows you to use an inflected version of the column
name in the accessors.
The Row class uses the
_transformColumn()
method to
change the name you use to the native column name in the
database table.
fetchNew();
// Use camelcase column names, and rely on the
// transformation function to change it into the
// native representation.
$row->bugDescription = 'New description';
]]>
You are responsible for writing the functions to perform
inflection transformation.
Zend Framework does not provide such
a function.