Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/58.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/157.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PHP表单和DB查询输入验证_Php_Mysql_Forms_Validation - Fatal编程技术网

PHP表单和DB查询输入验证

PHP表单和DB查询输入验证,php,mysql,forms,validation,Php,Mysql,Forms,Validation,(重新命名为“测试GET请求中的非空查询?”,因为在我写完时,这并不是我问题的重要部分。) 我正在用一个简单的DB搜索脚本帮助一位系谱学家朋友。如果用户将除一个输入字段外的所有输入字段都留空就可以了。我想区分3种情况: 有人浏览到没有查询参数的URL 所有字段为空的表单提交 至少有一个字段为非空的表单提交 我可能可以用同样的方法对待1和2;这不需要花哨 代码以前有一个if(isset($\u POST['submit']),显然是用来工作的。我想使用GET查询,这样人们就可以将搜

(重新命名为“测试GET请求中的非空查询?”,因为在我写完时,这并不是我问题的重要部分。)

我正在用一个简单的DB搜索脚本帮助一位系谱学家朋友。如果用户将除一个输入字段外的所有输入字段都留空就可以了。我想区分3种情况:

  • 有人浏览到没有查询参数的URL
  • 所有字段为空的表单提交
  • 至少有一个字段为非空的表单提交
我可能可以用同样的方法对待1和2;这不需要花哨

代码以前有一个
if(isset($\u POST['submit'])
,显然是用来工作的。我想使用
GET
查询,这样人们就可以将搜索添加到书签中。我首先假设我可以测试
$\u GET['submit']
,但它从未设置过。对于
GET
查询,我假设需要一个名为
submit
的隐藏文本字段,以便在查询URL中生成
?submit=
?我不想把URL弄得乱七八糟,所以我想我会放弃这个想法

谷歌在论坛等网站上找到了很多关于isset($\u GET['submit'])的点击率。通常问题中的其他错误代码会引起人们的注意,因此我从未发现任何关于在
GET
查询中实际使用该结构的讨论。因此,作为主要问题的旁白,我很好奇
isset($\u GET['submit'])
是如何变得半普遍的。这通常只是像我这样天真的人把
POST
改成
GET

由于我是PHP新手,如果有人能指出搜索脚本片段中的任何其他问题,我将不胜感激。我很确定它对SQL注入是完全开放的,所以我需要获取一个转义函数的输出来清理它们。检查输入字符串的长度也很常见吗?向该脚本提交查询的表单有长度限制

(我知道SO不欢迎代码审查问题,所以我想可以忽略我问题的这一部分。)

msearchresultlist.php:
从表单(包含在此代码块末尾)接收查询,如
…php/?names=Cordes&MaidenName=&GivenName=&Obit=
。 它打印出一张匹配表。
每行中有一个条目是指向该讣告详细信息页面的超链接

<?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>
您可以使用:

if(isset($_GET['variableName']) AND !empty($_GET['variableName']))
这将检查它是否已设置且不是空字符串

或者,此函数将循环通过$\u GET(它是一个数组),如果发现任何未填充的值,则返回true:

function fieldsEmpty(){
    foreach($_GET as $key => $value){
        if(empty($value)){
            return true;
        }
    }
}
if(fieldsEmpty()){
    // handle error
}

我想提到的第一件事是使用旧的、不推荐使用的mysql*()函数。您应该真正使用PDO或MySQLi库。 关于如何防止SQL注入,以及如何正确使用PDO/MySQLi,都有很多问题需要解决。我强烈推荐你读这本书

至于代码,我大致是这样做的:(我的注释前缀为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>";
}
/。。。使用硬编码的用户名/密码打开数据库:(。。。
/**
*解析输入(如果有),并返回一个包含结果的迭代。
*@param-PDO$db
*@return boolean |多类型:
*/
函数parse_submit($db)
{
//…检查用户是否登录到成员区域。。。
如果(!isset($\u GET['submit\u btn'])){
//CF:False==未提交表单。我们将在稍后进行测试。
返回false;
}
//CF:用于处理输入,并检查我们是否有输入。
$params=array();
$submitted=false;
//CF:最好在这里添加一些适当的输入验证,以确保您获得可能的名称。
if(空($\u GET['GivenName']==“”){
$params[':给定']='%';
}否则{
$params[':给定的']='%'。$\u获取['GivenName'].%';
$submitted=true;//更新:在我的原始发布中缺少此行。
}
/*
*CF:按上述方法执行其余参数。
*/
//CF:这里我们测试空提交。
如果(!$已提交){
//返回空数组以模拟非命中查询。
返回数组();
}
$stmt=$db->prepare(“从讣告中选择*)
GivenName喜欢的地方:GivenName
还有少女的名字:少女
和姓一样:姓
和讣告一样:讣告
按姓氏ASC排序,GivenName ASC);
返回$stmt->exec($params);
}
/**
*htmlspecialchars()的快捷版本
* 
*@param string$string
*@返回字符串
*/
函数hs($string)
{
返回htmlspecialchars($string,null,'utf-8');
}
$persons=parse_submit($db);
?>
…页面上有些东西

是的,它对sql注入攻击非常开放。您应该使用全文索引进行这样的搜索,并且一定要阅读注入防御技术:)。e、 g.停止使用mysql_*()函数,切换到PDO+带有占位符的预处理语句这里有很多srtuff,这使得整个问题太宽泛了。关于可能使用的问题,您是对的,但是在发布之前,请查看他们的帮助中心。在做任何其他事情之前,阅读《是的,对不起,我有多动症,永远都不能停在一个简单的问题上》。我总是要把它弄得更复杂!我不明白你为什么这么关心
$\u GET['submit']
是否有人填写。我同意您先前的说法,即如果您不关心是否有人通过表单或其他方法进入搜索页面,那么用例1和用例2是相同的。这将减少对某种
$\u GET['submit']
值的需求。@MikeBrant:是的,当我考虑需要验证用户提交表单时案例的输入时,我得到了相同的结论。我仍然好奇的是,为什么你会在网络上的php问题中看到这个
$\u GET['submit']
结构。人们真的用隐藏元素编写表单只是为了提交
submit吗