Laravel 查询生成器中的转义字符

Laravel escape character in query builder

我正在编码查询:

$result = \DB::table('order_items as oi')
        ->selectRaw(
            'order_item_type as item_type,
            order_item_id as item_id,
            if(order_item_type = "App\\Models\\Book", oi.price, invoices.price) as price
              )

请注意 if 语句,我必须使用 两个 转义字符或查询不匹配 App\Models\Book。当我通过 laravel 调试器检查输出查询时:

select order_item_type as item_type,
order_item_id as item_id,
if(order_item_type = "App\Models\Book", oi.price, invoices.price) as price,...

这里发生了什么? laravel 查询生成器会删除一个斜杠,然后 mysql 引擎会在 运行 时间内删除第二个斜杠吗?

编辑:
但是在同一个查询的其他地方我有一个 where 子句,我使用了 one 转义字符并且它工作正常:

 ->leftjoin('books', function ($q) {
            $q->on('q3.order_item_id', '=', 'books.id')
                ->where('q3.order_item_type', '=', 'App\Models\Book');
        })

和 laravel 调试器的输出查询部分:

left join `books` on `q3`.`order_item_id` = `books`.`id` and 
`q3`.`order_item_type` = 'App\Models\Book'

谁能解释为什么在 if 中我必须使用 两个 转义字符但在 join 中只能使用 一个需要转义字符吗?
事实上,如果我在 where 查询生成器方法 中不使用任何转义字符并将代码编写为:

也不会有任何问题
  ->leftjoin('books', function ($q) {
            $q->on('q3.order_item_id', '=', 'books.id')
                ->where('q3.order_item_type', '=', 'App\Models\Book');
        })

PHP1 and MySQL2 escapes slashes. MySQL on other hand requires them escaped unless NO_BACKSLASH_ESCAPES3 SQL 模式均已启用 - 默认情况下处于禁用状态。在 MySQL 中,转义序列要么被解释,要么被忽略 - \n 将被翻译成一个新行, \m 被忽略并被翻译成 m.

所以首先 PHP 会将 \\ 转换为 \ - 两个转义为一个。然后 MySQL 也会将 \ 转义为 \,理解你想要一个字面斜杠。 :)

关于您的编辑,selectRaw() 将原始查询发送到 MySQL,因此您必须自己转义数据。所有其他非原始方法都在 Laravel 查询生成器内部执行此操作,因此您不必为这些事情操心。

PHP 与 MySQL 不同,不会忽略斜杠。使用单引号字符串,任何非结尾的斜杠无论如何都会被识别为文字,因此您不需要转义它们 - 如果您的字符串以斜杠结尾,那么您是必需的。对于双引号字符串,转义序列会被翻译 - 您的示例仍然可以使用它们,但有些情况可能会出错。