使用urldecode()会导致MySql错误

JYe*_*Yeh 1 php mysql urlencode urldecode

我需要通过我的MySQL查询的URL传递特殊符号.例如,我需要一个类似于以下内容的URL:

www.example.com/index.php?q=AND name LIKE '%hi%'
Run Code Online (Sandbox Code Playgroud)

当我第一次尝试它时,我得到了406错误.我查了一下,显然我必须使用urlencode()urldecode().我把它们放进去了,406错误消失了,但后来我得到了一个MySQL错误:

mysql_fetch_array(): supplied argument is not a valid MySQL result resource
Run Code Online (Sandbox Code Playgroud)

通常当我得到这些时,这意味着查询编写不正确.所以我回应了MySQL查询,一切看起来都很好.我甚至删除了urldecode()并将硬编码转换为我希望传递给页面的变量,并且MySQL错误消失了.但是,使用urldecode()和不使用它们的查询完全相同,所以我有点困惑.

我走上了php.net文档页面urldecode(),并有一个警告,说的一样使用_GET,并urldecode()一起可能导致意想不到的事情,这_GET已经起到解码器(或至少这就是我理解的措辞),所以我删除urldecode()但仍留在_GET,并导致文本未被解码,所以我想我没有正确解释文档.

urldecode()不是与MySQL查询兼容?我很确定这是编码/解码的问题,因为我已经用绕过编码/解码的硬编码信息测试了我的代码,并且它工作正常.也许urldecode()是以某种方式将字符转换为看起来相同但内部不同的特殊字符,因此MySQL无法读取它们?

Ric*_*haw 75

不要这样做.这是不对的.当然,任何人都可以使用a结束查询;并启动新查询,删除所有内容或读取用户和密码.

一个简单而且更好的方法是使用www.example.com/index.php?q=hi你的URL,然后在服务器上(让我们假设PHP)

$queryString = mysql_real_escape_string($_GET['q']);

$query = "AND name LIKE '%$queryString%'";

// Then replace $query for whatever you were using $_GET['q'] for before.
// Feel free to rename my variables what you like!
Run Code Online (Sandbox Code Playgroud)

这样,用户就不会搞砸了,URL看起来更干净.mysql_real_escape_string函数通过转义事物使字符串在查询中安全使用.请阅读http://php.net/manual/en/function.mysql-real-escape-string.php了解更多信息.

如果您仍然不相信这是有用的,请考虑如果某人发布了一个会丢弃您的表格的链接,然后Google每周抓取一次,会发生什么情况.您的数据会在Google碰巧时被删除.

一旦你对这种技术感到满意,请阅读mod_rewrite(如果使用Apache)更清理URL,mysqli以及它是如何改进mysql函数的版本,最后是PHP Data Objects(PDO),它有助于清理PHP甚至更多.

  • 而不是使用`mysql_real_escape_string`(这是MySQL特定的和客户端唯一的 - 希望正确实现服务器的字符串转义),准备一个语句并传递字符串(使用%')会更清晰,更通用s)作为一个论点.另外,我将指出,根据你正在寻找的语义,你可能也应该从`q`的值中逃避`LIKE`(例如%)使用的各种特殊字符(顺便说一句,这是令人困惑的这里被命名为`queryString`,因为该术语在此上下文中通常表示"q = hi"). (5认同)

Mas*_*ler 8

Rich有正确的总体思路,但比引用更好的是使用数据库参数.它实质上将"变量标记"放入SQL查询中,然后单独传递变量.查询最终看起来像这样:

SELECT ID, VALUE1, VALUE2
FROM MY_TABLE
WHERE VALUE3 = :param
Run Code Online (Sandbox Code Playgroud)

然后在您的代码中,添加一个替换为for的值:param,然后将其与SQL一起发送到数据库.(在某些数据库库中,您使用的是?而不是:parametername.)它比引用更有效,原因有三:

首先,您可以保持查询字符串不变,而不必每次都重建它,这样可以提高服务器的性能.

其次,如果使用多个不同的参数多次向数据库发送相同的常量查询,则数据库引擎可以缓存查询计划,从而提高数据库的性能.

第三,当你习惯用参数化样式编写查询时,它变得很自然,特别是如果你使用一个以参数列表作为参数的查询函数,所以很难出错.相比之下,很容易忘记引用某些东西,然后你不小心在你的程序中打开了一个安全漏洞.

参数化的确切工作方式取决于您正在使用的数据库和数据库访问库,但每个SQL数据库都支持它们.您应该看看它是如何为您正在使用的系统完成的.它确实是使用SQL的最佳方式,尤其是当您从不受信任的来源(如Internet)输入时.