关于mysql_real_escape_string和strip_slashes的困惑

时间:2012-02-15 00:48:24

标签: php mysql mysql-real-escape-string stripslashes

我让用户输入他们的姓名,例如:O'riley

在将此数据输入MySQL数据库之前,我运行mysql_real_escape_string

问题是,当我选择此数据进行显示并稍后使用时,它显示为:O\'riley

显然,这是预期的操作。我想知道的是,如果有人确定我可以将它存储在数据库中(仍然安全地逃避可能的恶意代码),这样我就不必在输出上使用strip_slashes()每次我调用整个网络应用程序的数据?或者,我在这里错过了什么?

感谢。

更新 请参阅Deceze答案中的评论。

9 个答案:

答案 0 :(得分:10)

不,字符串存储为“O \'riley”不是预期的操作;它应该只在查询中转义,但不以这种方式存储。我猜测PHP会通过Magic Quotes反斜杠,然后再次将其转义以使其坚持下去。

Disable Magic Quotes

答案 1 :(得分:4)

我个人总是关闭魔术引号,因为它正在做一些我没有告诉它要做的事情。如果您无法将其关闭,请考虑将此代码包含在所有页面的顶部。

if (get_magic_quotes_gpc()) {
    function strip_array($var) {
        return is_array($var)? array_map("strip_array", $var):stripslashes($var);
    }

    $_POST = strip_array($_POST);
    $_SESSION = strip_array($_SESSION);
    $_GET = strip_array($_GET);
}

答案 2 :(得分:4)

如果您禁用了魔术引号,并且在get_magic_quotes_gpc返回1并且您执行类似@Michael演示并且此仍然的情况下,则可启用魔术引号运行时。

魔术引号运行时会在进行数据库查询时甚至在写入文件时向字符串添加斜杠。要在当前正在执行的脚本中禁用它,请执行:

if(function_exists('get_magic_quotes_runtime') && get_magic_quotes_runtime())
{
    set_magic_quotes_runtime(false);
}

如果可以,也可以禁用此configuration option through php.ini。但是,如果您无法通过php.ini永久禁用它,则可能需要在get_magic_quotes_runtimeset_magic_quotes_runtime之前添加@,因为如果error_reporting设置为{{1}},PHP可能会通过E_DEPRECATED错误记录这样的错误(这会很烦人)。

答案 3 :(得分:4)

好的,这就是你需要做的。首先,根据评论,从其他问题:

<强>分离物

您需要确定导致问题的原因。是服务器吗?是某些隐藏的代码吗?什么?一些程序员可能在配置页面上包含这样的代码:

<?php if (isset($_POST)) 
    foreach ($_POST as $key => $value) $_POST[$key] = addslashes($value); 
?>

所以这里有一些检查,看看它是否是服务器。这是一种尽可能坚实的检查方式。创建页面。将其保留为空白并添加以下代码:

<?php print_r($_POST); ?>
<form action="" method="POST">
<input type="text" name="test" value="O'riley" />
<input type="submit" name="submit" value="submit" />
</form>

保存并将其加载到浏览器中。命中提交。查看斜杠是否仍然添加。

如果仍在添加,则需要对服务器/配置进行故障排除。如果它是您付费的服务器,您需要告诉他们修复它或推它。如果它是你自己的服务器,那么你将需要做一些搞乱/谷歌搜索来弄清楚如何关闭魔术引号。

如果没有出现引号,那么肯定会有一些代码为你的帖子变量添加斜杠。然而,它可能不如上面的代码那么明显。您需要在代码上搜索“addslashes”,“mysql_real_escape_string”以及可能的“str_replace”。如果您找到其中一个,则需要禁用它。但请注意,这可能会破坏您网站的其他部分,即假设正在进行此操作。您将其存储在数据库中的另一种选择是执行类似于上面代码的功能,而是在其上运行stripslashes。然后你可以在以后运行mysql_real_escape_string。 (更多不必要的开销。)

答案 4 :(得分:3)

使用

var_dump(get_magic_quotes_gpc());

在实际使用发布的数据附近,看看魔术行情是否真的关闭。

另外一些奇怪的框架可能会为您添加引号,以便为addslashes和其他escape_string类似函数设置代码。

答案 5 :(得分:2)

我诚实地建议使用PDO。

PDO使用prepare和execute语句,这反过来又增加了安全性并消除了一些额外的麻烦。

$pdo = new PDO();
$stm = $pdo->prepare('INSERT... (LastName) VALUES (:LastName)');
$stm->execute(array(':LastName' => "O'Rily"));

$stm->fetchAssoc(PDO::FETCH_ASSOC);

您不再需要担心删除转义斜杠以及确保基本的SQL注入策略。

答案 6 :(得分:0)

可能会在httpd.conf或虚拟主机声明中打开魔术引号。

确切的位置和文件将取决于操作系统和发行版。我会检查Apache配置文件中的php_flag设置。

答案 7 :(得分:-1)

在插入数据库之前,只需使用清理数据,

function check_input($value)
{
    if( get_magic_quotes_gpc() )
    {
        $value = stripslashes( $value );
    }

    //check if this function exists
    if( function_exists( "mysql_real_escape_string" ) )
    {
        $value = mysql_real_escape_string( $value );
    }

    //for PHP version < 4.3.0 use addslashes
    else
    {
        $value = addslashes( $value );
    }

    return $value;
}


$cleandata = check_input($value);

$sql = "INSERT INTO `table_name` SET `field_name`='".$cleandata."'";

获取数据并显示在其中时使用stripslashes($val)

答案 8 :(得分:-1)

谢谢大家的答案。我会奖励+50,但我想告诉我真正的解决方案,所有人都帮助过......

我在发布的所有数据上(在任何处理之前)对mysql_real_escape_string执行了'。因此,添加了斜杠以转义已提交的\字符。我们知道这是正常的。

但是,没有理由在DB条目中出现反斜杠',对吗?逃脱是为了确保O'riley被输入。

事实证明,在转义之后,我会保存变量以重新加载到会话中的页面,以防用户在验证所有表单字段时发现错误。在这种情况下,用户的输入(以前为O\'riley现在作为O\'riley打印到他们的屏幕。然后,用户没有抓住这个 - 所以他们经常只修复PHP在验证期间捕获的错误(与名称字段无关),因此mysql_real_escape_string将落在数据库中,因为{{1}}将转义字符。

<强>课: 处理表单时,FIRST保存数据以供表单重新填充使用。第二个验证表单字段。 THIRD将数据转义为处理到数据库中。

或者更好的是,使用PDO并避免这种情况=)。

欢迎评论。感谢所有人!