按类别、价格和地区筛选产品

Product Refine filter by categories, price and regions

我还在学习网络开发,我正在做一个项目,以学习如何开发一个具有所有功能的完整网站。我目前正在尝试按类别、条件、区域和价格实施产品优化过滤器。我开始只根据类别和地区进行筛选,想看看我该怎么做,但我的尝试失败了。每当我选中一个框时,它都会获取 url 中的 categoryId,但会给我一个关于 sql 语法的错误。

收到的错误信息:

我有 4 个 table 广告 table 带有 adId、标题、catId、regionId、价格、条件、描述 类别 table,带有 catId、catName 区域 table 带有 regionId、regionName 图片 table with imageId,adId,path, preview

谁能帮我找到解决问题的方法?

这是我的 class 文件

public function getAllCat(){
    $query = "SELECT * FROM category ORDER BY catId";
    $result = $this->db->select($query);
    return $result;

}
    public function getAllRegion(){
    $query = "SELECT * FROM region ORDER BY regionId";
    $result = $this->db->select($query);
    return $result;
}
    public function getAllAds(){
    $query = "SELECT * FROM ads ORDER BY adId DESC";
    $result = $this->db->select($query);
    return $result;
}

public function getPreviewImage($id){
    $query = "SELECT * FROM images WHERE adId = $id AND preview = '1' ";
    $image = $this->db->select($query);
    return $image;

}

这是我的 allads.php 文件

<?php

//declaration array varible
 $filtercategory = array();
 $filterregion = array();

//finding query string value
if(isset($_REQUEST['filtercategory'])){
  //query string value to array and removing empty index of array
$filtercategory = array_filter(explode("-",$_REQUEST['filtercategory']));
 }
if(isset($_REQUEST['filterregion'])){

$filterregion = array_filter(explode("-",$_REQUEST['filterregion']));
}
?>
<main class="cd-main-content">
    <div class="Ads-Container">
        <?php 
                //Pagination start
                $query = "SELECT COUNT(adId) FROM ads";
                $result = $db->select($query);
                $row = mysqli_fetch_row($result);
                // Here we have the total row count
                $rows = $row[0];
                // This is the number of results we want displayed per page
                $page_rows = 20;
                // This tells us the page number of our last page
                $last = ceil($rows/$page_rows);
                // This makes sure $last cannot be less than 1
                if($last < 1){
                    $last = 1;
                }
                // Establish the $pagenum variable
                $pagenum = 1;
                // Get pagenum from URL vars if it is present, else it is = 1
                if(isset($_GET['pn'])){
                    $pagenum = preg_replace('#[^0-9]#', '', $_GET['pn']);
                }
                // This makes sure the page number isn't below 1, or more than our $last page
                if ($pagenum < 1) { 
                    $pagenum = 1; 
                } else if ($pagenum > $last) { 
                    $pagenum = $last; 
                }

                // This sets the range of rows to query for the chosen $pagenum
                $limit = 'LIMIT ' .($pagenum - 1) * $page_rows .',' .$page_rows;
            ?>

            <?php 
                    $query = "SELECT * FROM ads ORDER BY adId DESC $limit";
                    //filter query start
                      if(!empty($filtercategory)){
                       $categorydata =implode("','",$filtercategory);
                       $query .= " and catId in('$categorydata')";
                      }

                      if(!empty($filterregion)){
                       $regiondata =implode("','",$filterregion);
                       $query .= " and regionId in('$regiondata')";
                      }

                 //filter query end
                    $post = $db->select($query);
                    if($post){
                        while($result = $post->fetch_assoc()){
            ?>

        <div class="ads-column_2">
            <div class="ads-column-thumbnail">
                <?php 
                             $preview = $ad->getPreviewImage($result["adId"]);
                             if($preview){
                                while($rresult = $preview->fetch_assoc()){
                        ?>
                <img src="/afro-circle/<?php echo $rresult['path']?>" alt="" class="image-responsive">
                 <?php } } ?>
                <div class="ads-preview-details">
                   <center>
                      <h4><a href="addetails.php?adid=<?php echo $result['adId']; ?>"><?php echo $result['title']; ?></a></h4>
                      <h4 class="">FCFA <?php echo number_format($result['price']); ?></h4>
                   </center>
                </div>
                <div class="space-ten"></div>
                <div class="btn-ground text-center">
                   <a href="addetails.php?adid=<?php echo $result['adId']; ?>"><button type="button" class="btn btn-primary" data-toggle="modal" data-target="#product_view">Quick View</button></a>
                </div>
                <div class="space-ten"></div>
            </div>
        </div>

        <?php } } ?>

    </div>      
    <!-- /.row -->
       <div class="row" style="text-align: center;">
            <?php 
                // This shows the user what page they are on, and the total number of pages
                $textline1 = "Testimonials (<b>$rows</b>)";
                $textline2 = "Page <b>$pagenum</b> of <b>$last</b>";
                // Establish the $paginationCtrls variable
                $paginationCtrls = '';
                // If there is more than 1 page worth of results
                if($last != 1){
                    /* First we check if we are on page one. If we are then we don't need a link to 
                       the previous page or the first page so we do nothing. If we aren't then we
                       generate links to the first page, and to the previous page. */
                    if ($pagenum > 1) {
                        $previous = $pagenum - 1;
                        $paginationCtrls .= '<a href="'.$_SERVER['PHP_SELF'].'?pn=1">First Page</a> &nbsp; &nbsp; ';
                        $paginationCtrls .= '<a href="'.$_SERVER['PHP_SELF'].'?pn='.$previous.'">Previous</a> &nbsp; &nbsp; ';
                        // Render clickable number links that should appear on the left of the target page number
                        for($i = $pagenum-4; $i < $pagenum; $i++){
                            if($i > 0){
                                $paginationCtrls .= '<a href="'.$_SERVER['PHP_SELF'].'?pn='.$i.'">'.$i.'</a> &nbsp; ';
                            }
                        }
                    }
                    // Render the target page number, but without it being a link
                    $paginationCtrls .= '<span>'.$pagenum.'</span> &nbsp; ';
                    // Render clickable number links that should appear on the right of the target page number
                    for($i = $pagenum+1; $i <= $last; $i++){
                        $paginationCtrls .= '<a href="'.$_SERVER['PHP_SELF'].'?pn='.$i.'">'.$i.'</a> &nbsp; ';
                        if($i >= $pagenum+4){
                            break;
                        }
                    }
                    // This does the same as above, only checking if we are on the last page, and then generating the "Next"
                    if ($pagenum != $last) {
                        $next = $pagenum + 1;
                        $paginationCtrls .= ' &nbsp; &nbsp; <a href="'.$_SERVER['PHP_SELF'].'?pn='.$next.'">Next</a> ';
                        $paginationCtrls .= ' &nbsp; &nbsp; <a href="'.$_SERVER['PHP_SELF'].'?pn='.$last.'">Last Page</a> ';
                    }
                }
            ?>

            <div class="pagination">
              <div id="pagination_controls"><?php echo $paginationCtrls; ?></div>
            </div>

        </div>
        <!-- /.row -->          
    <div class="cd-filter filter-is-visible">
        <form>

            <div class="cd-filter-block">
                <h4>Categories <span class="spanbrandcls" style="float:right; visibility:hidden;"><a href="javascript:void(0);"><img src="refine/images/reset.png" alt="reset" title="reset"></a></span></h4>

                    <ul class="cd-filter-content cd-filters list">

                    <?php
                                  $getCategory = $category->getAllCat();
                                  if($getCategory){
                                    while($result = $getCategory->fetch_assoc()){
                    ?>
                    <li>
                        <input type="checkbox"  class="filter filtercategory" value="<?php echo $result['catId']; ?>" <?php if(in_array($result['catName'],$filtercategory)){ echo"checked"; } ?> >
                        <label class="checkbox-label" id="Category" ><?php echo $result['catName']; ?></label>
                    </li>

                    <?php } } ?>


                </ul> <!-- cd-filter-content -->                    
            </div> <!-- cd-filter-block -->

            <div class="cd-filter-block">
                <h4>Size <span class="spansizecls" style="float:right; visibility:hidden;"><a href="javascript:;"><img src="refine/images/reset.png" alt="reset" title="reset"></a></span></h4>

                <div class="cd-filter-content">
                    <div class="cd-select cd-filters">      
                        <select class="filter scheck" name="subcatId">
                            <option data-type="sizes" value="">Item Condition</option>

                            <option data-type="sizes" value="1">New</option>

                            <option data-type="sizes" value="2">Used</option>

                        </select>

                    </div> <!-- cd-select -->
                </div> <!-- cd-filter-content -->
            </div> <!-- cd-filter-block -->


            <div class="cd-filter-block">
                <h4>Region <span class="spancolorcls" style="float:right; visibility:hidden;"><a href="javascript:;"><img src="refine/images/reset.png" alt="reset" title="reset"></a></span></h4>

                <ul class="cd-filter-content cd-filters list">
                <?php
                                  $getRegion = $region->getAllRegion();
                                  if($getRegion){
                                    while($result = $getRegion->fetch_assoc()){
                 ?>

                    <li>
                        <input type="radio" class="filter filterregion" value="<?php echo $result['regionId']; ?>" <?php if(in_array($result['regionName'],$filterregion)){ echo"checked"; } ?>>
                        <label class="radio-label" for="radio1"><?php echo $result['regionName']; ?></label>
                    </li>

                <?php } } ?>        
                </ul> <!-- cd-filter-content -->
            </div> <!-- cd-filter-block -->
        </form>

        <a href="#0" class="cd-close"><i class="fa fa-close"></i> Close</a>
    </div>



    <a href="#0" class="cd-filter-trigger"><i class="fa fa-filter"></i> Search by:</a>
    <div class="clear"></div>

这是我的 JS

<script>
 $(function(){
  $('.filter').click(function(){
   var filtercategory = multiple_values('filtercategory');
   var filterregion = multiple_values('filterregion');

   var url ="allads.php?filtercategory="+filtercategory+"&filterregion="+filterregion;
   window.location=url;
  });

 });


 function multiple_values(inputclass){
  var val = new Array();
  $("."+inputclass+":checked").each(function() {
   val.push($(this).val());
  });
 return val.join('-');
}

问题出在下面这段代码:

$query = "SELECT * FROM ads ORDER BY adId DESC $limit";
//filter query start
if(!empty($filtercategory)){
   $categorydata =implode("','",$filtercategory);
   $query .= " and catId in('$categorydata')";
}

if(!empty($filterregion)){
   $regiondata =implode("','",$filterregion);
   $query .= " and regionId in('$regiondata')";
}

代码在sql 语句的en 处插入过滤条件,这意味着在limit 之后。因此,实际的 sql 语句如下所示:

SELECT * FROM ads ORDER BY adId DESC LIMIT 10, 10 and catId in('4')

正确的 sql 代码如下所示:

SELECT * FROM ads WHERE catId in('4') ORDER BY adId DESC LIMIT 10, 10

您必须修改 php 代码才能生成有效的 sql 代码。调试时,添加打印出完整 sql 语句的代码,以便在执行之前查看完整的 sql 语句。

此外,您的代码很容易受到 sql 注入攻击。请使用准备好的语句或其他技术来防止此类攻击。