0

私はiosからlatとlon座標の出力を取得しようとしています(これは正常に機能しています)、それをphpに送信してMySQLでクエリを実行し、phpにxmlドキュメントをiosに返送させます(この手順は機能していませんアップロードされたデータエントリをmysqlから読み取ることを拒否し、iOS UItableviewで解析します(これも正常に機能しています)。iOSでのxmlの解析は私にとって非常に簡単であり、すでに実行されているより単純な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 を初めて使用するので、スクリプトを 1 行ずつ見ていくことで、観察したことを記録しておこうと思いました。

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

ここのブレースは不要です。また、いくつかの入力の健全性チェック (パラメーターが設定されているかどうかを含む) を実行したい場合もあります。

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

地上のある範囲内のレコードを検索する場合は、大圏距離を計算する必要があります。現在のアプローチでは、経度 0.1° の距離は緯度によって異なり、極では距離がまったくないことから、赤道ではほぼ 7 マイルまで変化することに注意してください。

Google は、 Creating a Store Locator with PHP, MySQL & Google Maps の下に役立つガイドを作成しました。 Finding Locations with MySQLおよび (あなたの場合) Outputting XML with PHPのセクションに特に注意してください。

残りのコードを 1 つ以上の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 に答える