我已经基于codeigniter框架风格创建了自己的mvc模式。我现在的问题是,我想防止SQL注入,为此,我想使用mysql_real_eescape_string()。但当我使用它时,它一直在出错,因为它显然没有到数据库的"链接/源"?
我得到php错误:
警告:mysql_real_eescape_string():无法连接到本地mysql服务器通过套接字"/var/lib/mysql/mysql.sock'(2)/hsphere/local/home//dev/simple_blog/models/users_model.php联机8
警告:mysql_real_eescape_string():无法链接到服务器成立于/hsphere/local/home//dev/simple_blog/models/users_model.php联机8
我不太明白为什么,因为我可以把东西进出我的数据库,但出于某种原因,我不能保护它???
这是我给出错误的函数
public function getUserByName($username){
$username = mysql_real_escape_string($username);
$sql = "SELECT * FROM ".$this->db_table." WHERE username='".$username."' LIMIT 1";
$q = $this->db->query($sql);
if($q->rowCount() > 0){
foreach($q->fetch() as $key => $row){
$data[$key] = $row;
}
return $data;
}
}
正如您所看到的,我在顶部使用mysql_real_eescape_string(),然后在稍后执行查询操作。有人知道为什么这个不起作用吗?如果是,我该怎么解决?
注意:我不是PDO的鲨鱼,$this->db是PDO类。
要使用mysql_real_escape_string
,您需要首先使用MySQL函数连接到数据库服务器,而您可能还没有这样做。
您混淆了两个完全不同的PHP扩展:mysql和PDO!
此外,当使用PDO准备的语句时,您不需要转义字符串,这是通过PDO为您完成的。
使用PDO的示例:
$userDataStmt = $this->database->prepare('SELECT * FROM ' . $this->db_table . ' WHERE username = :username LIMIT 1');
$userDataStmt->bindValue(':username', $username);
$userDataStmt->execute();
if(!$userDataStmt->rowCount() <= 0)
{
$result = $userDataStmt->fetchAll();
}
不要这样做。如果您使用事先准备好的声明,PDO将为您逃离:
$stmt = $this->db->prepare("SELECT * FROM ".$this->db_table." WHERE username=:user LIMIT 1";
$stmt->bind(':user', $username);
$stmt->execute();
PDO在幕后使用(我相信)mysqli库。mysql_escape_real_string使用mysql库(注意i
的缺失)。这两个库都有完全独立的连接池,因此除非您与mysql_connect()
建立一个丢弃链接,否则无论如何都不能使用mysql_real_eescape_string,因为它需要一个活动的DB连接。
PDO版本为PDO::quote()
。看见http://php.net/manual/en/pdo.quote.php
所以在你的情况下,它将是
$username = $this->db->quote($username);
但是,大多数人建议使用PDO准备的语句来避免在PDO中进行SQL注入。看见http://php.net/manual/en/pdo.prepared-statements.php