(从“在GET请求中测试非空查询?”中重新命名,因为当我编写它时,结果并不是我问题的重要部分。)
我正在用一个简单的数据库搜索脚本帮助一个系谱专家朋友。如果用户将除一个输入字段之外的所有字段留空,则可以。我想区分3个案例:
我可以用同样的方式对待1和2;这不需要花哨。
以前的代码有一个if (isset($_POST['submit']))
,显然已经习惯了。我想使用GET
查询,以便人们可以为搜索添加书签。我首先假设我可以只测试$_GET['submit']
,但它从未设置过。对于GET
查询,我假设我需要在表单中使用名为submit
的隐藏文本字段,以在查询网址中生成?submit=
?进一步混乱URL不是我想要的,所以我想我会抛弃这个想法。
Google在isset($_GET['submit'])
,论坛等上发现了很多点击量。通常问题中的其他不良代码引起了人们的注意,因此我从未发现任何关于实际使用GET
查询构造的讨论。因此,作为主要问题的副线,我很好奇isset($_GET['submit'])
如何成为半常见的。这通常只是像我这样天真的人将POST
更改为GET
吗?
由于我是PHP的新手,如果有人能够在搜索脚本的这个片段中指出任何其他问题,我真的很感激。我很确定它对SQL注入很开放,所以我需要使用转义函数的输出来清理它们。是否也常常检查输入字符串的长度?向此脚本提交查询的表单具有长度限制。
(我知道SO不欢迎代码复习问题,所以我可以随意忽略这部分问题。)
msearchresultlist.php:
从表单中接收...php/?Surname=Cordes&MaidenName=&GivenName=&Obit=
之类的查询(包含在此代码块的末尾)。
它打印出一张火柴表
每行中的一个条目是指向该ob告的详细信息页面的超链接。
<?PHP
... check that user is logged in to members area ...
if (some_condition_discussed_above) {
... open the DB, with hard-coded username/password :( ...
$GivenName = $_GET['GivenName'];
if ($GivenName == "")
{$GivenName = '%';}
$Surname = $_GET['Surname'];
if ($Surname == "")
{$Surname = '%';}
$MaidenName = $_GET['MaidenName'];
if ($MaidenName == "")
{$MaidenName = '%';}
$Obit = $_GET['Obit'];
$result = mysql_query ("SELECT * FROM obits
WHERE GivenName LIKE '%$GivenName%'
AND MaidenName LIKE '$MaidenName%'
AND Surname LIKE '$Surname%'
AND Obit LIKE '%$Obit%'
ORDER BY Surname ASC, GivenName ASC");
} else {
$noquery = true;
}
?>
<!DOCTYPE html>
<html lang="en">
... some stuff on the page
<?php
if ($noquery) {
print "<p>No query found.</p>";
} else {
print "<table width='600' cellpadding='10px'>";
if($row = mysql_fetch_array($result)) {
do {
print "<tr>";
print "<td>".$row['Surname']."</td>";
print "<td>".$row['MaidenName']."</td>";
print "<td>" . '<a href="msearchresultform.php?ID='.$row['ID'].'">'.$row['GivenName'].'</a>'. "</td>";
print "<td>".$row['DOD']."</td>";
print"</tr>";
} while($row = mysql_fetch_array($result));
---- the form, on another page:
<form action=msearchresultlist.php method=GET>
When searching for a name with an apostrophe, such as O'Neil, use a double apostrophe, ie. O''Neil, not a quote but a double apostrophe. </br>
</br>
Search for:
<p>Last Name: <input type=text name=Surname size=15 maxlength=15>
<p>Maiden Name: <input type=text name=MaidenName size=15 maxlength=15>
<p>Given Name: <input type=text name=GivenName size=15 maxlength=15>
<p>Use % in front of each word in the Obit field, ie %Bridgewater% %Joudrey%
<p>Obit: <input type=text name=Obit size=50 maxlength=50>
<p>
<input type=submit>
我知道搜索可以通过搜索单个通配符或其他东西来转储整个数据库。我认为这是我朋友想要的结果,但我不希望它偶然发生。即,只有当用户明确搜索通配符时,才会提交空表单。此高级搜索脚本仅供经过身份验证的用户使用。有一个仅限姓氏的版本(nsobits.ca)
无论如何,如果不清楚我在问什么:我能做些什么聪明的事情来检查表格中是否填写了什么内容?像某些语法一样检查$_GET
至少有一个密钥的非零长度值?或者我应该if ($GivenName || $Surname || ...)
?
答案 0 :(得分:2)
我要提到的第一件事是使用旧的,已弃用的 mysql *()_函数。您应该真正使用PDO或MySQLi库。 关于如何防止SQL注入,以及如何正确使用PDO / MySQLi,都有really good reply。我强烈建议你阅读。
至于代码,这大致与我的方式相同:(我的评论带有前缀 CF )
// ... open the DB, with hard-coded username/password :( ...
/**
* Parses the input, if any, and returns an iterative with the results.
* @param PDO $db
* @return boolean|multitype:
*/
function parse_submit($db)
{
// ... check that user is logged in to members area ...
if (! isset($_GET['submit_btn'])) {
// CF: False == No form submitted. We're testing for this specifically later.
return false;
}
// CF: Used for taking care of input, and checking whether we have input.
$params = array();
$submitted = false;
// CF: Preferably add some proper input validation here, to make sure you get what could be a name.
if (empty($_GET['GivenName'] == "")) {
$params[':given'] = '%';
} else {
$params[':given'] = '%' . $_GET['GivenName'] . '%';
$submitted = true; // Update: Was missing this line in my original posting.
}
/*
* CF: Do the rest of the params as above.
*/
// CF: Here we test for empty submission.
if (! $submitted) {
// Return empty array to simulate a non-hit query.
return array();
}
$stmt = $db->prepare("SELECT * FROM obits
WHERE GivenName LIKE :given
AND MaidenName LIKE :maiden
AND Surname LIKE :surname
AND Obit LIKE :obit
ORDER BY Surname ASC, GivenName ASC");
return $stmt->exec($params);
}
/**
* Shortcut version of htmlspecialchars ()
*
* @param string $string
* @return string
*/
function hs($string)
{
return htmlspecialchars($string, null, 'utf-8');
}
$persons = parse_submit($db);
?>
<!DOCTYPE html>
<html lang="en">
... some stuff on the page
<?php
if ($persons === false) {
print "<p>No query found</p>";
} elseif (empty($persons)) {
print "<p>No search results found.</p>";
} else {
// CF: Using a output variable and a template to keep things clean.
$output = "<table>";
$outTemplate = <<<EOHTML
<tr>
<td>%1\$s</td>
<td>%2\$s</td>
<td><a href="msearchresultform.php?ID=%3\$d">%4\$s</a></td>
<td>%5\$s</td>
</tr>
EOHTML;
// CF: Since PDO result sets are iterative using PHP's functions, we use it directly here.
foreach ($persons as $r) {
$output .= sprintf($outTemplate, hs($r['Surname']), hs($r['MaidenName']), $r['ID'], hs($r['GivenName']), hs($r['DOD']));
}
echo $output . "</table>";
}
要使其生效,您需要将表单标记的操作属性更改为 get 。反映将数据发送到服务器的方法的变化,以及您尝试使用的阵列的名称。 我还建议将提交按钮的名称更改为除了提交&#34;之外的其他名称,以避免DOM事件出现问题。
&#34;聪明&#34;你问的问题是我的例子中的 $ submitted 变量。 ;)
我现在的最后一个改进领域是使用编码风格。在您的示例中,没有应用明确的样式,花括号或多或少随机放置。你坚持哪种编码风格并不重要,但选择一种并坚持不懈地坚持下去。通过这样做,您将在未来为自己和他人节省很多麻烦。 recommended style at this point in time is PSR-2,这是大多数主要PHP库正在使用的。
当您对PHP有更多经验时,您可能还想看看使用模板引擎和框架。只要你掌握了所有的基础知识,他们就会帮助你提高工作效率。
发布编辑后更新 我发现你根本没有为输入控件命名,这就是为什么你没有看到&#34; submit =&#34; URL中的键值参数。
PS:有安全意识的金星!
答案 1 :(得分:0)
您可以使用:
if(isset($_GET['variableName']) AND !empty($_GET['variableName']))
这将检查它是否已设置且不是空字符串。
或者,此函数将循环遍历$ _GET(这是一个数组),如果找到任何未填充的值,则返回true:
function fieldsEmpty(){
foreach($_GET as $key => $value){
if(empty($value)){
return true;
}
}
}
if(fieldsEmpty()){
// handle error
}