有没有更简单的方法来使用url变量来过滤mysql结果?我写了下面的代码,它在一定程度上起作用,我知道必须有一个更简单的方法,但我不知道从哪里开始。我宁愿换这个,因为它只有一半用。
$start=0;
$limit=3;
if(isset($_GET['pg']))
{
$pg=$_GET['pg'];
$start=($pg-1)*$limit;
}
else {
$pg = 1;
}
$sql = mysql_query($query);
if(isset($_GET['signage'])) {
$result = mysqli_query($conn,"SELECT * FROM pilotOperators WHERE signage='1' LIMIT $start, $limit");
}
elseif(isset($_GET['certifications'])) {
$certification = $_GET['certifications'];
$result = mysqli_query($conn,"SELECT * FROM pilotOperators WHERE certifications='$certification' LIMIT $start, $limit");
}
elseif(isset($_GET['state'])) {
$state = $_GET['state'];
$result = mysqli_query($conn,"SELECT * FROM pilotOperators WHERE state='$state' LIMIT $start, $limit");
}
elseif(isset($_GET['certifications'], $_GET['signage'])) {
$certification = $_GET['certifications'];
$signage = $_GET['signage'];
$result = mysqli_query($conn,"SELECT * FROM pilotOperators WHERE signage='$signage' AND certifications='$certification' LIMIT $start, $limit");
}
elseif(isset($_GET['certifications'], $_GET['signage'], $_GET['state'])) {
$certification = $_GET['certifications'];
$signage = $_GET['signage'];
$state = $_GET['state'];
$result = mysqli_query($conn,"SELECT * FROM pilotOperators WHERE signage='$signage' AND certifications='$certification' AND state='$state' LIMIT $start, $limit");
}
else {
$result = mysqli_query($conn,"SELECT * FROM pilotOperators LIMIT $start, $limit");
}
while($row = mysqli_fetch_array($result))
{
echo "\n <table border='0' class='resultTable' width='75%'> \n";
echo "<tr> \n";
echo "<td width='120px'>ID: </td> \n";
echo "<td>" . $row['id'] . "</td> \n";
echo "</tr> \n";
echo "<tr> \n";
echo "<td>Name: </td> \n";
echo "<td>" . $row['name'] . "</td> \n";
echo "</tr> \n";
echo "<tr> \n";
echo "<td>Phone: </td> \n";
echo "<td>" . $row['phone'] . "</td> \n";
echo "</tr> \n";
echo "<tr> \n";
echo "<td>Alt. Phone: </td> \n";
echo "<td>" . $row['alt_phone'] . "</td> \n";
echo "</tr> \n";
echo "<tr> \n";
echo "<td>Fax: </td> \n";
echo "<td>" . $row['fax'] . "</td> \n";
echo "</tr> \n";
echo "<tr> \n";
echo "<td>Email: </td> \n";
echo "<td>" . $row['email'] . "</td> \n";
echo "</tr> \n";
echo "<tr> \n";
echo "<td>Website: </td> \n";
echo "<td><a href='" . $row['website'] . "' target='_blank'>" . $row['website'] . "</a></td> \n";
echo "</tr> \n";
echo "<tr> \n";
echo "<td>City: </td> \n";
echo "<td>" . $row['city'] . "</td> \n";
echo "</tr> \n";
echo "<tr> \n";
echo "<td>State: </td> \n";
echo "<td>" . $row['state'] . "</td> \n";
echo "</tr> \n";
echo "<tr> \n";
echo "<td>Certifications: </td> \n";
echo "<td>" . $row['certifications'] . "</td> \n";
echo "</tr> \n";
echo "<tr> \n";
echo "<td>Top Sign: </td> \n";
echo "<td>";
if($row['signage'] = 1) {
echo "Has Top Sign";
}
else {
echo "Top Sign Not Listed";
}
echo "</td> \n";
echo "</tr> \n";
echo "</table> \n\n";
}
$rows = mysqli_num_rows(mysqli_query($conn, "SELECT * FROM pilotOperators"));
$total=ceil($rows/$limit);
echo "<div id='paginationLinks'> \n";
if($pg>1)
{
echo "<a href='?pg=".($pg-1)."' class='paginationButton'>PREVIOUS</a> \n";
}
if($pg!=$total)
{
echo "<a href='?pg=".($pg+1)."' class='paginationButton'>NEXT</a> \n";
}
echo "<ul class='page'> \n";
for($i=1;$i<=$total;$i++)
{
if($i==$pg) { echo "<li class='current'>".$i."</li> \n"; }
else { echo "<li><a href='?id=".$i."'>".$i."</a></li> \n"; }
}
echo "</ul> \n";
echo "</div> \n";
mysqli_close($con);
当我说这个代码有点管用时,请允许我解释一下。当我的url中有多个变量时(即?标牌=价值&认证=价值)代码的作用类似于它拥有或代替了和。
像这样:$result=mysqli_query($conn,“SELECT*FROM pilotOperators WHERE signage='$signage'OR certifications='$certification'LIMIT$start,$LIMIT”);
而不是这个:$result=mysqli_query($conn,“SELECT*FROM pilotOperators WHERE signage='$signage'AND certifications='$certification'LIMIT$start,$LIMIT”);
如果我的URL包含以下&signage=1&certifications=washington,则它不仅向我显示同时具有这两个证书的结果,而且还向我显示具有washington证书或signage=1的人的结果。
我没有太多变量可以传递。应该只有3个,但我的方法似乎很复杂。
我能做些什么来简化这个过程,为什么我的和我的行为类似,或者在试图过滤结果时。
最佳答案
问:我能做些什么来简化这个问题?
A:您可以执行如下操作,有条件地将谓词追加到SQL语句中,并将该语句推迟到完全构建完成后再运行。看起来您只需要运行一个SQL语句,所以只需要调用一个mysqli_query
。填充变量以包含用SQL文本填充的内容,并让mysqli_query
引用该变量。
注意:必须正确转义任何潜在的不安全值,以阻止SQL注入漏洞。(注意在SQL文本中包含的每个值周围使用mysqli_real_escape_string
函数。)
例如:
# start of SQL statement
$sql = "SELECT * FROM pilotOperators WHERE 1=1";
# append condition for signage (if required)
if(isset($_GET['signage'])) {
$sql .= " AND signage='1'";
}
# append condition for certifications (if required)
if(isset($_GET['certifications'])) {
$certification = mysqli_real_escape_string($conn,$_GET['certifications']);
$sql .= " AND certifications='$certification'"
}
# append condition for state (if required)
if(isset($_GET['state'])) {
$state = mysqli_real_escape_string($conn,$_GET['state']);
$sql .= " AND state='$state'";
}
# append ORDER BY and LIMIT
$sql .= " ORDER BY 1,2,3";
$sql .= " LIMIT " . mysqli_real_escape_string($conn,$start)
. "," . mysqli_real_escape_string($conn,$limit);
#echo "SQL=" . $sql; // for debugging
$result = mysqli_query($conn,$sql);
我还添加了ORDER BY子句,这样行将以确定的顺序返回;替换对所需列的位置引用。
WHERE 1=1
是一个虚拟占位符,其值始终为TRUE。这样做的目的是,任何后续谓词都可以用AND
添加,我们不需要费劲去弄清楚这是否是要添加的第一个谓词,我们需要使用WHERE
而不是AND
。每个附加部分的前导空格都很重要。(我只是觉得作为一个主角来处理这个问题比较容易,而不是记着在结尾处加上它,但是你可以在每个部分的结尾都留有空格)。
问:为什么我的行为像或?
A:不是,你永远不会得到一个包含
AND
的语句。如果设置了“certifications”,则执行的SQL语句只包含certifications
列上的谓词。“认证”和“状态”都已设置,您永远无法到达elseif
。后续行动
上面的代码中有一个错误,一行中缺少分号(语句结束符):
$sql .= " AND certifications='$certification'" ;
^
.=
运算符将右侧的值附加到左侧变量的当前值。也就是说,这个声明$x .= "foo";
做和这句话一样的事。
$x = $x . "foo";
变量
$certification
和$state
实际上不是必需的。您可以删除这两行: $state = mysqli_real_escape_string($conn,$_GET['state']);
$sql .= " AND state='$state'";
换成这个:
$sql .= " AND state='" . mysqli_real_escape_string($conn,$_GET['state']) . "'";
但是把它分成两行会更容易调试和发现错误,很容易添加
echo
或var_dump
进行调试。。。 $state = mysqli_real_escape_string($conn,$_GET['state']);
echo "state=" . $state ;
var_dump($state);
$sql .= " AND state='$state'";
关于php - PHP MySQL变量过滤器-“AND”的行为类似于“OR”,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/29972601/