1

I have 4 dynamic dependent select boxes, now I want to combine the result of the 4 selects into a query. I have all the relative code below.

font-end part of the select boxes

<form class="select-boxes" action="<?php echo site_url("/part-search-result/"); ?>" method="POST" target="_blank">
    <?php include(__DIR__.'/inc/part-search.php'); ?>
</form>

part-search.php

<?php
    include( __DIR__.'/db-config.php' );
    $query = $db->query("SELECT * FROM ps_manufact WHERE status = 1 ORDER BY manufact_name ASC");
    $rowCount = $query->num_rows;
?>

<select name="manufacturer" id="manufact" onchange="manufactText(this)">
    <option value="">Select Manufacturer</option>
    <?php
        if($rowCount > 0){
            while($row = $query->fetch_assoc()){
                echo '<option value="'.$row['manufact_id'].'">'.$row['manufact_name'].'</option>';
            }
        }else{
            echo '<option value="">Manufacturer Not Available</option>';
        }
    ?>
</select>
<input id="manufacturer_text" type="hidden" name="manufacturer_text" value=""/>
<script type="text/javascript">
    function manufactText(ddl) {
        document.getElementById('manufacturer_text').value = ddl.options[ddl.selectedIndex].text;
    }
</script>

<select name="type" id="type" onchange="typeText(this)">
    <option value="">Select Manufacturer First</option>
</select>
<input id="type_text" type="hidden" name="type_text" value=""/>
<script type="text/javascript">
    function typeText(ddl) {
        document.getElementById('type_text').value = ddl.options[ddl.selectedIndex].text;
    }
</script>

<select name="year" id="year" onchange="yearText(this)">
    <option value="">Select Type First</option>
</select>
<input id="year_text" type="hidden" name="year_text" value=""/>
<script type="text/javascript">
    function yearText(ddl) {
        document.getElementById('year_text').value = ddl.options[ddl.selectedIndex].text;
    }
</script>

<select name="model" id="model" onchange="modelText(this)">
    <option value="">Select Year First</option>
</select>
<input id="model_text" type="hidden" name="model_text" value=""/>
<script type="text/javascript">
    function modelText(ddl) {
        document.getElementById('model_text').value = ddl.options[ddl.selectedIndex].text;
    }
</script>

<input type="submit" name="search" id="search" value="Search">


<script type="text/javascript">
    jQuery(function($) {
        $('#manufact').on('change',function(){
            var manufactID = $(this).val();
            if(manufactID){
                $.ajax({
                    type:'POST',
                    url:'<?php echo home_url('wp-content/themes/myTheme/inc/ajax-data.php') ?>',
                    data:'manufact_id='+manufactID,
                    success:function(html){
                        $('#type').html(html);
                        $('#year').html('<option value="">Select Type First</option>');
                    }
                });
            }else{
                $('#type').html('<option value="">Select Manufact First</option>');
                $('#year').html('<option value="">Select Type First</option>');
            }
        });

        $('#type').on('change',function(){
            var typeID = $(this).val();
            if(typeID){
                $.ajax({
                    type:'POST',
                    url:'<?php echo home_url('wp-content/themes/myTheme/inc/ajax-data.php') ?>',
                    data:'type_id='+typeID,
                    success:function(html){
                        $('#year').html(html);
                        $('#model').html('<option value="">Select Year First</option>');
                    }
                });
            }else{
                $('#year').html('<option value="">Select Type First</option>');
                $('#model').html('<option value="">Select Year First</option>');
            }
        });

        $('#year').on('change',function(){
            var yearID = $(this).val();
            if(yearID){
                $.ajax({
                    type:'POST',
                    url:'<?php echo home_url('wp-content/themes/myTheme/inc/ajax-data.php') ?>',
                    data:'year_id='+yearID,
                    success:function(html){
                        $('#model').html(html);
                    }
                });
            }else{
                $('#model').html('<option value="">Select Year First</option>');
            }
        });
    });
</script>

ajax-data.php

<?php

include( __DIR__.'/db-config.php' );

if(isset($_POST["manufact_id"]) && !empty($_POST["manufact_id"])){
    $query = $db->query("SELECT * FROM ps_type WHERE manufact_id = ".$_POST['manufact_id']." AND status = 1 ORDER BY type_name ASC");

    $rowCount = $query->num_rows;

    if($rowCount > 0){
        echo '<option value="">Select Type</option>';
        while($row = $query->fetch_assoc()){
            echo '<option value="'.$row['type_id'].'">'.$row['type_name'].'</option>';
        }
    }else{
        echo '<option value="">Type Not Available</option>';
    }
}

if(isset($_POST["type_id"]) && !empty($_POST["type_id"])){
    $query = $db->query("SELECT * FROM ps_year WHERE type_id = ".$_POST['type_id']." AND status = 1 ORDER BY year_name ASC");

    $rowCount = $query->num_rows;

    if($rowCount > 0){
        echo '<option value="">Select Year</option>';
        while($row = $query->fetch_assoc()){
            echo '<option value="'.$row['year_id'].'">'.$row['year_name'].'</option>';
        }
    }else{
        echo '<option value="">Year Not Available</option>';
    }
}

if(isset($_POST["year_id"]) && !empty($_POST["year_id"])){
    $query = $db->query("SELECT * FROM ps_model WHERE year_id = ".$_POST['year_id']." AND status = 1 ORDER BY model_name ASC");

    $rowCount = $query->num_rows;

    if($rowCount > 0){
        echo '<option value="">Select Model</option>';
        while($row = $query->fetch_assoc()){
            echo '<option value="'.$row['model_id'].'">'.$row['model_name'].'</option>';
        }
    }else{
        echo '<option value="">Model Not Available</option>';
    }
}

?>

part-search-result.php

<?php

if (isset($_POST['search'])) {
    $clauses = array();
    if (isset($_POST['manufacturer_text']) && !empty($_POST['manufacturer_text'])) {
        $clauses[] = "`manufacturer` = '{$_POST['manufacturer_text']}'";
    }
    if (isset($_POST['type_text']) && !empty($_POST['type_text'])) {
        $clauses[] = "`type` = '{$_POST['type_text']}'";
    }
    if (isset($_POST['year_text']) && !empty($_POST['year_text'])) {
        $clauses[] = "`year` = '{$_POST['year_text']}'";
    }
    if (isset($_POST['model_text']) && !empty($_POST['model_text'])) {
        $clauses[] = "`model` = '{$_POST['model_text']}'";
    }
    $where = !empty( $clauses ) ? ' where '.implode(' and ',$clauses ) : '';
    $sql = "SELECT * FROM `wp_products` ". $where;
    $result = filterTable($sql);
} else {
    $sql = "SELECT * FROM `wp_products` WHERE `manufacturer`=''";
    $result = filterTable($sql);
}

function filterTable($sql) {
    $con = mysqli_connect("localhost", "root", "root", "i2235990_wp2");
    if (!$con) {
        die('Could not connect: ' . mysqli_error($con));
    }
    $filter_Result = mysqli_query($con, $sql);
    return $filter_Result;
}

?>

    <?php get_header(); ?>

    <div class="container">
        <div id="products" class="row list-group">
        <?php while ( $rows = mysqli_fetch_array($result) ): ?>
            <div class="item col-xs-12 col-sm-4 col-md-4 col-lg-4">
                <div class="thumbnail">
                    <?php
                        echo '<img name="product-image" class="group list-group-image hvr-bob" src=' . $rows['image_url'] . ' width="400px" height="250px" alt="" />';
                    ?>
                    <div class="caption">
                        <h4 class="group inner list-group-item-heading">
                        <?php
                            echo "Manufacturer:\t".$rows['manufacturer'].'<br>';
                            echo "Type:\t".$rows['type'].'<br>';
                            echo "Year:\t".$rows['year'].'<br>';
                            echo "Model:\t".$rows['model'].'<br>';
                            echo '<br>';
                            echo "Description:\t".$rows['description'].'<br>';
                        ?>
                        </h4>                           
                    </div>
                </div>
            </div>
        <?php endwhile; ?>
        </div>
    </div>

    <?php get_footer(); ?>

Now my problem is:

If only select the first one box, or select the first two boxes, and click the Search button, it successfully jumps to the result page. However, if continuously select the third box, the result page is gone and Chrome Console returns the error:

Failed to load resource: the server responded with a status of 404 (Not Found)

4

1 回答 1

4

让我问你一个问题。您已将此标记为 WordPress 网站。正确的?那你为什么不使用内置的数据库处理程序$wpdb来准备和与数据库通信呢?这是您使用数据库的最安全、最快捷的方式。

修订代码

在这里,我修改了您的代码以执行以下操作:

  • 用于$wpdb->prepare清理$_POST值以保护数据库免受恶意人员的侵害
  • 通过遍历列名列表并使用您通过_text为列名添加后缀指定的字段命名模式来删除冗余
  • 用于$wpdb->get_results()获取结果。

这是修改后的代码:

/**
 * Build the search's WHERE SQL from the form's $_POST fields.
 *
 * @since 1.0.0
 *
 * @return string
 */
function build_search_where_sql() {
    global $wpdb;

    $column_names = array(
        'manufacturer',
        'type',
        'year',
        'model',
    );

    $where_clauses = [];
    foreach( $column_names as $column_name ) {
        $post_key = $column_name . '_text';
        if ( isset( $_POST[ $post_key ] ) && $_POST[ $post_key ] ) {
            $where_clauses[] =  $wpdb->prepare( "{$column_name} = %s", $_POST[ $post_key ] );
        }
    }

    if ( empty( $where_clauses ) ) {
        return '';
    }

    $where_sql = " WHERE " . join( ' AND ', $where_clauses );

    return $where_sql;
}

/**
 * Get the search results from the database.  If the records
 * do not exist or an error occurs, false is returned.  Else,
 * an array with stdClass objects for each record is returned.
 *
 * @since 1.0.0
 *
 * @return bool|array
 */
function get_search_database_results() {
    $where_sql = isset( $_POST['search'] )
        ? build_search_where_sql()
        : "WHERE manufacturer = ''";

    if ( ! $where_sql ) {
        return false;
    }

    global $wpdb;

    $sql_query = "SELECT * FROM wp_products {$where_sql};";

    $records = $wpdb->get_results( $sql_query );

    if ( ! $records ) {
        return false;
    }

    return $records;
}

更新:为您制定的策略

既然我已经看到了您提出的 HTML 代码,并且知道您正在学习构建网站,那么让我们来谈谈您项目的不同架构策略。

  1. 不要使用自定义数据库表。
  2. 改用名为的自定义帖子类型products
  3. 使用帖子元数据设置每个产品的属性,即制造商、型号、年份、类型等。
  4. 使用表单插件,例如 Ninja Forms。
  5. 如果您有技术能力,您可以自己为元数据构建元框。否则,您可以使用第三方插件,例如 CMB2 或 ACF。

自定义帖子类型

WordPress 让您能够添加自定义内容。它们提供内置的帖子类型。我们开发人员可以添加特定内容上下文的自定义内容。产品是自定义帖子类型的理想选择。

您可以在GenerateWP上生成代码。它实际上是几行代码来创建它。

您在哪里可以了解自定义帖子类型?

好吧,有很多教程。 Codex为您提供文档和示例。我在Know the Code教它。Tuts+ 有很多教程。还有许多其他......

为什么自定义帖子类型而不是自定义 Db 表?

是的,您可以构建自定义数据库表。但它需要您添加架构、为表播种、编写界面以供管理员与内容交互,然后编写并保护交互。要填充 中的选项select,您必须使用查询数据库$wpdb,然后编写模型将其转换为视图。然后你必须编写表单处理来交互和保存。

换句话说,它会花费你的时间和金钱。为什么?因为它是更多的代码,而不是 WordPress 原生的。您必须自己编写、保护、测试和维护它。

如果您想坚持当前的策略

如果您更喜欢坚持使用自定义数据库表策略,那么这里有一些建议可以帮助您:

  1. 您不需要隐藏input每个select元素。为什么?发布表单时,为每个表单设置的选项select将回发到服务器。
  2. 我会将select名称更改为数组,如下所示:name="part-select[manufacturer]"然后重复类型、型号、年份等。然后您可以$_POST['part-select']获取所有值。
  3. 您将要添加随机数来保护内容。确保在做 AJAX 时也将其与数据包一起传递。
  4. 使用AJAX,您可以从数据库中请求记录。您需要修改我提供给您的代码才能构建 SQL 查询。然后循环遍历结果以构建要发送回前端的 HTML。
  5. 我喜欢在服务器端构建 HTML 标记,然后在执行 AJAX 时将其发送回前端。

干杯。

于 2016-11-24T18:06:31.407 回答