我正在使用sqlite_escape_string()转发博客帖子,并使用旧的面向对象的方式连接到数据库。
(是的,我知道,我应该使用PDO,我稍后会讨论;转换此脚本需要一段时间。)
如果我有以下数据:It's raining cats and dogs!
,则会将其保存到数据库:It''s raining cats and dogs!
。问题是它来自数据库,而stripslashes()不会撤消它。 Magic Quotes已关闭。
每当我从数据库中回忆起数据并再次保存时,它就会添加更多的单引号。我怎么能阻止它呢?
以下是删节提交代码:
# Grab the data from form and escape the text
$title = sqlite_escape_string(strip_tags($_POST['title']));
$text = sqlite_escape_string($_POST['text']);
# Query for previous data
$result = @$dbh->query("SELECT * FROM posts WHERE id=".$id);
# Fetch previous data
while($past = $result->fetchObject()) {
$ptitle = $past->title;
$ptext = $past->post;
}
# Set a base query to modify
$base = "UPDATE posts SET ";
# Run through scenarios
if(stripslashes($ptitle) !== $title) { $base .= "title='".sqlite_escape_string($title)."', "; }
if(stripslashes($ptext) !== $text) { $base .= "text='".sqlite_escape_string($text)."', "; }
}
# Remove last comma & space
$base = substr($base, 0, -2);
$base .= " WHERE id=".(int)$id;
# Execute modified query
@$dbh->query($base);
这是读取数据的代码:
# Sanitize and set variables
$start = (int)$start;
$limit = (int)$limit;
$start = ($start - 1) * $limit;
$dbh = $this->dbh;
$this->limit = $limit;
# Query the database for post data
$this->result = $dbh->query("SELECT * FROM posts ORDER BY id desc LIMIT ".$start.", ".$limit);
public function loop() {
# Do we have any posts?
if(!empty($this->result)) {
# Convert query results into something usable
$this->cur_result = $this->result->fetchObject();
# This while loop will remain true until we run out of posts
while($post = $this->cur_result) {
return true;
}
# At which point it turns false, ending the loop in the template file
return false;
}
# We don't have any posts :(
else {
return false;
}
}
public function content($excerpt = '') {
# We didn't screw up and keep an empty query, did we?
if(!empty($this->cur_result)) {
echo stripslashes($this->cur_result->post);
}
}
答案 0 :(得分:0)
我怀疑你有magic_quotes_sybase。张贴以下值:
echo ini_get('magic_quotes_sybase');
echo get_magic_quotes_gpc() // Probably not relevant, but may as well be thorough.
两者都应为0。
编辑:你显然是双重逃避$text
和$title
:
$title = sqlite_escape_string(strip_tags($_POST['title']));
$text = sqlite_escape_string($_POST['text']);
...
if(stripslashes($ptitle) !== $title) { $base .= "title='".sqlite_escape_string($title)."', "; }
if(stripslashes($ptext) !== $text) { $base .= "text='".sqlite_escape_string($text)."', "; }
如您所知,准备好的陈述是最好的解决方案。但是,如果您要使用转义,请在最后一刻撤消每个变量。这是在DB调用之前,当你正在读取输入时,不是。
如果您正确使用转义或预处理语句,则从db读取时,您将永远不必调用stripslashes或删除额外的引号。
答案 1 :(得分:0)
看起来你要两次逃避数据。
在您的代码的开头,您有:
$title = sqlite_escape_string(strip_tags($_POST['title']));
$text = sqlite_escape_string($_POST['text']);
然后在插页中你有:
if(stripslashes($ptitle) !== $title) { $base .= "title='".sqlite_escape_string($title)."', "; }
if(stripslashes($ptext) !== $text) { $base .= "text='".sqlite_escape_string($text)."', "; }
从if语句中删除sqlite_escape_string,我认为现在结果会正确显示。