Eftersom du är ny på PHP tänkte jag spela in mina observationer på ditt skript genom att gå igenom det rad för rad:
{ $lat = (float)$_GET['lat']; }
{ $lon = (float)$_GET['lon']; }
Hängslen här är överflödiga. Du kanske också vill utföra några förnuftskontroller (inklusive om parametrarna överhuvudtaget var inställda).
$minlat = $lat-.1;
$maxlat = $lat+.1;
$minlon = $lon-.1;
$maxlon = $lon+.1;
Om du vill söka efter poster inom ett visst område på marken vill du beräkna storcirkelavstånd ; du bör vara medveten om att med din nuvarande inflygning varierar avståndet 0,1° longitud med ens latitud, från inget som helst avstånd vid polerna till nästan 7 miles vid ekvatorn.
Google har skrivit en användbar guide under Skapa en butikssökare med PHP, MySQL och Google Maps :Var särskilt uppmärksam på avsnittet om Hitta platser med MySQL och (i ditt fall) Utmata XML med PHP .
Placera resten av koden i en eller flera try { ... }
blockerar och fånga eventuella undantag.
$dbh = new PDO('(censored personal information)');
Kontrollera att det lyckades:if (!$dbh) die('Unable to create PDO object');
.
Ställ sedan in det här PDO-objektet för att skapa undantag $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
och inte bara för att efterlikna förberedda satser $dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, FALSE);
.
$sql = 'SELECT lat, lon, name FROM locations WHERE lat >= ? AND lat <= ? AND lon >= ? AND lon <= ?';
Även om din fråga mycket väl kan förändras dramatiskt efter råden ovan, kan det fortfarande vara användbart att veta att du kan förkorta den här frågan med MySQL:s BETWEEN ... AND ...
operator:WHERE (lat BETWEEN ? AND ?) AND (lon BETWEEN ? AND ?)
.
Du kanske också tycker att din kod är lättare att underhålla om du använder namngivna parametrar istället för platshållare:WHERE (lat BETWEEN :minlat AND :maxlat) AND (lon BETWEEN :minlon AND :maxlon)
.
$params = array( $minlat, $maxlat, $minlon, $maxlon );
Om du använder namngivna platshållare kan du använda en associativ array som $params = array ( ':minlat' => $minlat, ... );
.
I båda fallen kan du binda värden eller variabler till dina parametrar separat (vilket är min föredragna metod, eftersom det enkelt gör det möjligt för en att köra frågan igen med bara några parametrar ändrade):$q->bindParam(':minlat', $minlat);
etc.
$q = $dbh->prepare( $sql );
$q->execute( $params );
$doc = new DOMDocument();
Kontrollera att det lyckades:if (!$doc) die('Unable to create DOMDocument object');
.
$r = $doc->createElement( "locations" );
$doc->appendChild( $r );
foreach ( $q->fetchAll() as $row) {
fetchAll()
hämtar hela resultatuppsättningen till PHP, vilket kan kräva mycket minne om resultatuppsättningen är stor. Där man bara vill iterera över varje post i tur och ordning, är det vanligtvis bättre att hämta varje post efter behov:while ( $row = $q->fetch() )
.
{
Denna tandställning (tillsammans med sitt par nedan) är överflödig.
$e = $doc->createElement( "location" );
$e->setAttribute( 'name', $row['name'] );
$e->setAttribute( 'd', $d );
Var är din $d
variabel deklarerad/tilldelad?
$r->appendChild( $e );
}
Som nämnts ovan är denna tandställning överflödig.
}
print $doc->saveXML();