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

时间:2016-06-28 05:41:58

标签: mysql laravel 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子句,我使用了一个转义字符,它运行正常:

 ->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');
        })

1 个答案:

答案 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不会忽略斜杠。使用单引号字符串无论如何都会将任何非结尾的斜杠识别为文字,因此您不需要将它们转义 - 如果您的字符串以斜杠结尾,那么您就需要它。使用双引号字符串会有转换的转义序列 - 您的示例仍可以使用它们,但有些情况可能会出错。