我正在编写查询:
$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
子句,我使用了一个转义字符,它运行正常:
->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');
})
答案 0 :(得分:1)
PHP 1和MySQL 2都会转义斜杠。另一方面,MySQL要求它们被转义,除非NO_BACKSLASH_ESCAPES
3启用了SQL模式 - 默认情况下它被禁用。在MySQL中,转义序列被解释或忽略 - \n
将被转换为新行,\m
将被忽略并转换为m
。
因此,首先PHP将\\\
转换为\\
- 两个转换为一个。然后MySQL也会将\\
转义为\
,理解你想要一个文字斜杠。 :)
关于您的编辑,selectRaw()
向MySQL发送原始查询,因此您可以自行转义数据。所有其他非原始方法在Laravel Query Builder内部执行此操作,因此您不必为这些事情烦恼。
与MySQL不同,PHP不会忽略斜杠。使用单引号字符串无论如何都会将任何非结尾的斜杠识别为文字,因此您不需要将它们转义 - 如果您的字符串以斜杠结尾,那么您就需要它。使用双引号字符串会有转换的转义序列 - 您的示例仍可以使用它们,但有些情况可能会出错。