【问题标题】:Laravel escape character in query builder查询生成器中的 Laravel 转义字符
【发布时间】:2016-10-30 06:58:54
【问题描述】:

我正在编写查询代码:

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

【问题讨论】:

  • 您是否尝试过使用 4 个或 2 个反斜杠? 3 个反斜杠对我来说看起来不正确。
  • @IvanYarych 这种行为一直不一样,看看编辑。

标签: mysql laravel query-builder


【解决方案1】:

PHP1 和 MySQL2 都对斜杠进行转义。另一方面,MySQL 要求它们转义,除非启用了NO_BACKSLASH_ESCAPES3 SQL 模式 - 默认情况下禁用。在 MySQL 中,转义序列要么被解释,要么被忽略 - \n 将被转换为新行,\m 被忽略并转换为 m

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

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

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

【讨论】:

  • 谢谢,我添加了一个编辑。请您再检查一下问题吗
  • 我更新了我的答案,也回答了你的新问题。 ;)
  • 我没有在内部 where 查询构建器方法中使用任何转义字符,它工作正常。这是否意味着where 方法将假定所有用户(开发人员)书写的字符都是文字?
  • PHP 与 MySQL 不同,不会忽略斜杠。使用单引号字符串,任何非结尾斜杠无论如何都将被识别为文字,因此您不需要转义它们 - 如果您的字符串以斜杠结尾,那么您是必需的。对于双引号字符串,会有转义序列被翻译 - 您的示例仍然可以使用它们,但有些情况可能会出错。 ;)
猜你喜欢
  • 2015-12-13
  • 1970-01-01
  • 2019-03-09
  • 2021-08-07
  • 1970-01-01
  • 1970-01-01
  • 2020-10-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多