我有一个代码:
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);
我不断获得Fatal error: Call to a member function escape() on a non-object on line 61
(function write($sid, $data)
中的第2行)。奇怪的是调试器显示函数read
已成功执行。有谁可以请说明为什么会发生这种情况?
答案 0 :(得分:2)
最有可能(虽然我们没有看到你在哪里调用该方法),但在声明$db
变量之前它被调用。
正确的解决方案是通过构造函数将变量注入类。
public function __construct(db $db, $debug = false) {
$this->db = $db;
....
}
然后在您需要的地方使用$this->db
。
使用全局变量的问题是重要的顺序,这意味着您必须在致电$db
之前声明Session::write()
,但这并不明显你需要这样做!。现在,很明显因为你需要一个$db
对象才能运行构造函数!
<强> Why is Global State so Evil? 强>