我在回答sql查询中的一行时遇到问题。我现在还很新,但我根本无法理解。
我的网页标题为“listing.php?id = 7”
页面内部是这个脚本:
<?php
mysql_connect("localhost", "user", "pass");
mysql_select_db("table");
$query = "SELECT * FROM vehicles WHERE id='$id'";
$result = mysql_query($query);
while($r = mysql_fetch_array($result))
{
$year = $r["year"];
$make = $r["make"];
$model = $r["model"];
$miles = $r["miles"];
$pricepay = $r["pricepay"];
$pricecash = $r["pricecash"];
$transmission = $r["transmission"];
$color = $r["color"];
$vin = $r["vin"];
echo "$year $make $model $miles $pricepay $pricecash $transmission $color $vin<br />";
}
?>
问题在于“WHERE id ='$ id'”。当我使用var时,它什么都不显示,但如果我手动将它作为我的ID号,例如7,它就可以正常工作。我做错了什么?
答案 0 :(得分:2)
如果
SELECT * FROM vehicles WHERE id=7
有效但
SELECT * FROM vehicles WHERE id='$id'
不起作用 然后获取$ id附近的报价
所以
SELECT * FROM vehicles WHERE id=$id
引号将$ id转换为字符串比较 - 如果列类型为整数,则无效。
答案 1 :(得分:2)
更好的是,使用PDO。创建连接:
$db = new PDO("mysql:host=localhost;dbname=someDBname", 'user', 'password');
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
但只在一个脚本中完成,最好是在单个或某些脚本中。这有许多优点,包括将所有数据库密码放在一个文件中(这更容易保护),并减少主机名,数据库名称,用户名或密码中的拼写错误的可能性,从而导致连接失败。用它作为:
try {
$query = $db->prepare(
"SELECT year, make, model, miles, pricepay,
pricecash, transmission, color, vin
FROM vehicles WHERE id=?"
);
$query->execute(array($_REQUEST['id']));
while ($row = $query->fetch(PDO::FETCH_NUM)) {
echo implode(', ', $row);
}
} catch (PDOException $exc) {
echo "Query failed.";
}
这使用了prepared query,它不容易受到SQL injection的攻击。它还does away with "or die"。
如果你还没有见过单身人士,这里有一个例子:
class DB {
private static $db;
static function open() {
if (! isset(self::$db) ) {
self::$db = new PDO('mysql:host=hostName,dbname=dbName', 'user', 'password');
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
return self::$db;
}
}
然后,只要您需要连接,只需致电DB::open()
即可。如果需要连接到多个主机,请将PDO存储在DB中的关联数组中,而不是DB :: $ db。在这种情况下,您可以将连接信息放在DB脚本中,或者将其放在DB解析的单独配置文件中。
答案 2 :(得分:0)
获取原始代码并在查询前添加此行:
$id = (int)$_GET['id']; // Sanitize Integer Input
并按其他人建议删除引号更改您的查询:
$query = "SELECT * FROM vehicles WHERE id=$id";
我假设你的id
是一个正常的mysql auto_increment
,从1开始。这意味着如果`$ _GET ['id']不是数字,它将返回0并且因此不匹配数据库中的任何内容。
答案 3 :(得分:-1)
$query = sprintf("SELECT * FROM vehicles WHERE id=%d", mysql_real_escape_string($_GET['id']));
$result = mysql_query($query);
id
,则无法在int
字段周围加上引号mysql_real_escape_string
来阻止sql注入