Тъй като сте нов в 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 Maps :обърнете специално внимание на секцията за Намиране на местоположения с MySQL и (във вашия случай) Извеждане на XML с PHP .
Поставете останалата част от кода в един или повече 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 <= ?';
Въпреки че вашата заявка може да се промени драстично след съвета по-горе, все пак може да е полезно да знаете, че можете да съкратите тази заявка с помощта на 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();