Php Laravel Eloquent:如何筛选多个和/或单个表的条件

Php Laravel Eloquent:如何筛选多个和/或单个表的条件,php,database,laravel,filter,eloquent,Php,Database,Laravel,Filter,Eloquent,我正在制作一个与房地产相关的应用程序,我一直很难弄清楚如何设置查询,以便它将返回“仅在选定区域内的公寓或复式公寓”,我希望用户能够在城市的多个选定象限中找到多种类型的房地产 我有一个数据库,它的“type”列是“公寓”、“房子”、“复式”、“移动” 在另一列中,我有带值的象限_main:“NW”、“SW”、“NE”、“SE” 我的代码在只选择了一个象限时有效,但当我选择多个象限时,我似乎得到的结果包括第二个或第三个或第四个象限中的所有属性类型,而不仅仅是“公寓”和“复式”或用户选择的任何类型。。

我正在制作一个与房地产相关的应用程序,我一直很难弄清楚如何设置查询,以便它将返回“仅在选定区域内的公寓或复式公寓”,我希望用户能够在城市的多个选定象限中找到多种类型的房地产

我有一个数据库,它的“type”列是“公寓”、“房子”、“复式”、“移动”

在另一列中,我有带值的象限_main:“NW”、“SW”、“NE”、“SE”

我的代码在只选择了一个象限时有效,但当我选择多个象限时,我似乎得到的结果包括第二个或第三个或第四个象限中的所有属性类型,而不仅仅是“公寓”和“复式”或用户选择的任何类型。。。任何帮助都将不胜感激!thx提前

我的控制器功能如下所示:

public function quadrants()
{
    $input = \Request::all();
    $currentPage = null;
    $column = "price";
    $order = "desc";

    //
    //  Looks like the input is like 0 => { key: value } ...
    //  (an Array of key/value pairs)

    $q = Listing::where('status','=','Active')->where(function($query) {
        $input = \Request::all();
        $currentPage = null;
        $typeCount = 0;
        $quadrantCount = 0;

        foreach( $input as $index => $object ) {

            $tempObj = json_decode($object);
            $key = key((array)$tempObj);
            $val = current((array)$tempObj);

            if ( $key == "type" ) {
                if ( $typeCount > 0 ) {
                    $query->orWhere('type', '=', $val );
                }
                else {
                    $query->where('type', '=', $val );
                    $typeCount++;
                }
            }
            if ( $key == "quadrant_main" ) {
                if ( $quadrantCount > 0 ) {
                    $query->orWhere('quadrant_main', '=', $val );
                }
                else {
                    $query->where('quadrant_main', '=', $val );
                    $quadrantCount++;
                }
            }
            // else {
            //  $query->orWhere($key,$val);
            // }
        }

        if( $currentPage ) {
            //Force Current Page to Page of Val
            Paginator::currentPageResolver(function() use ($currentPage) {
                return $currentPage;
            });
        }
    });

    $listings = $q->paginate(10);

    return $listings;
array(
    0: '{type: Apartment}',
    1: '{type: Duplex}',
    2: '{quadrant_main: NW}',
    3: '{quadrant_main: SW}',
)
id|type|quadrant_main
=====================
1|Apartment|NW
2|Apartment|SW
3|Apartment|NE
4|Apartment|SE
5|Duplex|NW
6|Duplex|SW
7|Duplex|NE
8|Duplex|SE
9|House|NW
10|House|SW
11|House|NE
12|House|SE

看看你的问题,它有点混乱,没有给出多少明确的答案。问题的可能原因可能是数据库中的错误数据,或者用户输入的内容已损坏

免责声明:请注意,我的答案很可能根本不适用于您。 在这种情况下,请提供更多的信息,我们将工作的事情 出去

有一件事我认为你忽略了,因此你得到了错误的结果。首先让我假设几件事

我认为示例用户输入应该如下所示:

public function quadrants()
{
    $input = \Request::all();
    $currentPage = null;
    $column = "price";
    $order = "desc";

    //
    //  Looks like the input is like 0 => { key: value } ...
    //  (an Array of key/value pairs)

    $q = Listing::where('status','=','Active')->where(function($query) {
        $input = \Request::all();
        $currentPage = null;
        $typeCount = 0;
        $quadrantCount = 0;

        foreach( $input as $index => $object ) {

            $tempObj = json_decode($object);
            $key = key((array)$tempObj);
            $val = current((array)$tempObj);

            if ( $key == "type" ) {
                if ( $typeCount > 0 ) {
                    $query->orWhere('type', '=', $val );
                }
                else {
                    $query->where('type', '=', $val );
                    $typeCount++;
                }
            }
            if ( $key == "quadrant_main" ) {
                if ( $quadrantCount > 0 ) {
                    $query->orWhere('quadrant_main', '=', $val );
                }
                else {
                    $query->where('quadrant_main', '=', $val );
                    $quadrantCount++;
                }
            }
            // else {
            //  $query->orWhere($key,$val);
            // }
        }

        if( $currentPage ) {
            //Force Current Page to Page of Val
            Paginator::currentPageResolver(function() use ($currentPage) {
                return $currentPage;
            });
        }
    });

    $listings = $q->paginate(10);

    return $listings;
array(
    0: '{type: Apartment}',
    1: '{type: Duplex}',
    2: '{quadrant_main: NW}',
    3: '{quadrant_main: SW}',
)
id|type|quadrant_main
=====================
1|Apartment|NW
2|Apartment|SW
3|Apartment|NE
4|Apartment|SE
5|Duplex|NW
6|Duplex|SW
7|Duplex|NE
8|Duplex|SE
9|House|NW
10|House|SW
11|House|NE
12|House|SE
用户的意思是给我任何属于西北或西南地区的公寓或复式公寓

因此,循环结束后,最后的SQL语句应该如下所示:

public function quadrants()
{
    $input = \Request::all();
    $currentPage = null;
    $column = "price";
    $order = "desc";

    //
    //  Looks like the input is like 0 => { key: value } ...
    //  (an Array of key/value pairs)

    $q = Listing::where('status','=','Active')->where(function($query) {
        $input = \Request::all();
        $currentPage = null;
        $typeCount = 0;
        $quadrantCount = 0;

        foreach( $input as $index => $object ) {

            $tempObj = json_decode($object);
            $key = key((array)$tempObj);
            $val = current((array)$tempObj);

            if ( $key == "type" ) {
                if ( $typeCount > 0 ) {
                    $query->orWhere('type', '=', $val );
                }
                else {
                    $query->where('type', '=', $val );
                    $typeCount++;
                }
            }
            if ( $key == "quadrant_main" ) {
                if ( $quadrantCount > 0 ) {
                    $query->orWhere('quadrant_main', '=', $val );
                }
                else {
                    $query->where('quadrant_main', '=', $val );
                    $quadrantCount++;
                }
            }
            // else {
            //  $query->orWhere($key,$val);
            // }
        }

        if( $currentPage ) {
            //Force Current Page to Page of Val
            Paginator::currentPageResolver(function() use ($currentPage) {
                return $currentPage;
            });
        }
    });

    $listings = $q->paginate(10);

    return $listings;
array(
    0: '{type: Apartment}',
    1: '{type: Duplex}',
    2: '{quadrant_main: NW}',
    3: '{quadrant_main: SW}',
)
id|type|quadrant_main
=====================
1|Apartment|NW
2|Apartment|SW
3|Apartment|NE
4|Apartment|SE
5|Duplex|NW
6|Duplex|SW
7|Duplex|NE
8|Duplex|SE
9|House|NW
10|House|SW
11|House|NE
12|House|SE
哦,当我们讨论SQL主题时,您还可以记录实际的 在laravel中生成SQL查询,以便您可以实际查看 最终生成SQL。如果你能把它贴在这里,它会有帮助 很多

此查询将实际生成以下内容:

Select any listing which is active and:
1. Type is an apartment, or,
2. Type is a duplex, or,
3. Quadrant is SW, and,
4. Quadrant is NW
假设您有这样一个数据库:

public function quadrants()
{
    $input = \Request::all();
    $currentPage = null;
    $column = "price";
    $order = "desc";

    //
    //  Looks like the input is like 0 => { key: value } ...
    //  (an Array of key/value pairs)

    $q = Listing::where('status','=','Active')->where(function($query) {
        $input = \Request::all();
        $currentPage = null;
        $typeCount = 0;
        $quadrantCount = 0;

        foreach( $input as $index => $object ) {

            $tempObj = json_decode($object);
            $key = key((array)$tempObj);
            $val = current((array)$tempObj);

            if ( $key == "type" ) {
                if ( $typeCount > 0 ) {
                    $query->orWhere('type', '=', $val );
                }
                else {
                    $query->where('type', '=', $val );
                    $typeCount++;
                }
            }
            if ( $key == "quadrant_main" ) {
                if ( $quadrantCount > 0 ) {
                    $query->orWhere('quadrant_main', '=', $val );
                }
                else {
                    $query->where('quadrant_main', '=', $val );
                    $quadrantCount++;
                }
            }
            // else {
            //  $query->orWhere($key,$val);
            // }
        }

        if( $currentPage ) {
            //Force Current Page to Page of Val
            Paginator::currentPageResolver(function() use ($currentPage) {
                return $currentPage;
            });
        }
    });

    $listings = $q->paginate(10);

    return $listings;
array(
    0: '{type: Apartment}',
    1: '{type: Duplex}',
    2: '{quadrant_main: NW}',
    3: '{quadrant_main: SW}',
)
id|type|quadrant_main
=====================
1|Apartment|NW
2|Apartment|SW
3|Apartment|NE
4|Apartment|SE
5|Duplex|NW
6|Duplex|SW
7|Duplex|NE
8|Duplex|SE
9|House|NW
10|House|SW
11|House|NE
12|House|SE
在结果集中,您将只收到
1和5。这个结果集显然是错误的,而且它取决于
NW
,因为这是
条件

正确的SQL查询应该是:

select * from listings where status = 'Active' and (type = 'Apartment' or type = 'Duplex') and (quadrant_main = 'NW' or quadrant_main = 'SW');
因此,构造L5应用程序,使其生成这种SQL查询。不要试图把所有东西都塞进一个循环,而是有两个循环。一个循环只能处理
类型
,另一个循环只能处理
象限_main
。这样,您将在正确的位置获得必要的
条件


作为旁注:
  • 永远不要直接使用用户输入。总是先消毒
  • 将所有逻辑都放在控制器中不是最佳做法。使用存储库模式
  • 多个where子句通常通过
    标准应用。在上面链接的存储库模式中检查这一点
  • 您的代码逻辑非常复杂,完全没有必要。只需发送复选框的状态,而不是发送JSON对象。不要试图通过循环来概括函数。而是逐个处理所有复选框,即选择“公寓”,如果是,则将其添加到您的子句中,如果不是,则不添加