最安全的mysql连接url写法是database_url=mysql://user:pass@127.0.0.1:3306/dbname?serverversion=8.0,必须用127.0.0.1而非localhost以避免unix socket路径错误,端口需显式写出,特殊字符须url编码,serverversion参数不可省略。

MySQL 连接 URL 怎么写才不报 Connection refused
直接写 DATABASE_URL=mysql://user:pass@127.0.0.1:3306/dbname 是最安全的起点,别用 localhost —— MySQL 会尝试走 Unix socket,而 Symfony 默认不配 socket 路径,结果就是 SQLSTATE[HY000] [2002] No such file or directory。
-
127.0.0.1强制走 TCP,本地开发稳 - 端口必须显式写(哪怕默认 3306),Docker 或远程 DB 时尤其关键
- 密码含
@、/、:等字符,得 URL 编码,比如pa@s/s→pa%40s%2Fs - MySQL 8.0+ 必须加
?serverVersion=8.0,否则 Doctrine 不知道用哪种语法生成 DDL
PostgreSQL 和 SQLite 的 URL 格式差异在哪
协议头和参数完全不同,混用会直接启动失败或连错库。
- PostgreSQL:
DATABASE_URL=postgresql://user:pass@127.0.0.1:5432/dbname?serverVersion=13&charset=utf8—— 注意是postgresql(不是pgsql),serverVersion要匹配 pg 版本 - SQLite:
DATABASE_URL=sqlite:///%kernel.project_dir%/var/data.db—— 路径用%kernel.project_dir%变量,不能写绝对路径(否则部署时出错) - 所有 URL 中的
?后参数必须小写,ServerVersion或CHARSET都会失效
为什么 doctrine:database:create 报 Access denied
这个命令不是用 root 连,而是用 DATABASE_URL 里配的用户去执行 CREATE DATABASE,所以失败基本等于权限不够。
- 确认该用户有
CREATE权限:GRANT CREATE ON *.* TO 'your_user'@'%'; - 如果只是想建库,又不想授过大权限,改用原生命令:
mysql -u root -p -e "CREATE DATABASE IF NOT EXISTS dbname;" - Docker 环境下常见陷阱:MySQL 8.0 镜像默认禁用
mysql_native_password插件,老项目用户认证方式不兼容,需手动执行:ALTER USER 'user'@'%' IDENTIFIED WITH mysql_native_password BY 'pass';
怎么把 DATABASE_URL 解析成 PHP 数组
别自己 parse_url() 拆——URL 参数语义复杂(比如 charset、serverVersion、url 嵌套),Doctrine 已经帮你做好了。
- 注入
Doctrine\DBAL\Connection服务,调getParams(): public function __construct(private Connection $connection) {} // ... $connection->getParams(); // 返回 ['dbname' => 'xxx', 'host' => '127.0.0.1', ...]- 这个数组是 Doctrine 实际连接时用的完整配置,含自动解析后的
serverVersion、driverOptions等,比手动拆可靠得多
真正容易被忽略的是 serverVersion —— 它不是可选参数,而是影响 SQL 生成逻辑的开关。少写或写错版本号,doctrine:schema:update 可能生成非法语法,或者字段类型映射错乱。











