Я пытаюсь перейти на php из элементов массива javascript для обработки, например:
for(var i=0;i<points.length;++i){
var xmlhttp = new XMLHttpRequest();
var distancesObject = null;
lat = points[i][LAT];
lng = points[i][LNG];
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200){
if (xmlhttp.response!=null){
distancesObject = JSON.parse(xmlhttp.response);
}
}
};
xmlhttp.open("GET", "Distances.php?lat = " + lat + "&lng = " + lng, true);
xmlhttp.send();
}
Он должен перебирать все элементы массива и возвращать объект, если он существует в базе данных, но возвращает ноль, хотя я точно знаю, что первые значения хранятся в базе данных. Это работает, только если я передаю такие значения, как points [0], points [1]. Код PHP:
<?php
$latitude = $_GET['lat']; //"47.158857";
$longitude = $_GET['lng']; // "27.601249"
$query = "SELECT pharmacyDistance, schoolDistance, restaurantDistance, busStationDistance FROM distances WHERE lat='$latitude' and lng='$longitude'";
$result = mysqli_query($dbc,$query);
$count = mysqli_num_rows($result);
$row = mysqli_fetch_array($result, MYSQLI_ASSOC);
$json_array = json_encode($row);
if ($json_array!=null){
echo $json_array;
}
mysqli_close($dbc);
?>
Что-то я делаю не так?
points [i] [LAT] обозначает широту точки, например, в моем случае 47.158857, а points [i] [LNG] обозначает долготу точки - 27.601249
Я сбит с толку, если вы передаете широту и долготу, предположительно полученные с такого устройства, как телефон, как ваша база данных может содержать все возможные расстояния между любой точкой в мире и любой / каждой аптекой в мире? Это, безусловно, должен быть расчет, и вам нужно искать Аптеки в чем-то вроде GoogleMaps.
Ваш PHP-код очень уязвим для SQL-инъекция, вместо этого используйте подготовленные операторы (везде, а не только в этом коде)



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Я считаю, что ваша проблема заключается в этих двух строках:
lat = points[i][LAT];
lng = points[i][LNG];
Во-первых, вы определили их в глобальном масштабе. Они должны иметь префикс с ключевым словом var, если вы еще не определили эти переменные выше.
Во-вторых, [LAT] пытается использовать (я предполагаю, унифицированную) переменную с именем LAT. Правильный синтаксис для использования имени строкового ключа - points[i]['LAT'] или points[i].LAT.
Итак, обновив код до
var xmlhttp = new XMLHttpRequest();
var distancesObject = null;
var lat = points[i].LAT;
var lng = points[i].LNG;
Надеюсь, это решит вашу проблему.
вы перезаписываете объект, который обрабатывает соединение в цикле for, вероятно, быстрее, чем может вернуть ответ.
пытаться:
var xmlhttp = [];
for(var i=0;i<points.length;++i){
xmlhttp[i] = new XMLHttpRequest();
var distancesObject = null;
lat = points[i][LAT];
lng = points[i][LNG];
xmlhttp[i].onreadystatechange = function() {
if (xmlhttp[i].readyState == 4 && xmlhttp[i].status == 200){
if (xmlhttp[i].response!=null){
distancesObject = JSON.parse(xmlhttp.response);
}
}
};
xmlhttp[i].open("GET", "Distances.php?lat = " + lat + "&lng = " + lng, true);
xmlhttp[i].send();
}
Пожалуйста, не делай этого. Действительно. Добавьте все элементы массива в свой URL-адрес и выполните только запрос один, где вы запросите все, что вам нужно, и вернете список. Обработайте список в ответе. Что-то вроде (с макушки):
var urlParams = [];
points.forEach(function(point) {
urlParams.push("lat[] = " + point.LAT + "&lng[] = " + point.LNG);
});
var xmlhttp = new XMLHttpRequest();
var distancesObject = null;
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200){
if (xmlhttp.response!=null){
distancesObject = JSON.parse(xmlhttp.response);
}
}
};
xmlhttp.open("GET", "Distances.php?" + urlParams.join("&"), true);
xmlhttp.send();
В PHP:
$whereClause = "";
for ($i = 0; $i < count($_GET['lat']); $i++) {
$whereClause.= "(lat='" . $_GET['lat'][$i] . "' and lng='" . $_GET['lng'][$i]. "') and ";
}
$query = "SELECT pharmacyDistance, schoolDistance, restaurantDistance, busStationDistance FROM distances WHERE " . substr($whereClause, 0, (strlen($whereClause) - 4)); // Substr to remove last ' and' from where clause
$result = mysqli_query($dbc,$query);
$count = mysqli_num_rows($result);
$distances = array();
while($row = mysqli_fetch_array($result, MYSQLI_ASSOC)) {
$distances[] = $row;
}
$json_array = json_encode($distances);
if ($json_array!=null){
echo $json_array;
}
mysqli_close($dbc);
Тогда у вас будет список ваших distances как json и только одно попадание в вашу базу данных. Кроме того, ваше приложение не может вызывать ajax в цикле for, оно будет открывать различные параллельные асинхронные запросы, беспорядок.
Примерно так будет выглядеть запрос:
SELECT ... FROM ... WHERE (lat='1' and lng='1') and (lat='2' and lng='2') and ...
Я не тестировал эти коды и какое-то время не играю с PHP, поэтому надеюсь, что с кодом все в порядке, простите за опечатки или синтаксические ошибки.
Как видно из исходного сообщения, этот фрагмент кода PHP очень уязвим для SQL-инъекция.
@EliasSoares уверен, это еще одна вещь, которую я оставил в стороне. Запросы ajax были настолько плохими, что я не осознавал эту проблему с SQL.
Итак, я не знаю, задаю ли я глупый вопрос, но как мой запрос будет выглядеть на php? как я это вижу (я, конечно, могу ошибаться), поскольку $ whereClause находится в цикле, это будет конкатенация всех lats и lngs?
@MadalinaGrigoras посмотрите обновленный пост. Вам нужно будет вернуть lat и lng из запроса, чтобы узнать в обратном вызове запроса javascript, какая строка связана с какой широтой / долготой.
Но это будет означать, что он попытается выбрать строки, где lat = value, а также где lat = anotherValue, верно?
@MadalinaGrigoras да, вы выберете несколько строк по заданным точкам, поэтому ваш javascript получит список. Вам нужно будет обработать этот список, то есть выполнить еще один Выбрать над этим списком (например, используя filter()), чтобы использовать его в вашем js-коде.
Но я изменил некоторые строчки, и теперь это работает, большое спасибо @DontVoteMeDown
@MadalinaGrigoras отлично! На мой взгляд, это право. Ваше здоровье.
показать, что содержит
points...