我编写了下面的脚本作为我的第一个php mysql应用程序。我是自学成才,代码按预期工作。我的主机认为它可能容易受到SQL注入攻击,但无法告诉我为什么或我应该改变什么以使其更好。我确信它不是那么干净但如果有人有任何建议或见解我肯定会感激。
<form method="post" action="search.php?go" id="searchform">
<?php
$db=mysql_connect ("server", "*", "*") or die ('I cannot connect to the database because: ' . mysql_error());
$mydb=mysql_select_db("*");
$category_sql="SELECT distinct category FROM Members";
$category_Options="";
$category_result=mysql_query($category_sql) or die ('Error: '.mysql_error ());
while ($row=mysql_fetch_array($category_result)) {
$category=$row["category"];
$category_Options.="<OPTION VALUE=\"$category\">".$category.'</option>';
}
?>
<p>
<SELECT NAME="category"><OPTION VALUE=0>Choose<?=$category_Options?></SELECT>
</p>
<input name="submit" "id="submit" type="submit" value="submit" />
</form>
<?php
if(isset($_POST['submit'])){
if(isset($_GET['go'])){
$category=$_POST['category'];
$category=mysql_real_escape_string($category);
$sql="SELECT category, company, address, city, state, zip, phone, web, addescription, image
FROM Members
WHERE category LIKE '$category'";
$result=mysql_query($sql);
while($row=mysql_fetch_array($result)){
$category2=$row["category"];
$company=$row["company"];
$address=$row["address"];
$city=$row["city"];
$state=$row["state"];
$zip=$row["zip"];
$phone=$row["phone"];
$web = $row["web"];
$addescription = $row["addescription"];
$image = $row["image"];
echo "<blockquote>";
if(@file_get_contents($image))
{
echo "<img src='".$image ."' class='image'/>\n";
}
else
{
}
echo "<p>\n";
echo "</br>".$category2 . "\n";
echo "</br><b>".$company . "</b>\n";
echo "</br>".$address . "\n";
echo "</br>".$city . ", ".$state. " ".$zip . "\n";
echo "</br>".$phone . "\n";
echo "</br><a href=http://".$web .">".$web ."</a>\n";
echo "</br>".$addescription . "\n";
echo "</br><a href=http://www.printfriendly.com style=color:#6D9F00;text-decoration:none; class=printfriendly onclick=window.print();return false; title=Printer Friendly and PDF><img style=border:none; src=http://cdn.printfriendly.com/pf-button.gif alt=Print Friendly and PDF/></a>\n";
echo "</p>";
echo "</blockquote>"
;
}
}
else{
echo "<p>Please select a Category</p>";
}
}
mysql_close($db)
?>
答案 0 :(得分:3)
不推荐使用MySQL函数。使用MySQLi函数和预处理语句是防止sql注入攻击的更好方法。
$stmt = $mysqli->prepare('SELECT category, company, address, city, state, zip, phone, web, addescription, image FROM Members WHERE category LIKE ?');
$stmt->bind_param('s', $category);
答案 1 :(得分:1)
我将展示PDO连接的实现以及如何使用它进行查询。在这里!
首先,我们使用您的数据库凭据创建连接变量。我们会将此连接存储在$db
。
$username = "root";
$password = "";
$host = "localhost";
$dbname = "my_database";
$options = array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8');
try{
$db = new PDO("mysql:host={$host};dbname={$dbname};charset=utf8"; $username, $password, $options);
}catch(PDOException $ex){
die("Failed to connect: ".$ex->getMessage());
}
现在您有一个存储在$db
中的PDO连接,您可以通过该连接进行查询。如果您不使用PHP 5.4,则可能需要考虑magic quotes,因此请记住这一点。
否则,像这样创建查询语句..
$query = "SELECT category, company, address, city, state, zip, phone, web, addescription, image FROM Members WHERE category LIKE :category"
之后,您希望将$_POST['category']
变量(或创建该变量后的$category
)中的值绑定到参数:category
。这样做:
$query_params = array( ':category' => $category);
最后,既然您已经拥有了语句和参数,请使用先前创建的$db
变量来准备和执行语句。
$statement = $db->prepare($query);
$result = $statement->execute($query_params);
由于我们SELECT
数据可以返回多行(假设您在一个类别中有多行),我们需要考虑到这一点。抓取语句返回的行,如下所示:
$rows = $statement->fetchAll();
现在,您可以使用foreach语句引用数据库表的每个$row
中的列标题。
$citiesArray = array();
foreach($rows as $row){
if(isset($row['city'])){
$citiesArray[] = $row['city'];
}
}
希望有所帮助!
答案 2 :(得分:1)
请记住永不信任您的用户的黄金法则。永远不要接受任何原始用户输入并将其插入数据库,因为您可能会因安全问题而敞开大门。
您的代码似乎很好。但请注意,自PHP 5.5.0起不推荐使用MySQL,而应使用MySQLi或PDO扩展来提供更高的安全性。
也许这就是你的主持人说出这样的事情的原因,但是从快速查看你的代码看起来对我来说似乎很好。
干杯。
答案 3 :(得分:0)
问题是代码中的以下部分
$sql = "SELECT category, company, address, city, state, zip,
phone, web, addescription, image
FROM Members
WHERE category LIKE '$category'";
$result=mysql_query($sql);
如果从GET或POST参数中读取参数$ category,则应为escaped:
$sql = "SELECT category, company, address, city, state, zip,
phone, web, addescription, image
FROM Members
WHERE category LIKE '" . mysql_real_escape_string($category) . "';";
如果您这样做,该变量不能用于SQL Injection
顺便说一句(就像Matthew Johnson所说的那样),自PHP 5.5以来,程序的mysql扩展已被弃用。您最好使用Mysqli或PDO。
OOP方式(强烈推荐)看起来像:
$pdo = new PDO($dsn, $user, $password, $options);
$statement = $pdo->prepareStatement(
"SELECT category, company, address,
city, state, zip, phone, web,
addescription, image
FROM Members
WHERE category LIKE :category;");
$statement->bindParam(':category', $category, PDO::PARAM_STR);
$statement->execute();
$categories = $statement->fetchAll();