Вот часть некоторых вычислений расстояния, которые должны соответствовать вашему сценарию использования в отношении использования Doctrine и цитирования.
Используя Doctrine, вы также получите записи в виде массива. См. Ниже, если вам нужны объекты Extbase.
Получите версию TYPO3 Doctrine DBAL QueryBuilder:
$q = GeneralUtility::makeInstance(ConnectionPool::class)
->getQueryBuilderForTable($table = 'tx_....');
$q->select(
...
'a.lat',
'a.lng'
)
->from($table /*, 'alias if you want' */);
Я не часто использую свободный интерфейс, когда делать подобные вычисления (хотя, конечно, это можно сделать с помощью любой функции MySQL с $q->selectLiteral()
).
Параметры
Чтобы предотвратить SQL инъекцию, вы должны указать все возможные пользовательские данные с помощью $q->quote()
/ $q->quoteIdentifier()
или использовать параметры $q->createNamedParameter()
.
Пример ограничений
Это только часть ограничений. Он содержит пример того, как их комбинировать на основе условий, как это обычно бывает в функции поиска.
if ((float)$searchObject->radiusKm > .5) {
$_radiusOrs = [
'IF (
' . $q->quoteIdentifier('lat') . ' = 0,
100000,
12742 * ASIN(
SQRT(
POWER(
SIN(
( ' . $q->quote((float)$searchObject->lat) . '
- ABS( ' . $q->quoteIdentifier('lat') . ' )
) * 0.0087266
),
2
)
+
COS( ' . $q->quote((float)$searchObject->lng) . ' * 0.01745329 ) * COS(
ABS( ' . $q->quoteIdentifier('lat') . ' ) * 0.01745329
) * POWER(
SIN(
( ' . $q->quote((float)$searchObject->lng) . '
- ' . $q->quoteIdentifier('lng') . '
) * 0.0087266
),
2
)
)
)
) < ' . $q->quote((float)$searchObject->radiusKm),
];
$q->andWhere(
$q->expr()->orX(...$_radiusOrs)
);
}
...
$aRes = $q->execute()->fetchAll();
(Если вы хотите отладить: вы получаете SQL с $q->getSQL()
, $q->getParameters()
)
Отображение на объекты Extbase
$dataMapper = $this->objectManager->get(\TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper::class);
$objects = $dataMapper->map(YourExtbaseModel::class, $aRes);
Я бы предложил: Используйте объекты Extbase, только если у вас мало объектов или если у вас достаточно памяти и вам все равно о производительности. В большинстве случаев вам просто следует избегать использования простых массивов.
Конструктор запросов Extbase допускал небольшую оптимизацию при выводе в шаблон Fluid: пропуск \TYPO3\CMS\Extbase\Persistence\Generic\QueryResult
позволял использовать на нем f:paginate
ViewHelper, который не нужно создавать экземпляры всех объектов, а только те, которые показаны на текущей странице. Такой возможности нет (пока?) При использовании Doctrine QueryBuilder. Таким образом, использование моделей Extbase должно быть в крайнем случае сейчас, а не по умолчанию. Казалось бы, «лучшая практика» - это уже не так, ИМХО.