Azure网站MySQL In-App连接PDO报错:套接字访问权限被拒绝
我之前帮其他开发者排查过类似的Azure MySQL In-App连接问题,这个SQLSTATE[HY000] [2002]权限错误其实挺常见的,咱们一步步来定位解决:
先检查连接字符串的语法细节
看你代码里构建PDO DSN的这一行:
$pdocon = "mysql:host".$conStr["Data Source"].";dbname=".$conStr["Database"];
这里host后面少了个等号,正确的DSN格式应该是mysql:host=xxx;dbname=xxx。虽然你说打印$pdocon能看到有效值,但还是要确认这个细节——有时候笔误会触发意想不到的连接问题,哪怕看起来输出正常。
Azure MySQL In-App的专属配置注意事项
这个错误在Azure环境里,大多和本地Socket的配置或者权限有关,不是单纯的认证问题:
优先使用本地Socket而非TCP连接:Azure MySQL In-App默认提供的是本地Unix Socket路径,不是常规的TCP端口。如果你的
$conStr["Data Source"]是127.0.0.1:xxxx这类TCP地址,很可能会遇到权限限制。正确的Socket路径可以从Azure环境变量MYSQLCONNSTR_localdb里获取,或者直接在Azure门户的应用服务配置面板里查看。验证PHP扩展的Socket配置:Azure App Service的PHP环境中,mysqlnd扩展有时候会和MySQL In-App的Socket路径不匹配。你可以临时在代码里加一行
phpinfo();,然后查找mysqli.default_socket或pdo_mysql.default_socket的值,确认它和Azure提供的Socket路径完全一致。检查App Service的层级权限:如果你的应用跑在免费/共享层,可能会有本地Socket的访问限制。条件允许的话,可以临时升级到标准层测试一下,看是否能解决问题——如果升级后正常,那就是层级权限的限制导致的。
修正后的参考代码
推荐直接从Azure的环境变量里获取连接信息,这样能避免手动配置的错误,代码示例如下:
// 从Azure环境变量读取MySQL In-App的连接字符串 $conStr = getenv('MYSQLCONNSTR_localdb'); // 解析环境变量里的各项参数(格式示例: Database=myDB; Data Source=/var/run/mysql/mysql.sock; User ID=myUser; Password=myPass) preg_match('/Database=(.*?);/', $conStr, $dbMatch); preg_match('/Data Source=(.*?);/', $conStr, $socketMatch); preg_match('/User ID=(.*?);/', $conStr, $userMatch); preg_match('/Password=(.*?)$/', $conStr, $passMatch); $dbName = $dbMatch[1]; $socketPath = $socketMatch[1]; $username = $userMatch[1]; $password = $passMatch[1]; // 构建支持Unix Socket的PDO DSN $pdocon = "mysql:dbname=$dbName;unix_socket=$socketPath"; try { $conn = new PDO($pdocon, $username, $password); $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); echo "Connected successfully"; } catch(PDOException $e) { echo "Connection failed: " . $e->getMessage(); }
额外的排查小技巧
- 先去Azure门户确认MySQL In-App服务是运行状态,免费层应用长时间不访问会自动暂停,这也会导致连接失败。
- 用Azure的在线控制台直接连接MySQL测试:
mysql -u <你的用户名> -p<你的密码> -S <Socket路径> <数据库名>
如果这个命令能成功连接,说明数据库本身没问题,问题肯定出在PHP代码的配置上。
内容的提问来源于stack exchange,提问作者Nirav Madariya

