【问题标题】:Combine the results of several select boxes by using PHP and MySQL in WordPress在 WordPress 中使用 PHP 和 MySQL 组合几个选择框的结果
【发布时间】:2016-11-24 17:21:50
【问题描述】:

我有 4 个动态依赖选择框,现在我想将 4 个选择的结果组合到一个查询中。我有下面所有的相关代码。

选择框的字体结束部分

<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(); ?>

现在我的问题是:

如果只选择第一个框,或者选择前两个框,点击Search按钮,成功跳转到结果页面。但是,如果连续选择第三个框,结果页面就没有了,Chrome 控制台返回错误:

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

【问题讨论】:

    标签: php mysql wordpress jquery-selectbox


    【解决方案1】:

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

    修改后的代码

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

    • 使用$wpdb-&gt;prepare 清理$_POST 值以保护数据库免受恶意人员的攻击
    • 通过遍历列名列表并使用您指定的字段命名模式(通过在列名后添加_text)来删除冗余
    • 使用$wpdb-&gt;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 让您能够添加自定义内容。它们提供内置的帖子类型。我们开发人员可以添加特定内容上下文的自定义内容。 Products 是自定义帖子类型的理想选择。

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

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

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

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

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

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

    如果您想坚持当前的策略

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

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

    干杯。

    【讨论】:

    • 我刚开始学习使用 WordPress 构建网站。感谢您帮助我更多地了解 WordPress 规则。我只是编辑问题以添加框的 HTML。我想知道我是否还应该添加动态依赖部分。
    • 按照你的方式,如何打印搜索结果的每一行?我试过但无法正确获取。
    • @L.Leo 我修改了上面的答案,为您的项目提供推荐策略。我建议您使用自定义帖子类型而不是自定义数据库表。这将节省您的时间、金钱和挫败感。此外,这对您的客户来说是一个更好的策略,因为它很好地集成到了 WordPress CMS 中。
    • 感谢您的建议。如果我使用自定义帖子类型,选择框问题也能解决吗?
    • @L.Leo,您的表单中 select 元素的原始问题可以使用任一策略来解决。自定义帖子类型仅仅消除了编写、测试和维护 WordPress 之外的解决方案的所有额外代码和时间。
    猜你喜欢
    • 2019-07-06
    • 1970-01-01
    • 2011-02-27
    • 2011-02-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-07
    • 1970-01-01
    相关资源
    最近更新 更多