dra8603 2012-07-15 14:42
浏览 45
已采纳

“在非对象上调用成员函数”的一个不寻常的案例[重复]

This question already has an answer here:

I have a code:

class db {
    var $connection;
    function escape($esc) {
        return str_replace(array('%','_'),array('\%','\_'),mysqli_real_escape_string($this->connection,$esc));
    }
[...]
}
$db=new db;



class Session {
    private function read($sid) {
        global $db;
        $r=$db->query('SELECT `data` FROM `sess` WHERE `hash`=\''.$db->escape($sid).'\' LIMIT 1');
        if ($this->debug) echo 'Read: <u>SELECT `data` FROM `sess` WHERE `hash`=\''.$db->escape($sid).'\' LIMIT 1</u><br/>';
        if($db->num_rows($r)==1) {
            $fields=$db->fetch_assoc($r);
            return $fields['data'];
        }
        else return '';
    }

    private function write($sid, $data) {
        global $db;
        if ($this->debug) echo 'Write: <u>REPLACE INTO `sess`(`hash`,`data`) VALUES(\''.$db->escape($sid).'\',\''.$db->escape($data).'\')</u><br/>';
        $db->query('REPLACE INTO `sess`(`hash`,`data`) VALUES(\''.$db->escape($sid).'\',\''.$db->escape($data).'\')');
        return $db->connection->affected_rows;
    }
[...]
function __construct($debug=false) {
    session_set_save_handler(
        array(&$this, 'open'),
        array(&$this, 'close'),
        array(&$this, 'read'),
        array(&$this, 'write'),
        array(&$this, 'destroy'),
        array(&$this, 'clean')
    );
    $this->debug=$debug;
    session_start();
}
}
$sessions=new Session(true);

And I keep getting Fatal error: Call to a member function escape() on a non-object on line 61 (2nd row in function write($sid, $data)). The strange thing is that the debugger shows that the function read has successfully executed. Could anyone please shed some light on why this might be happening?

</div>
  • 写回答

1条回答 默认 最新

  • douqiao6563 2012-07-15 16:17
    关注

    Most likely (though we don't see where you call the method), it's called somewhere before the $db variable is declared.

    The correct solution would be to inject the variable to class via the constructor.

    public function __construct(db $db, $debug = false) {
        $this->db = $db;
        ....
    }
    

    Then use $this->db wherever you need.

    The problem with using global variables is that the order of decleration matters, meaning you have to declare $db before you call Session::write(), but it's not obvious that you need to do so!. Now, it's obvious because you need a $db object in order for your constructor to run!

    Why is Global State so Evil?

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 c语言怎么用printf(“\b \b”)与getch()实现黑框里写入与删除?
  • ¥20 怎么用dlib库的算法识别小麦病虫害
  • ¥15 华为ensp模拟器中S5700交换机在配置过程中老是反复重启
  • ¥15 java写代码遇到问题,求帮助
  • ¥15 uniapp uview http 如何实现统一的请求异常信息提示?
  • ¥15 有了解d3和topogram.js库的吗?有偿请教
  • ¥100 任意维数的K均值聚类
  • ¥15 stamps做sbas-insar,时序沉降图怎么画
  • ¥15 买了个传感器,根据商家发的代码和步骤使用但是代码报错了不会改,有没有人可以看看
  • ¥15 关于#Java#的问题,如何解决?