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?
Most likely (though we don’t see where you call the method), it’s called somewhere before the
$dbvariable is declared.The correct solution would be to inject the variable to class via the constructor.
Then use
$this->dbwherever you need.The problem with using global variables is that the order of decleration matters, meaning you have to declare
$dbbefore you callSession::write(), but it’s not obvious that you need to do so!. Now, it’s obvious because you need a$dbobject in order for your constructor to run!Why is Global State so Evil?