You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 07:47:12