0

我正在尝试从 ios 获取 lat 和 lon 坐标的输出(这工作正常),将其发送到 php 以使用 MySQL 进行查询,并让 php 将 xml 文档发送回 ios(此步骤不起作用,因为它是拒绝从mysql读取上传的数据条目),然后在iOS UItableview上解析它(这也很好)。我试图让它与 XML 一起使用,因为在 iOS 上解析 xml 对我来说真的很简单,而且我已经在上面运行了一个更简单的 xml 脚本,但可能是由于 php 经验不足导致的错误,我无法得到这个 php 脚本在职的。我在我的 php 脚本中做错了什么?谢谢!

<?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();
?>
4

1 回答 1

2

由于您是 PHP 新手,我想我会通过逐行浏览脚本来记录我对脚本的观察:

{ $lat = (float)$_GET['lat']; }
{ $lon = (float)$_GET['lon']; }

这里的牙套是多余的。您可能还希望执行一些输入完整性检查(包括是否设置了参数)。

$minlat = $lat-.1;
$maxlat = $lat+.1;
$minlon = $lon-.1;
$maxlon = $lon+.1;

如果您要搜索地面某个范围内的记录,则需要计算大圆距离;您应该知道,在您当前的方法中,0.1° 经度的距离随一个人的纬度而变化,从两极没有任何距离到赤道几乎 7 英里。

Google 在使用 PHP、MySQL 和 Google 地图创建商店定位器下编写了一个有用的指南:特别注意使用 MySQL 查找位置和(在您的情况下)使用 PHP 输出 XML部分。

将其余代码放在一个或多个try { ... }块中并捕获任何抛出的异常。

$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);

$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 ?).

如果您使用命名参数而不是占位符,您可能还会发现您的代码更易于维护:WHERE (lat BETWEEN :minlat AND :maxlat) AND (lon BETWEEN :minlon AND :maxlon).

$params = array( $minlat, $maxlat, $minlon, $maxlon );

如果使用命名占位符,您可以使用关联数组作为$params = array ( ':minlat' => $minlat, ... );.

在任何一种情况下,您都可以将值或变量分别绑定到您的参数(这是我的首选方法,因为它很容易让一个人在只更改一些参数的情况下再次运行查询):$q->bindParam(':minlat', $minlat);等等。

$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() ).

  {

这个支架(连同下面的一对)是多余的。

    $e = $doc->createElement( "location" );
    $e->setAttribute( 'name', $row['name'] );
    $e->setAttribute( 'd', $d );

您的变量在哪里$d声明/分配?

    $r->appendChild( $e );
  }

如上所述,这个支架是多余的。

}
print $doc->saveXML();
于 2012-10-13T07:32:15.413 回答