Sandeepan Nath
Sandeepan Nath

Reputation: 10284

php class function not returning properly to caller

Background
I am writing a new database connector file for TeraWURFL which will use PDO extension. For more details on this please check

Details
I added a new database connector - TeraWurflDatabase_MySQL5_Mine.php and defined the same in the config file - TeraWurflConfig.php (there already are many connector files which come with TeraWURFL the value in the config file decides which one is used) -

public static $DB_CONNECTOR = "MySQL5_Mine";

I then wrote a test script to unit test all the functions of the new TeraWurflDatabase_MySQL5_Mine.php class file to make sure they return the same values after the changes. I am facing problem in the test script.

Everything is working fine but something is wrong with one function inside TeraWurflDatabase_MySQL5_Mine.php called rebuildCacheTable(). When I call this function from my test script, control does not return back to my test script after the return statement inside that function. -

Code inside test script test_connector.php -

/*file inclusiong start*/
require_once '/var/cake_1.2.0.6311-beta/app/webroot/Tera-Wurfl_PDO/TeraWurfl.php';
    require_once '/var/cake_1.2.0.6311-beta/app/webroot/Tera-Wurfl_PDO/TeraWurflConfig.php';

    require_once '/var/cake_1.2.0.6311-beta/app/webroot/Tera-Wurfl_PDO/DatabaseConnectors/TeraWurflDatabase.php'; //this file is same on both setups
    require_once '/var/cake_1.2.0.6311-beta/app/webroot/Tera-Wurfl_PDO/TeraWurflLoader.php';
    require_once '/var/cake_1.2.0.6311-beta/app/webroot/Tera-Wurfl_PDO/UserAgentFactory.php';
    require_once '/var/cake_1.2.0.6311-beta/app/webroot/Tera-Wurfl_PDO/UserAgentUtils.php';
    require_once '/var/cake_1.2.0.6311-beta/app/webroot/Tera-Wurfl_PDO/WurflConstants.php';
    require_once '/var/cake_1.2.0.6311-beta/app/webroot/Tera-Wurfl_PDO/WurflSupport.php';
    require_once '/var/cake_1.2.0.6311-beta/app/webroot/Tera-Wurfl_PDO/UserAgentMatchers/UserAgentMatcher.php';

    require_once '/var/cake_1.2.0.6311-beta/app/webroot/Tera-Wurfl_PDO/DatabaseConnectors/TeraWurflDatabase_MySQL5_Mine.php';
/*file inclusiong end*/


    $wurflDbPdoObj = new TeraWurflDatabase_MySQL5_Mine();
    $wurflDbPdoObj->connect();
    $dbObj = $wurflDbPdoObj;
    echo "before call";
    var_dump($dbObj->rebuildCacheTable());
    echo "after call"; //this does not execute if new TeraWurfl() object is initiated below

And code inside TeraWurflDatabase_MySQL5_Mine -

class TeraWurflDatabase_MySQL5_Mine extends TeraWurflDatabase{
    ...
    ...

    public function rebuildCacheTable(){
       $rebuilder = new TeraWurfl(); //if this object is initiated, return does not happen properly
       return true; //this does not return properly. 

   }
}

My debugging so far

I verified that the object initiated by $rebuilder = new TeraWurfl(); is a proper object.

I could narrow down to this, that if the line $rebuilder = new TeraWurfl(); inside TeraWurflDatabase_MySQL5_Mine is removed, return works properly.

Also, there is no such problem if I call the same function of the existing connector class TeraWurflDatabase_MySQL5 (I include TeraWurflDatabase_MySQL5.php instead of TeraWurflDatabase_MySQL5_Mine.php in the file inclusion part and make public static $DB_CONNECTOR = "MySQL5";) -

 $wurflDbPdoObj = new TeraWurflDatabase_MySQL5();
 $wurflDbPdoObj->connect();
 $dbObj = $wurflDbPdoObj;
 echo "before call";
 var_dump($dbObj->rebuildCacheTable());
 echo "after call"; //works

I also compared the var_dump() values of the objects created by $rebuilder = new TeraWurfl(); in both these cases (new TeraWurflDatabase_MySQL5_mine.php and existing TeraWurflDatabase_MySQL5.php). Found no problem there.

I have no clue what is wrong with my code. Any idea??

Updates
Further found that the problem is inside the constructor of the TeraWurfl.php class. The constructor initiates an object of the database connector class again -

public function __construct()
{
    ...
    $dbconnector = 'TeraWurflDatabase_'.TeraWurflConfig::$DB_CONNECTOR; //return fails if this object is initiated
    if($this->db === false) $this->db = new $dbconnector;
    ...
}

No errors/warnings appear and var_dump() looks fine comparing with the existing database connector case. There too an object of that database connector class is initiated.

Update #2 - profiling output
I set up code profiling by following steps as mentioned in http://kpayne.me/2012/02/04/use-register_tick_function-to-profile-your-code/ with a little modification to also display the class name in the output, and here are the outputs -

Profiling on test script for TeraWurflDatabase_MySQL5_Mine -

Array
(
    [TeraWurfl ->__construct] => Array
        (
            [time] => 9.0599060058594E-5
            [calls] => 8
        )

    [TeraWurflDatabase_MySQL5_Mine ->__construct] => Array
        (
            [time] => 4.3630599975586E-5
            [calls] => 4
        )

    [TeraWurflDatabase_MySQL5_Mine ->connect] => Array
        (
            [time] => 0.00010228157043457
            [calls] => 6
        )

    [TeraWurflDatabase_MySQL5_Mine ->rebuildCacheTable] => Array
        (
            [time] => 7.8678131103516E-6
            [calls] => 1
        )

    [show_profile] => Array
        (
            [time] => 1.7881393432617E-5
            [calls] => 1
        )

)

But for the existing class TeraWurflDatabase_MySQL5, I did not get the function call details, which is strange again -

Array
(
    [show_profile] => Array
        (
            [time] => 0.00024199485778809
            [calls] => 1
        )

)

Upvotes: 1

Views: 411

Answers (1)

Eugene
Eugene

Reputation: 3375

In such cases you can debug the flow even without xdebug by using:

declare(ticks=1);
register_tick_function(function(){
    $debug = debug_backtrace();
    echo "Running on line " . $debug[0]['line'] . " in file " . $debug[0]['file'] . "\n"; 
});

Edit: Actually, my example was bad, so I only left the important part.

Upvotes: 1

Related Questions