Symfony + Doctrine 读取 PostGIS Point 类型返回空值问题求助
问题根因
- 读取PostGIS的Point字段时,未将数据库存储的二进制EWKB格式转为WKT文本,
convertToPHPValue方法拿到的是不可解析的二进制数据,最终解析出来的经纬度为null。 - 写入时生成的参数不符合
PointFromText要求的WKT格式,存在数据写入错误隐患。
修复步骤
1. 替换PointType.php完整代码
<?php namespace App\DBAL\Types\PSQL; use App\DBAL\Types\Geolocation\Point; use Doctrine\DBAL\Platforms\AbstractPlatform; use Doctrine\DBAL\Types\Type; class PointType extends Type { const POINT = 'point'; public function getSQLDeclaration(array $column, AbstractPlatform $platform): string { return "POINT"; } public function getName(): string { return self::POINT; } /** * 读取时将数据库Point值转为WKT文本 */ public function convertToPHPValueSQL($sqlExpr, $platform): string { return sprintf('ST_AsText(%s)', $sqlExpr); } public function convertToPHPValue($value, AbstractPlatform $platform): ?Point { if ($value === null) { return null; } // 解析WKT格式的POINT字符串 if (preg_match('/^POINT\((\-?\d+\.?\d*) (\-?\d+\.?\d*)\)$/', $value, $matches)) { $longitude = (float)$matches[1]; $latitude = (float)$matches[2]; return new Point($latitude, $longitude); } throw new \InvalidArgumentException(sprintf('无效的Point WKT格式: %s', $value)); } /** * 写入时将PHP对象转为符合要求的WKT格式 */ public function convertToDatabaseValue($value, AbstractPlatform $platform): ?string { if ($value === null) { return null; } return sprintf('POINT(%f %f)', $value->getLongitude(), $value->getLatitude()); } public function convertToDatabaseValueSQL($sqlExpr, AbstractPlatform $platform): string { return sprintf('PointFromText(%s)', $sqlExpr); } /** * 避免Doctrine每次diff时误判字段类型需要更新 */ public function requiresSQLCommentHint(AbstractPlatform $platform): bool { return true; } }
2. 后续验证操作
- 确认数据库已开启PostGIS扩展,执行SQL:
CREATE EXTENSION IF NOT EXISTS postgis; - 清除Symfony项目缓存:
php bin/console cache:clear - 若此前已有写入的错误格式数据,清空后重新写入测试即可。
内容的提问来源于stack exchange,提问作者Alexander Álvarez
相关产品推荐
相关产品推荐

