问题描述
我正在尝试从 ios 获取纬度和经度坐标的输出(这工作正常),将其发送到 php 以使用 MySQL 进行查询,并让 php 将 xml 文档发送回 ios(此步骤不起作用)因为它拒绝从 mysql 读取上传的数据条目),然后在 iOS UItableview 上解析它(这也工作正常).我试图让它与 XML 一起工作,因为在 iOS 上解析 xml 对我来说真的很简单,而且我已经在上面运行了一个更简单的 xml 脚本,但可能是由于缺乏 php 经验而导致的错误,我无法得到这个 php 脚本在职的.我在我的 php 脚本中做错了什么?谢谢!
I am trying to get the output of the lat and lon coordinates from ios (this is working fine), send it to php to query with MySQL and have the php emit an xml document back to ios(this step is not working because it is refusing to read an uploaded data entry from mysql), then parsing it on iOS UItableview (this is working fine too). I am trying to get this to work with XML because parsing xml on iOS is really simple for me and I've gotten a simpler xml script running already on it, but probably due to mistakes from inexperience in php, I cannot get this php script working. What am I doing wrong in my php script? Thanks!
<?php
{ $lat = (float)$_GET['lat']; } //ios get "lat" value from: NSString *urlString = [NSString stringWithFormat:@"http://www.mysite.com/loc.php?lat=%g&lon=%g", latitude, longitude];
{ $lon = (float)$_GET['lon']; } //ios get "lon" value from: NSString *urlString = [NSString stringWithFormat:@"http://www.mysite.com/loc.php?lat=%g&lon=%g", latitude, longitude];
$minlat = $lat-.1;
$maxlat = $lat+.1;
$minlon = $lon-.1;
$maxlon = $lon+.1;
$dbh = new PDO('(censored personal information)');
$sql = 'SELECT lat, lon, name FROM locations WHERE lat >= ? AND lat <= ? AND lon >= ? AND lon <= ?';
$params = array( $minlat, $maxlat, $minlon, $maxlon );
$q = $dbh->prepare( $sql );
$q->execute( $params );
$doc = new DOMDocument();
$r = $doc->createElement( "locations" );
$doc->appendChild( $r );
foreach ( $q->fetchAll() as $row) {
{
$e = $doc->createElement( "location" );
$e->setAttribute( 'name', $row['name'] );
$e->setAttribute( 'd', $d );
$r->appendChild( $e );
}
}
print $doc->saveXML();
?>
推荐答案
由于您是 PHP 新手,我想我会通过逐行浏览脚本来记录我对脚本的观察:
Since you're new to PHP, I thought I'd record my observations on your script by walking through it line-by-line:
{ $lat = (float)$_GET['lat']; }
{ $lon = (float)$_GET['lon']; }
这里的大括号是多余的.您可能还希望执行一些输入完整性检查(包括是否完全设置了参数).
The braces here are superfluous. You might also wish to perform some input sanity checks (including whether the parameters were set at all).
$minlat = $lat-.1;
$maxlat = $lat+.1;
$minlon = $lon-.1;
$maxlon = $lon+.1;
如果您想在地面上的某个范围内搜索记录,您需要计算 大圆距离;您应该知道,按照您目前的方法,0.1° 的距离为 0.1°.经度随纬度而变化,从极地无距离到赤道近 7 英里.
If you're looking to search for records within some range on the ground, you will want to calculate great-circle distance; you should be aware that, with your current approach, the distance of 0.1° longitude varies with one's latitude, from no distance whatsoever at the poles to almost 7 miles at the equator.
Google 在 Creating a Store Locator with PHP, MySQL & 下编写了一个有用的指南.Google 地图:请特别注意使用 MySQL 查找位置 和(在您的情况下)使用 PHP 输出 XML.
Google have written a useful guide under Creating a Store Locator with PHP, MySQL & Google Maps: pay particular attention to the section on Finding Locations with MySQL and (in your case) Outputting XML with PHP.
将其余代码放在一个或多个 try { ... }
块中并捕获抛出的任何异常.
Place the rest of the code in one or more try { ... }
blocks and catch any exceptions thrown.
$dbh = new PDO('(censored personal information)');
检查是否成功:if (!$dbh) die('Unable to create PDO object');
.
然后设置这个 PDO 对象来引发异常 $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
而不仅仅是模拟准备好的语句 $dbh->;setAttribute(PDO::ATTR_EMULATE_PREPARES, FALSE);
.
Then set this PDO object to raise exceptions $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
and not merely to emulate prepared statements $dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, FALSE);
.
$sql = 'SELECT lat, lon, name FROM locations WHERE lat >= ? AND lat <= ? AND lon >= ? AND lon <= ?';
虽然您的查询很可能会按照上述建议发生巨大变化,但知道您可以使用 MySQL 的 BETWEEN ... AND ...
运算符:WHERE (lat BETWEEN ? AND ?) AND (lon BETWEEN ?AND ?)
.
Whilst your query may well change dramatically following the advice above, it may still be useful to know that you can abbreviate this query using MySQL's BETWEEN ... AND ...
operator: WHERE (lat BETWEEN ? AND ?) AND (lon BETWEEN ? AND ?)
.
如果您使用命名参数而不是占位符,您可能还会发现您的代码更易于维护:WHERE (lat BETWEEN :minlat AND :maxlat) AND (lon BETWEEN :minlon AND :maxlon)
.
You might also find your code easier to maintain if you use named parameters instead of placeholders: WHERE (lat BETWEEN :minlat AND :maxlat) AND (lon BETWEEN :minlon AND :maxlon)
.
$params = array( $minlat, $maxlat, $minlon, $maxlon );
如果使用命名占位符,您可以使用关联数组作为 $params = array ( ':minlat' => $minlat, ... );
.
If using named placeholders, you could use an associative array as $params = array ( ':minlat' => $minlat, ... );
.
在任何一种情况下,您都可以分别将值或变量绑定到您的参数(这是我的首选方法,因为它可以轻松地使人们在仅更改一些参数的情况下再次运行查询):$q->bindParam(':minlat', $minlat);
等
In either case, you could bind values or variables to your parameters separately (which is my preferred approach, as it easily enables one to run the query again with only some parameters changed): $q->bindParam(':minlat', $minlat);
etc.
$q = $dbh->prepare( $sql );
$q->execute( $params );
$doc = new DOMDocument();
检查是否成功:if (!$doc) die('Unable to create DOMDocument object');
.
$r = $doc->createElement( "locations" );
$doc->appendChild( $r );
foreach ( $q->fetchAll() as $row) {
fetchAll()
将整个结果集提取到 PHP 中,如果结果集很大,这可能需要大量内存.如果只希望依次遍历每条记录,通常最好根据需要获取每条记录:while ( $row = $q->fetch() )
.
fetchAll()
fetches the entire resultset into PHP, which could require a lot of memory if the resultset is large. Where one merely wishes to iterate over each record in turn, it's usually better to fetch each record as required: while ( $row = $q->fetch() )
.
{
这个支架(连同下面的一对)是多余的.
This brace (together with its pair below) is superfluous.
$e = $doc->createElement( "location" );
$e->setAttribute( 'name', $row['name'] );
$e->setAttribute( 'd', $d );
你的 $d
变量在哪里声明/赋值?
Where is your $d
variable declared/assigned?
$r->appendChild( $e );
}
如上所述,这个大括号是多余的.
As mentioned above, this brace is superfluous.
}
print $doc->saveXML();
这篇关于php 查询 iOS 纬度和经度,而不是使用 xml 输出搜索附近的 mysql 纬度和经度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!