2010年5月2日星期日

Re: [fw-db] Re: Unexpected behavior from Zend_Db_Table_Row_Abstract::setFromArray()

I guess it comes down to what you are attempting to do.

If you just want to be able to access the data in object notation, I'd
simply do this:

$obj = new ArrayObject($data, ArrayObject::ARRAY_AS_PROPS);

You will then be able to access anything that was put into $data as a
property of that object:

$obj->prop_one, $obj->prop_two, and so on.

If your goal is to have a row object that can be persisted to the
database, then you should be using createRow().

The __construct() of a Zend_Db_Table_Row object doesnt actually take
just data, it also takes stateful information like whether or not the
data is already in the database already, and if it should be read-only,
but most importantly, which table object it should be referenced from.

On your row object below, calling $row->save() should throw an
exception, b/c it will not know which table object to attempt to use to
do the implied insert() or update().

The other problem that might arise with injecting into the row object
yourself is that your row object does not know what is a valid row and
what is not. This type of stuff is typically handled in the createRow()
routine of the Table object, explore that here:

http://framework.zend.com/svn/framework/standard/trunk/library/Zend/Db/Table/Abstract.php
(search for createRow())

So, in summary, if you are only concerned with arrayObject access, see
the above. If you are concerned with modeling new data into a live row
object, you should probably stick with createRow(), or try to mimic what
is going on inside createRow() as best as possible.

-ralph

jeremykendall wrote:
> Here's something interesting. As long as I pass an array of data into
> the row upon instantiation, setFromArray() works as I expected it to.
> See the test below:
>
> /**
> * Tests Zend_Db_Table_Row->setFromArray()
> */
> public function
> testSetFromArrayWorksWhenPassingArrayDuringInstantiation() {
>
> $row = new Zend_Db_Table_Row(array('data' => $this->_data));
>
> $this->assertEquals(3, count($row->toArray()));
>
> $this->assertEquals(1, $row->row_one);
> $this->assertEquals(2, $row->row_two);
> $this->assertEquals(3, $row->row_three);
>
> $updatedValues = array(
> 'row_one' => 7,
> 'row_two' => 8,
> 'row_three' => 9
> );
>
> $row->setFromArray($updatedValues);
>
> $this->assertEquals(7, $row->row_one);
> $this->assertEquals(8, $row->row_two);
> $this->assertEquals(9, $row->row_three);
> }
>
> Since I'm running unit tests on a custom row class, I think I'll use
> the technique above for further testing in this case.
>
> Do you guys see a problem with that going forward?
>
> On Sat, May 1, 2010 at 2:46 PM, Ralph Schindler-2 [via Zend Framework
> Community] <[hidden email]
> </user/SendEmail.jtp?type=node&node=2122526&i=0>> wrote:
>
> > Hey Jeremy,
> >
> > Try something like this:
> >
> > $row = $table->createRow($dataArray);
> >
> > This will create a row where it is aware of what table it belongs to.
> > This is important since the row has to understand the metadata of the
> > table, and which columns are in it, and more importantly, which is the
> > primary key and indexes.
> >
> > -ralph
> >
> > jeremykendall wrote:
> >> I'm getting some unexpected behavior from
> >> Zend_Db_Table_Row_Abstract::setFromArray(). If I instantiate a new row
> >> without passing any data and subsequently call setFromArray() to load
> >> data,
> >> Zend_Db_Table_Row::toArray() returns an empty array.
> >>
> >> I've never tried to instantiate a row in that manner in an
> application. I
> >> ran into this while writing some unit tests. I couldn't find a test
> in ZF
> >> that covered this use case, so I whipped one up to demonstrate the
> issue.
> >>
> >> Line 663 in Zend_Db_Table_Row_Abstract seems to be causing the issue
> >> (unless
> >> it's my improper use of the class that's the issue) when it calls
> >> array_intersect with an empty array as the second argument.
> >>
> >> Thoughts?
> >>
> >> <?php
> >>
> >> /**
> >> * Zend_Db_Table_Row test case.
> >> */
> >> class Kendall_Db_Table_Row_ZendRowTest extends
> PHPUnit_Framework_TestCase
> >> {
> >>
> >> /**
> >> * @var Zend_Db_Table_Row
> >> */
> >> private $_row;
> >>
> >> /**
> >> * @var array Initial dataset
> >> */
> >> private $_data = array();
> >>
> >> /**
> >> * Prepares the environment before running a test.
> >> */
> >> protected function setUp() {
> >>
> >> parent::setUp();
> >>
> >> $this->_data = array(
> >> 'row_one' => 1,
> >> 'row_two' => 2,
> >> 'row_three' => 3
> >> );
> >>
> >> $this->_row = new Zend_Db_Table_Row();
> >>
> >> }
> >>
> >> /**
> >> * Cleans up the environment after running a test.
> >> */
> >> protected function tearDown() {
> >> // TODO Auto-generated
> >> Kendall_Db_Table_Row_ZendRowTest::tearDown()
> >> $this->_row = null;
> >> parent::tearDown();
> >> }
> >>
> >> /**
> >> * Tests Zend_Db_Table_Row->setFromArray()
> >> *
> >> * Test fails with
> >> * 1) Kendall_Db_Table_Row_ZendRowTest::testSetFromArray
> >> * Failed asserting that <boolean:false> is true.
> >> */
> >> public function testSetFromArrayFailsToSetData() {
> >> $this->_row->setFromArray($this->_data);
> >> $this->assertTrue(array_key_exists('row_one',
> >> $this->_row->toArray()));
> >> }
> >>
> >> /**
> >> * Tests Zend_Db_Table_Row->setFromArray()
> >> *
> >> * This test passes.
> >> *
> >> * I think the problem is on
> >> Zend_Db_Table_Row_Abstract->setFromArray()
> >> line 663.
> >> * Calling array intersect on ($array, $emptyArray) always
> returns an
> >> empty array
> >> */
> >> public function testSetFromArrayReturnsEmptyArray() {
> >> $this->_row->setFromArray($this->_data);
> >> $this->assertEquals(0, count($this->_row->toArray()));
> >> }
> >>
> >> }
> >>
> >
> >
> > ________________________________
> > View message @
> >
> http://zend-framework-community.634137.n4.nabble.com/Unexpected-behavior-from-Zend-Db-Table-Row-Abstract-setFromArray-tp2122159p2122335.html
> > To unsubscribe from Unexpected behavior from
> > Zend_Db_Table_Row_Abstract::setFromArray(), click here.
> >
>
>
>
> --
> Jeremy
>
> Jeremy Kendall
> Web Developer & Entrepreneur
> http://jeremykendall.net
> http://bit.ly/SendOutCards
> [hidden email] </user/SendEmail.jtp?type=node&node=2122526&i=1>
> Jeremy Kendall
> Web Developer & Entrepreneur
> http://jeremykendall.net
>
> ------------------------------------------------------------------------
> View this message in context: Re: Unexpected behavior from
> Zend_Db_Table_Row_Abstract::setFromArray()
> <http://zend-framework-community.634137.n4.nabble.com/Unexpected-behavior-from-Zend-Db-Table-Row-Abstract-setFromArray-tp2122159p2122526.html>
> Sent from the Zend DB mailing list archive
> <http://zend-framework-community.634137.n4.nabble.com/Zend-DB-f671793.html>
> at Nabble.com.

没有评论: