Symfony 4中Sonata SEO自定义SQL LIKE查询的YAML转义问题
解决Sonata SEO YAML配置中SQL转义的问题
我之前在配置Sonata SEO站点地图的时候也踩过类似的转义坑,给你几个实用的解决思路:
1. 用YAML块标量(|)写SQL,彻底避免转义麻烦
这是最省心的方式,YAML的|块标量会原样保留你写的SQL内容,不需要处理任何转义字符(包括单引号、反斜杠、冒号)。比如你的排除页面的SQL可以这么写:
# config/packages/sonata_seo.yaml sonata_seo: sitemap: doctrine_orm: - { connection: default, query: | SELECT id, slug, updated_at FROM page WHERE slug NOT IN ('exclude-page-1', 'exclude-page-2') AND is_published = 1 ORDER BY updated_at DESC }
这种写法不仅可读性强,而且完全不会出现转义错误或者参数误解析的问题,直接和你在MySQL客户端里写的SQL一致就行。
2. 单行SQL的转义规则
如果一定要写单行SQL,根据你用的引号类型,遵循不同的转义规则:
单引号包裹的情况
- 内部的单引号需要替换成两个连续的单引号(YAML的单引号转义规则)
- 反斜杠(比如MySQL里用于转义下划线、百分号的
\)不需要额外转义,直接写即可
例子:
query: 'SELECT id, slug, updated_at FROM page WHERE slug NOT IN(''exclude-page-1'', ''exclude-page-2'') AND is_published = 1'
双引号包裹的情况
- 内部的反斜杠需要转义成两个反斜杠(因为YAML会解析双引号里的转义字符)
- 单引号可以直接使用,不需要转义
例子:
query: "SELECT id, slug, updated_at FROM page WHERE slug NOT IN('exclude-page-1', 'exclude-page-2') AND is_published = 1" # 如果SQL里有MySQL转义的反斜杠,比如匹配下划线: query: "SELECT id, slug FROM page WHERE slug LIKE '%\\_%'"
3. 排查参数未定义的根源
如果出现“参数未定义”错误,大概率是你的SQL里有类似:slug、:id的写法——Sonata SEO会把这些带冒号的字符串当作要注入的参数,但你没有在配置里提供对应的参数值。
如果这些冒号不是故意用作参数的(比如只是SQL里的普通字符),用块标量写法就能避免这个问题;如果确实需要传递参数,要在配置里加上parameters字段:
sonata_seo: sitemap: doctrine_orm: - { connection: default, query: "SELECT id, slug FROM page WHERE category_id = :category_id", parameters: { category_id: 5 } }
按照上面的方法调整后,再运行php bin/console sonata:seo:sitemap应该就能正常生成站点地图了。
内容的提问来源于stack exchange,提问作者Bananaapple
相关产品推荐
相关产品推荐

