Php 当变量为false时,Where子句不';不考虑SQL查询吗?

Php 当变量为false时,Where子句不';不考虑SQL查询吗?,php,mysql,sql,laravel,Php,Mysql,Sql,Laravel,我有些不太明白的事情,我有解决办法,但我不知道为什么,这让我有点疯狂 控制器 DB::connection()->enableQueryLog(); $transfer = Transfer::where('ticket_id', $last_ticket)->where('event_id', 36)->where('buyer', $user_email)->first(); $queries = DB::getQueryLog(); dd($queries);

我有些不太明白的事情,我有解决办法,但我不知道为什么,这让我有点疯狂

控制器

DB::connection()->enableQueryLog();

$transfer = Transfer::where('ticket_id', $last_ticket)->where('event_id', 36)->where('buyer', $user_email)->first();

$queries = DB::getQueryLog();

dd($queries);
结果

array:1 [
  0 => array:3 [
    "query" => "select * from `transfers` where `ticket_id` = ? and `event_id` = ? and `buyer` = ? limit 1"
    "bindings" => array:3 [
      0 => false
      1 => 36
      2 => "[email protected]"
    ]
    "time" => 0.36
  ]
]
情况: 数据库中的
$last_ticket
是唯一的,从不
null
、空或
false

在我的示例中,
$last\u ticket
false
,但是在DB中没有任何
false
,为什么我仍然得到结果

这是不是因为当一个条件为假时,它没有把它纳入方程

因此,问题是: 如何接收正确的结果?这意味着:如果$last\u ticket为false,则没有结果,如果它有一些数据,则返回受$last\u ticket限制的行结果


一个选项可以是在($last\u ticket==false){$last\u ticket='randomInexistentString\u ag4dh&2g32y4t'}所以它不是null或零,但我不认为这是更好的方法

MySQL中的零总是匹配任何不以数字开头的字符串-这是因为它希望比较的两边都是相同的类型,所以它将字符串转换为数字,任何不以数字开头的字符串都会自动计算为
0

现在,你不是在给它输入一个
0
——而是在给它输入一个
false
,在MySQL中,这不是一个真正的布尔值,而是一个
0

在不知道您的数据库是什么样子的情况下,我认为这是最可能的解释

有很多方法可以解决这个问题,例如,您可以使用
->when()
链接到雄辩的:

Transfer::where('event_id', 36)
        ->where('buyer', $user_email)
        ->when($last_ticket, function ($query) use ($last_ticket) {
            $query->where('ticket_id', $last_ticket);
        })
        ->first();

(从内存中提取,语法可能有点错误。感谢Rick James在评论中的更正。)

重新设计UI。如果查询中应该遗漏某些内容,则不要将其包含在查询中

也就是说,动态构建
WHERE
子句,以便在提供“false”时,它变为

WHERE `event_id` = ? and `buyer` = ?
我不知道Laravel,但在PHP中,我会构建一个数组,将
放在一起,然后构建
WHERE

$ands = array();
if (...)  $ands[] = "ticket_id = ...";
if (...)  $ands[] = "event_id = ...";
if (...)  $ands[] = "buyer = ...";

if (empty($ands))
    $where = '';
else
    $where = 'WHERE ' . implode(' AND ', $ands);

$sql = "SELECT ... $where ...";

请注意,它可以轻松地处理任何或所有被忽略的项。

您能否提供“传输”表架构,并提供“票证id”列数据类型和约束?返回结果集中票证id字段的值是多少?(我猜是0)。@Shadow为false可能与0相同。我感兴趣的是返回的值,而不是您提供的参数。这会告诉我们发生了什么。啊,对不起,根据帖子中的调试结果,您所指的返回值也是假的。。或者你在问另一个值?哦,谢谢,我不知道0,如果我给它输入null?我想这是一样的,但我真的不确定。额外的分数;)我在同一主题中添加了一个问题,如果last_ticket为零或null,如何返回none?你的额外问题有点奇怪-这是一个纯if条件,那么你为什么不直接执行
if($last_ticket){do things}或者{do things}
?@JoelHinz-不。零匹配任何不以数字开头的字符串。在将字符串转换为数字时,如果前导数字在那里,它将使用前导数字。在laravels查询生成器中,您可以传递一个字符串数组:
->where(['ticket\u id'=>7,'event\u id'=>5])
。见第一条评论。您甚至应该能够传递一个空数组,因此不需要检查
if(empty($ands))