2

我需要一个 php 脚本,它将使用表单复选框的值作为 MySQL 查询来检索数据。我想我需要在查询中使用 WHERE 和 OR 运算符。

我的 PHP 和 MySql 级别是初学者。

<form id="form1" name="form1" method="post" action="">

    <p>
        <h3>story</h3>
        <label><input type="checkbox" name="story" value="1" id="story_1" />one story</label>
        <label><input type="checkbox" name="story" value="2" id="story_2" />two story</label>
    </p>

    <p>
        <h3>bedrooms</h3>
        <label><input type="checkbox" name="bedroom" value="2" id="bed_2" />two beds</label>
        <label><input type="checkbox" name="bedroom" value="3" id="bed_3" />three beds</label>
        <label><input type="checkbox" name="bedroom" value="4" id="bed_4" />four beds</label>
    </p>

    <p>
        <h3>baths</h3>
        <label><input type="checkbox" name="bath" value="1" id="bath_1" />one bath</label>
        <label><input type="checkbox" name="bath" value="2" id="bath_2" />two baths</label>
        <label><input type="checkbox" name="bath" value="3" id="bath_3" />three baths</label>
    </p>

    <input type="submit" name="search" value="search" />

</form>

到目前为止我的查询

SELECT * FROM homes WHERE story='1' OR story='2' OR bed='3' OR baths='3'

因此,如果未选中任何复选框,则根本不会添加 WHERE 子句,并且默认检索所有记录。

4

4 回答 4

2

您可以通过使用相同的名称命名输入并后跟方括号来获取数组中的所有选定值:

HTML:
<input type="checkbox" name="bed[]" value="1" /> 一居室
<input type="checkbox" name="bed[]" value="2" /> 两居室

然后,您可以在 WHERE 子句中使用mysql IN() 函数。PHP:

$aBeds = $_POST['bed'];  // array (1,2) if both are checked
$aBeds = array_map ('intval', $aBeds); // filter with intval for sql injection
$sBeds = implode (',', $aBeds); // "1,2" if both are checked
$query = "SELECT  * FROM homes WHERE bed IN($sBeds) and ...";

注意:我在那里做了一些快速而肮脏的输入过滤,但请注意,这可能不是避免 SQL 注入的最佳方法。最好使用数据访问层、预准备语句或其他一些通用方案,其中每个查询都不需要自己的过滤代码。

于 2012-04-14T15:20:34.780 回答
2

使用带有这么多或的 select 语句会导致问题。

SELECT * FROM homes WHERE story='1' OR story='2' OR bed='3' OR baths='3'

这将生成所有故事 = 1 且具有任意数量的浴室或卧室的房屋。其中故事 = 2,带有任意数量的浴室或卧室。其中 bed = 3 带有任意数量的楼层或浴室 其中 baths = 3 带有任意数量的床或浴室

所以你最终可能会得到所有家庭的结果

你应该做的是用括号将不同的类型分开,并在它们之间使用 AND。

SELECT * FROM homes WHERE (story='1' OR story='2') and (bed='3') and (baths='3')

或者对于更复杂的查询,类似这样的。

SELECT * FROM homes WHERE (story='1' OR story='2') 
                      and (bed='3' OR bed = '4') 
                      and (baths='3' OR baths='4')

这将产生具有 1 层或 2 层的故事、3 或 4 层的卧室和 3 或 4 层的浴室的结果。你不会得到任何 3 层的房子,你不会得到任何 2 卧室的房子,你不会没有两间浴室的房子。

我认为这会做到。

于 2012-04-14T15:08:21.897 回答
1

您需要在 HTML 中的每个输入上具有唯一的“名称”属性。当表单发布时,它会被发送到“action”属性的 URL 地址。你有空白,所以你可能想把它发送到“something.php”,并在服务器上有一个同名的 PHP 文件。

如果 empty($_POST) 返回 True,您将知道表单是否已发布到 PHP 文件。此变量保存表单中发布的数据。

每个输入标签的名称属性将在 $_POST 全局变量中创建一个数组条目。因此,如果启用该复选框,则 $_POST["bath_1"] 将为 1。

有许多不同的方法可以将 $_POST 数据转换为您想要的 SQL 语句。我建议您先处理已发布的数据,然后再提出一个与处理数组和生成 SQL where 语句相关的更具体的问题。

于 2012-04-14T15:11:37.263 回答
1

我添加了一些额外的东西来避免注入攻击。

$query = 'SELECT * FROM homes WHERE 1';

// Protect against injection attacks
$valid_responses = array(
    'story' => array(
        '1','2'),
    'bedroom' => array(
        '2','3','4'),
    'bath_1' => array(
        '1','2','3'),
);
foreach ($valid_responses as $field=>$values) {
    $selection = array_intersect($_POST[$field],$values);
    if (!empty($selection)) {
        $query .= ' AND ' . $field . ' IN (' . implode(',',$selection) . ')';
    }
}
于 2012-04-14T15:13:10.417 回答