【问题标题】:Not object although var_dump() says otherwise?不是反对,尽管 var_dump() 另有说明?
【发布时间】:2009-07-13 15:20:57
【问题描述】:

当我创建控制器时,我将模型(AccountModel)加载到类变量“Model”并检查用户是否登录:

function __construct()
{
    parent::__construct();

    $this->loadModel("AccountModel", "Model");

    $account = $this->getUserAccount();
    ...
}

getUserAccount() 发生致命错误:

致命错误:在第 57 行的 wwwroot/lib/account/account.php 中的非对象上调用成员函数 getAccount()

这是第 57 行,我在之前加载的模型上调用 getAccount()

$account = $this->Model->getAccount($_SESSION["account"]["user_account_id"]);

所以,看起来$this->Model 不是对象,但是当我在调用getAccount() 之前放置var_dump($this->Model) 时,它会显示object(AccountModel)#26 (2) ... p>

我也做了var_dump($this),它转储了控制器,发现类变量$Model存在并且是AccountModel的实例。

谁能告诉我到底发生了什么?

顺便说一句,模型是这样分配的(控制器方法):

function loadModel($model_name, $var_name)
{
 // blah blah blah
 $obj = new $class_name();
 $this->$var_name = $obj;
}

更新:

在 __construct() 中,如果我直接在我的模型上调用 getAccount()(之前我调用了 getUserAccount,然后在其中调用了 getAccount)而不参数,PHP输出错误说:

缺少参数 1 AccountModel::getAccount()

但是当我添加参数时,它又说它不是对象。

解决办法:

加载模型时,方法 loadModel() 将模型分配给控制器实例,并将加载模型的每个名称存储到静态属性中。第二次调用控制器时发生错误,因此控制器的第二个实例并没有真正得到它的模型。将 staitc 属性替换为对象属性(检查模型是否已被调用避免使用 require_once 降低开销,但现在必须为该部分找到更好的解决方案;)无论如何,现在它可以工作了,感谢大家的帮助。

【问题讨论】:

    标签: php oop object


    【解决方案1】:

    您是否禁用了警告和通知?您的 loadModel 方法应该在 new $class_name 上发出警告 - 应该是 new $model_name

    function loadModel($model_name, $var_name)
    {
     // blah blah blah
     $obj = new $model_name();
     $this->$var_name = $obj;
    }
    

    【讨论】:

    • 啊,我的错,函数从 $model_name 准备类名(名称转换等),所以 $obj = new $class_name() 是正确的。
    • 好的,在这种情况下,我感觉你发布了你认为问题所在的代码片段,可能忽略了问题的真正根源:)
    • 也许吧,但由于这都是我的自定义框架的一部分,所以很难发布整个代码:) 但是,变量 IS 对象,但是当我尝试执行它的方法时,它会说不是... :(
    【解决方案2】:

    这将是设置工作调试器的绝佳机会,例如xdebugnetbeans/php

    编辑:缺少“真正的”调试器(更好)一个(坏的)回显/断言调试器必须做

    • 向您的类添加错误处理方法
    • 在构造函数中设置错误处理程序
    • 在构造函数中设置 error_reporting=E_ALL 和 display_errors=On
    • 在构造函数中设置一些断言选项
    • 在构造函数中添加断言
    • 在控制器的 getUserAccount() 方法中添加两个断言

    完成调试后不要忘记删除代码

    class YourController extends TheController{
      // debug, don't forget to remove/comment out this method
      public static function myErrorHandler($errno, $errstr, $errfile, $errline) {
        $source = file($errfile);
        echo '<fieldset><legend>', htmlspecialchars($errstr. ', '.$errfile.'@'.$errline), "<legend><pre>\n";
        for($i=$errline-8; $i<$errline+3; $i++) {
          if ( isset($source[$i]) ) {
            echo $i+1, ': ', htmlspecialchars($source[$i]);
          }
        }
        echo "\n</pre></fieldset>\n";
        flush();
        return false;
      }
    
      public function __construct()
      {
        set_error_handler('YourController::myErrorHandler'); // debug, don't forget to remove
        error_reporting(E_ALL); ini_set('display_errors', 1);  // debug, don't forget to remove
        assert_options(ASSERT_ACTIVE, 1);  // debug, don't forget to remove
        assert_options(ASSERT_WARNING, 1);  // debug, don't forget to remove
        assert_options(ASSERT_BAIL, 1);  // debug, don't forget to remove
        assert_options(ASSERT_QUIET_EVAL, 1);  // debug, don't forget to remove
        parent::__construct();
    
        $this->loadModel("AccountModel", "Model");
        assert( is_object($this->Model) );  // debug, don't forget to remove
        $account = $this->getUserAccount();
      }
    
      public function loadModel($model_name, $var_name)
      {
         // blah blah blah
         $obj = new $model_name();
         $this->$var_name = $obj;
      }
    
      public function getUserAccount() {
        assert( is_object($this->Model) );  // debug, don't forget to remove
        assert( is_callable(array($this->Model, 'getAccount')) );  // debug, don't forget to remove
        $account = $this->Model->getAccount($_SESSION["account"]["user_account_id"]);
      }
    

    【讨论】:

    • 添加了一些 printf-debugger 代码提案。不过看看xdebug。真正的调试器随时都胜过 printf-have-to-(repeatedly-)change-the-code-debugger。
    • 我用过xDebug(不知道PHPDesigner有,谢谢,下次用)。无论如何,我解决了这个问题,你的回答对我帮助很大。将用解决方案更新我的问题(这是一个相当糟糕的错误:\)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-01-06
    • 2015-03-29
    • 1970-01-01
    • 1970-01-01
    • 2011-03-07
    • 2021-07-03
    相关资源
    最近更新 更多