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甚至更多.
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)输入时.