Jua*_*doz 16 php sql combinations
我有两个文本输入.像这样:
所以,我有一些动态的ajax搜索.我传递输入数据并做两个不同的mysql选择.像这样的东西:
表finalmap - SELECT 1
id -------- latitud-----longitud---
1 | 6.2523915 | -75.5737028 |
2 | 6.2640349 | -75.5990783 |
3 | 6.2642411 | -75.5999791 |
4 | 6.2638461 | -75.5982590 |
-------------------------------------
Run Code Online (Sandbox Code Playgroud)
表finalmap - SELECT 2
id -------- latitud-----longitud---
6 | 6.262669 | -75.596799 |
7 | 6.258019 | -75.598001 |
8 | 6.253668 | -75.599374 |
9 | 6.250724 | -75.602335 |
-------------------------------------
Run Code Online (Sandbox Code Playgroud)
因此,我想将每个"纬度和纵向"与SELECT2的所有"纬度"和"纵向"字段进行比较:
我有这个Php,我必须做一些改进,但可以说它有效:
<?php
$buscar = $_POST['b'];
$buscarcarrera = $_POST['c'];
$whatIWant = substr($buscar, strpos($buscar, "Calle") + 5);
$whatIWant2 = substr($buscarcarrera, strpos($buscarcarrera, "Carrera") + 5);
$vacio = "Calle50A";
$vacioc = "Carrera50A";
if (preg_match('/[A-Za-z]/', $whatIWant))
{
buscar($buscar, "", $buscarcarrera, "");
}
else
{
buscar($buscar, $vacio, $buscarcarrera, $vacioc);
}
function buscar($b, $exclusion, $buscarcarrera, $exclusion2)
{
$con = mysql_connect('localhost', 'root', '');
mysql_select_db('map', $con);
$sql = mysql_query("SELECT * FROM finalmap WHERE calle LIKE '%" . $b . "%' AND calle not in ('$exclusion')", $con);
$contar = mysql_num_rows($sql);
if ($contar == 0)
{
echo "No se han encontrado resultados para '<b>" . $b . "</b>'.";
}
else
{
while ($row = mysql_fetch_array($sql))
{
$nombre = $row['calle'];
$id = $row['id'];
$lat = $row['latitud'];
$lon = $row['longitud'];
}
}
$sql2 = mysql_query("SELECT * FROM finalmap WHERE calle LIKE '%" . $buscarcarrera . "%' AND calle not in ('$exclusion2')", $con);
$contar2 = mysql_num_rows($sql2);
if ($contar2 == 0)
{
echo "No se han encontrado resultados para '<b>" . $b . "</b>'.";
}
else
{
while ($row2 = mysql_fetch_array($sql2))
{
$nombre2 = $row2['calle'];
$id2 = $row2['id'];
$lat2 = $row2['latitud'];
$lon2 = $row2['longitud'];
}
}
}
function distance($lat1, $lon1, $lat2, $lon2, $unit)
{
$theta = $lon1 - $lon2;
$dist = sin(deg2rad($lat1)) * sin(deg2rad($lat2)) + cos(deg2rad($lat1)) * cos(deg2rad($lat2)) * cos(deg2rad($theta));
$dist = acos($dist);
$dist = rad2deg($dist);
$miles = $dist * 60 * 1.1515;
$unit = strtoupper($unit);
if ($unit == "K")
{
return ($miles * 1.609344);
}
else
if ($unit == "N")
{
return ($miles * 0.8684);
}
else
{
return $miles;
}
}
echo distance(32.9697, -96.80322, 29.46786, -98.53506, "M") . " Miles<br />";
echo distance(32.9697, -96.80322, 29.46786, -98.53506, "K") . " Kilometers<br />";
echo distance(32.9697, -96.80322, 29.46786, -98.53506, "N") . " Nautical Miles<br />";
?>
Run Code Online (Sandbox Code Playgroud)
然后:如何使用函数比较每个值来确定坐标之间的接近程度(使用我的distance()
函数)?我的问题是我不知道如何比较第一个查询的每个点与第二个查询的每个点之间的距离,以及每种可能的组合.
我希望有这样的函数比较(lat1,lon1,lat2,lon2); (lat1,lon1,lat3,lon3),(lat1,lon1,lat4,lon4),(lat1,lon1,lat5,lon5),(lat1,lon1,lat6,lon6)等等.
非常感谢您提供任何帮助
你的逻辑是完全错误的,你正在弄清楚你在寻找什么.它比你想象的要简单得多.
第一:为了大幅加速脚本和查询以及保护它免受任何攻击,请使用PDO预处理语句和安全协议.Mysql没有准备好的语句已被弃用超过十年!
我的经验(25年的编码)告诉我永远不要相信你的服务器会发生什么,所以我对安全性有点恐惧....本教程解释了你需要做的第一个基本步骤,并解释你这个脚本,因为它应该(按原样复制所有代码).
注意,使用本地IP地址而不是Localhost将加速mysql连接2到5,具体取决于开发平台(灯,wamp等...)
设置执行参数
ini_set('memory_limit', '64M'); // memory limit used by script
set_time_limit(0); // no time limit
Run Code Online (Sandbox Code Playgroud)
建立您的安全mysql连接
try {
$con = new PDO('mysql:host=127.0.0.1;dbname=map;charset=UTF8','root','password');
$con->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
echo 'Connection failed: ' . $e->getMessage();
}
Run Code Online (Sandbox Code Playgroud)
建立二级安全协议以检查它是否真的是一个ajax调用
$isAjax = isset($_SERVER['HTTP_X_REQUESTED_WITH']) AND
strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest';
if (!$isAjax) {
$user_error = 'Access denied - not an AJAX request from allowed computer...';
trigger_error($user_error, E_USER_ERROR);
exit;
}
Run Code Online (Sandbox Code Playgroud)
第二:使用远程函数INSIDE你的mysql查询,以便正确排序你正在寻找的结果.请注意,此处使用的mysql距离与您当前使用的距离不同(更快,更精确).它将为您提供表1中参考点与表2中所有其他参考点之间的距离(以km为单位),按距离排序(最接近第一行).
我们假设您从这样的ajax获得结果:
if($isAjax){
$param4 = '%' . $_POST['b']. '%'; // MYSQL LIKE bind param buscar
$param5 = '(' . $_POST['c'] . ')'; //MYSQL NOT IN bind param buscarcarrera
}
Run Code Online (Sandbox Code Playgroud)
我们假设您从第一个查询获得结果(简化):
$sql1_array = array(
array('id' => 1, 'Lati' => 6.2523915, 'Longi' => -75.5737028),
array('id' => 2, 'Lati' => 6.2640349, 'Longi' => -75.5990783)
);
Run Code Online (Sandbox Code Playgroud)
(注意:总是使用"lati"和"longi"来避免与像"long"这样的PHP函数冲突)
你准备好的声明:
$sql2 = "SELECT *, ( 6371 * acos( cos(radians(?))
* cos(radians(Latitude)) * cos(radians(Longitude) - radians(?)) +
sin( radians(?) ) * sin(radians(Latitude)))) AS distance
FROM finalmap WHERE calle LIKE ? AND calle NOT IN ?
ORDER BY distance LIMIT 10";
$stmt = $con->prepare($sql2);
Run Code Online (Sandbox Code Playgroud)
第三步:使用每个query1结果执行循环以获得与表2相比的距离.在循环中,将参数绑定到准备好的stmt.这将大大加快您的查询速度,因为与数据库的连接是持久的,并且使用PDO(已编译和在内存中)准备查询.
foreach ($sql1_array as $key => $value) {
$stmt->bindParam(1, $value['Lati'], PDO::PARAM_INT);
$stmt->bindParam(2, $value['Longi'], PDO::PARAM_INT);
$stmt->bindParam(3, $value['Lati'], PDO::PARAM_INT);
$stmt->bindParam(4, $param4, PDO::PARAM_STR);
$stmt->bindParam(5, $param5, PDO::PARAM_STR);
$stmt->execute();
$count = $stmt->rowCount();
if ($count >= 1) {
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
}
}
/* $result ordered by distance */
|**************************************|
|field 0 | field 1 | field 2 | distance|
|**************************************|
| 1 | a1 | a2 | 0.00123 | 1 meters
| 2 | b1 | b2 | 0.01202 | 12 meters
| 3 | c1 | c2 | 0.23453 | 234 meters
| 4 | d1 | d2 | 1.58741 | 1km and 587 meters
|**************************************|
Run Code Online (Sandbox Code Playgroud)
我想你们都定了!请享用.