Doctrine Migrations中反斜杠转义问题:如何正确更新MySQL表中的实体命名空间
解决Doctrine Migration中命名空间替换的转义问题
我懂你这种转义绕晕的感觉——在MySQL控制台跑的好好的语句,一放进Doctrine迁移就没效果,核心是PHP字符串解析、Doctrine SQL处理、MySQL自身转义这三层叠加导致的转义规则变化。下面给你两种靠谱的解决方案:
方案1:手动处理多层转义
在PHP单引号字符串里,每个要传递给MySQL的反斜杠都得双重转义(PHP先解析一次,再交给MySQL处理)。对应你需求的正确写法是:
$this->addSql('UPDATE Entity SET entity_name = REPLACE(entity_name, \'Old\\\\App\', \'New\\\\App\') WHERE entity_name LIKE \'Old\\\\\\\\App%\';');
为啥要这么写?
- 对于
REPLACE里的Old\App:MySQL需要用'Old\\App'来表示字面量的Old\App(SQL字符串中\\等价于一个\),所以在PHP单引号里要写成\'Old\\\\App\'——PHP会把\\\\解析成\\,最终传给MySQL的就是正确的Old\\App。 - 对于
LIKE条件里的Old\App%:MySQL的LIKE子句中,\\才代表字面量\,所以SQL里得写成'Old\\\\App%',因此PHP单引号里要写成\'Old\\\\\\\\App%\'——PHP解析后变成Old\\\\App%,MySQL收到后会把\\\\转成\\,这样就能正确匹配以Old\App开头的字符串了。
方案2:使用参数绑定(强烈推荐)
手动转义太容易出错,Doctrine的参数绑定会自动帮你处理所有转义逻辑,代码更清晰省心:
$this->addSql( 'UPDATE Entity SET entity_name = REPLACE(entity_name, :old_ns, :new_ns) WHERE entity_name LIKE :like_pattern', [ 'old_ns' => 'Old\\App', 'new_ns' => 'New\\App', 'like_pattern' => 'Old\\App%' ] );
这种方式直接传入原始的命名空间字符串就行,完全不用纠结转义层数,Doctrine会负责把它转换成MySQL能识别的格式,对你用的Doctrine 2.7完全兼容。
内容的提问来源于stack exchange,提问作者cfag
相关产品推荐
相关产品推荐

