Ticket #855 (defect)

Opened 2 months ago

Last modified 2 weeks ago

__sleep() function in TActiveRecord

Status: new

Reported by: ctrlaltca Assigned to: xue
Priority: normal Milestone: 3.1.3
Component: Prado Framework v3 Version: 3.1
Severity: minor Keywords: _connection __sleep tactiverecord
Cc:

There's a problem in TActiveRecord's sleep() function; the problem is exactly the same explained in http://trac.pradosoft.com/prado/ticket/803 . In #803 the problem was that _readOnly was private; it has been solved changing it to protected. I'm using php 5.2.6 and prado 3.1.2; i have the same problem, this time involving the _connection variable; changing it from private to protected solves the problem for me.

Exact error message i get:

TPhpErrorException Description

[Notice] serialize() [<a href='function.serialize'>function.serialize</a>]: &quot;_connection&quot; returned as member variable from sleep() but does not exist (@line 68 in file /var/www/htdocs/oro/protected/Common/UAMActiveDataGrid.php).

Change History

05/14/2008 07:18:47 AM: Modified by ctrlaltca

As you can see from the post, i hate WikiFormatting (the function name is _ _ sleep(), while WikiFormatting thinks i want to underline the entire paragraph).

06/05/2008 08:27:00 AM: Modified by ctrlaltca

bump is there anyone in here?

06/06/2008 05:12:54 AM: Modified by maarten

One way to solve this is by using reflection to filter out the privates:

  • framework/Data/ActiveRecord/TActiveRecord.php

    old new  
    183183       public function __sleep() 
    184184       { 
    185185               $this->_connection=null; 
    186                return array_keys(get_object_vars($this)); 
     186               $vars = array(); 
     187               $class = new ReflectionClass(__CLASS__); 
     188               foreach ($class->getProperties() as $property) 
     189               { 
     190                       if (!$property->isPrivate() && !$property->isStatic()) 
     191                       { 
     192                               $vars[] = $property->getName(); 
     193                       } 
     194               } 
     195               return $vars; 
    187196       } 
    188197       /** 

I could submit this to SVN, but I'm not sure what the procedure for testing/code reviewing is. Also I'm not sure if reflection is a part of the core of PHP, so I might be creating an unwanted dependency.

06/06/2008 05:35:58 AM: Modified by maarten

Well, that off course should be:

  • framework/Data/ActiveRecord/TActiveRecord.php

    old new  
    183183       public function __sleep() 
    184184       { 
    185185               $this->_connection=null; 
    186                return array_keys(get_object_vars($this)); 
     186               $vars = array(); 
     187               $class = new ReflectionClass($this); 
     188               foreach ($class->getProperties() as $property) 
     189               { 
     190                       if (!$property->isPrivate() && !$property->isStatic()) 
     191                       { 
     192                               $vars[] = $property->getName(); 
     193                       } 
     194               } 
     195               return $vars; 
    187196       } 
    188197       /** 

Otherwise properties of subclasses won't be included...

06/30/2008 07:11:02 AM: Modified by rojaro

The Reflection API is a core part of PHP since it's introduction in PHP version 5/Zend Engine 2. Since PRADO never was meant to be compatible with older PHP versions, usage of the reflection API is save and PRADO already uses the Reflection API in serveral classes.

However, the fix is good and clean and i think it should be incorporated as fast as possible as it basically fixes a "horrible" bug which caused already enough sleepless nights for many developers.

07/06/2008 03:02:42 PM: Modified by maarten

My friends,

I would like to commit, but my account doesn't seem to have the necessary permissions. I've made a unittest and a patch. Patch is described above, testcase is:

  • tests/simple_unit/Tickets/Ticket855Test.php

    old new  
     1<?php 
     2 
     3Prado::using('System.Data.ActiveRecord.TActiveRecord'); 
     4 
     5class TestRecord extends TActiveRecord 
     6{ 
     7} 
     8 
     9class Ticket855Test extends UnitTestCase 
     10{ 
     11    function test() 
     12    { 
     13        error_reporting(E_ALL); 
     14        $record = new TestRecord(); 
     15 
     16        $serialized = serialize($record); 
     17        $this->pass(); 
     18    } 
     19} 

Can somebody do a review? And commit? Or give me an account to be able to commit?

Thanks!