【问题标题】:php class function not returning properly to callerphp类函数没有正确返回给调用者
【发布时间】:2012-06-18 16:08:12
【问题描述】:

背景
我正在为 TeraWURFL 编写一个新的数据库连接器文件,它将使用 PDO 扩展名。有关这方面的更多详细信息,请查看

详情
我添加了一个新的数据库连接器 - TeraWurflDatabase_MySQL5_Mine.php 并在配置文件中定义了相同的 - TeraWurflConfig.php(TeraWURFL 已经有许多连接器文件,配置文件中的值决定使用哪个) -

public static $DB_CONNECTOR = "MySQL5_Mine";

然后我编写了一个测试脚本来对新TeraWurflDatabase_MySQL5_Mine.php 类文件的所有函数进行单元测试,以确保它们在更改后返回相同的值。我在测试脚本中遇到问题。

一切正常,但TeraWurflDatabase_MySQL5_Mine.php 中的一个名为rebuildCacheTable() 的函数出了点问题。当我从我的测试脚本调用这个函数时,控制不会在该函数内的 return 语句之后返回到我的测试脚本。 -

测试脚本内的代码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

还有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. 

   }
}

到目前为止我的调试

我验证$rebuilder = new TeraWurfl(); 发起的对象是正确的对象。

我可以缩小到这一点,如果 $rebuilder = new TeraWurfl(); 内的 TeraWurflDatabase_MySQL5_Mine 行被删除,返回正常工作。

另外,如果我调用现有连接器类TeraWurflDatabase_MySQL5的相同函数(我在文件包含部分包含TeraWurflDatabase_MySQL5.php而不是TeraWurflDatabase_MySQL5_Mine.php并制作public static $DB_CONNECTOR = "MySQL5";),就不会有这样的问题 -

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

我还比较了$rebuilder = new TeraWurfl(); 在这两种情况下创建的对象的var_dump() 值(新的TeraWurflDatabase_MySQL5_mine.php 和现有的TeraWurflDatabase_MySQL5.php)。没有发现问题。

我不知道我的代码有什么问题。有什么想法吗??

更新
进一步发现问题出在TeraWurfl.php类的构造函数内部。构造函数再次初始化一个数据库连接器类的对象——

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

与现有的数据库连接器案例相比,没有出现错误/警告,var_dump() 看起来还不错。该数据库连接器类的对象也已启动。

更新 #2 - 分析输出
我按照http://kpayne.me/2012/02/04/use-register_tick_function-to-profile-your-code/ 中提到的步骤设置代码分析,稍作修改以在输出中显示类名,这是输出 -

分析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
        )

)

但是对于现有的类TeraWurflDatabase_MySQL5,我没有得到函数调用的细节,这又是奇怪的-

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

)

【问题讨论】:

  • 您使用的是$DB_CONNECTOR = 'MySQL5_Mine',但文件名为TeraWurflDatabase_MySQL5Mine.php,例如没有额外的下划线。也许这是造成问题的原因?我猜你错误地命名了文件名或类。
  • @BArt 这是在准备问题时发生的。感谢您指出。但是代码没有这个问题

标签: php return


【解决方案1】:

在这种情况下,即使没有xdebug,您也可以使用以下命令调试流程:

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

编辑: 其实我的例子很糟糕,所以我只留下了重要的部分。

【讨论】:

  • 谢谢,我在我的代码中设置了分析并将输出发布在更新#2 - 分析输出部分。看看能不能帮忙
  • 非常感谢先生!分析救了我。由错误抑制运算符 @ 抑制的致命错误隐藏了问题区域,因此不会返回给调用者。我认为设置 error_reporting(-1)ini_set("display_errors","On") 无论如何都会显示所有错误,但事实并非如此。
  • 我比较了两个数据库连接器(现有的连接器和我修改的新连接器)的分析器输出的差异。致命错误发生在新类的 __desctruct() 方法中,因此它没有显示在分析器输出中。但是我不确定探查器输出何时不显示函数。我刚刚发现,如果函数内没有可执行代码行(比如一个空函数),它不会显示在 prof 输出中。为什么会这样?有什么意义?
猜你喜欢
  • 2019-09-10
  • 1970-01-01
  • 1970-01-01
  • 2015-11-09
  • 2019-03-18
  • 1970-01-01
  • 2011-07-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多