So I've got a website with two HTML drop-down lists- one is a list of US states, the other is a list of the cities/towns in the selected state. As of right now, I have an HTML file for each state, and they all have the options listed as such:
<option value="44.729932, -72.381758">Albany</option>
<option value="44.976728, -73.30257">Alburg</option>
The values are the coordinates (latitude, longitude) of each town. When I hit "search", the form data is sent to a PHP script for SimpleGeo (a location database company- amazing, btw)- the purpose of selecting the town is to provide values for $lat and $lon in this part of the PHP script, which is sent to SimpleGeo for every query:
$q = $_GET['q'];
$lat = 44.729932;
$lon = -72.381758;
$args = array('q' => $q, 'num' => 25, 'category' => Restaurant, 'radius' => 25);
$results = $client->getPlaces($lat, $lon, $args);
The part that can't change is the "getPlaces($lat, $lon, $args);" part because for some reason when I replace $lat and $lon with $coordinates and then replace their values with:
$coordinates = $_GET['city']; ('city' is the name and id of my city/town lists)
It doesn't see it as a valid query. Meanwhile, if you replace "$lat, $lon" with numbers as the coordinates, it understands perfectly.
... I just need to split up my values, either in the HTML files themselves, or in the PHP script by recognizing that ", " means the latitude value has ended and the longitude value has started. I don't know how it should be done, I just know that $lat and $lon have to equal the values set by my HTML files- one file for every state, about 500 options on average per file... How do I make it recognize something like "44.729932, -72.381758" as $lat and $lon?! Or alternatively, how do I make my drop down list pass on the values for lat and lon if I make the options look like this:
<option lat="44.976728" lon="-73.30257">Alburg</option>
Thanks for reading, sorry it's so long! It's 2:50AM, my eyes are bleeding! :P Help is MUCH appreciated...
You can split your option's value to get the latitude and longitude.
Validate your field with a regex like -?[0-9]+\.[0-9]+, -?[0-9]+\.[0-9]+, then explode it and get the two values :
list($lat, $lon) = explode(", ", $_GET['city']);
Here the separator is , including the space, to remove it btw.
You could try this...
if (isset($_GET['location']) AND strpos($_GET['location'], ', ') !== FALSE) {
list($latitude, $longitude) = explode(', ', $_GET['location']);
}
...though this will also split successfully if someone sends you something funny like hello -4.3, 3.1 bye!.
Ideone.
Alternatively, you could use this regex to validate it and extract the values.
if ($location = filter_input(INPUT_GET, 'location')) {
preg_match('/^(?P<latitude>-?\d+\.\d+), (?P<longitude>-?\d+\.\d+)\z/', $location, $matches);
$latitude = $matches['latitude'];
$longitude = $matches['longitude'];
}
Ideone.
The issue above of extra data either side won't be an issue with the regex.
I'd advise that you use a unique ID as the option's value attribute and then load the latitude and longitude for the selected town from your database based on the ID the user selects.
If you insist in doing it this way, then you can use explode() to split the returned value.
Related
I'm currently working on a project where my current goal is to print information about the specific user on the final checkout form inputs.
First off I gather the information of the specific user through a public function:
public function getUserAddress($dbh)
{
$sql = "SELECT street, zip, city FROM address WHERE user_id=:user";
$stmt = $dbh->prepare($sql);
$stmt->bindParam(':user', $this->uid);
$stmt->execute();
$userAddress = $stmt->fetchAll(PDO::FETCH_ASSOC);
$this->userAddress = $userAddress;
return $this->userAddress;
}
Then I store the information in a variable I call $userAddress
$userAddress = $user->getUserAddress($dbh);
Since the user has two addresses, both with a "Street", "City" & "Zip" I'm storing both arrays in $templateData. This way I can specify what index should be printed out in which input tag instead of having to create a new function for each slot.
$templateData['user']['address'] = $userAdress['street']." ".$userAddress['city']." ".$userAddress['zip'];
However, printing these out seems near impossible. When I var_dump
$templateData['user']['address']
I only seem to be getting 2 empty strings and nothing else.
This is just code from my Checkout.controller but somehow the information doesn't seem to be found in my template page. All routes and includes are correct so dw about that.
I'm quite new to all this so I'd appreciate any help I can get!
Image of how the information should be presented https://gyazo.com/40fa06832207bd785ee038af4962bb1e
So in this case: "Postort" = "City" & "Gatuadress" = "Street"
PDO::fetchAll(PDO::FETCH_ASSOC) will return an array of associative arrays; so to access the individual elements you need something like:
$userAdress[0]['street']." ".$userAddress[0]['city']." ".$userAddress[0]['zip']
I could alaways define every single one of them specifically although it seems far fetched. Something like this:
$templateData['user']['address'][0]['street'] = $userAddress[0]['street'];
$templateData['user']['address'][0]['city'] = $userAddress[0]['city'];
$templateData['user']['address'][0]['zip'] = $userAddress[0]['zip'];
$templateData['user']['address'][1]['street'] = $userAddress[1]['street'];
$templateData['user']['address'][1]['city'] = $userAddress[1]['city'];
$templateData['user']['address'][1]['zip'] = $userAddress[1]['zip'];
I'm basically looking for another solution which doesn't require so much repetition.
I'm looping through rows in my database to get information from whois results.
Here's what I have right now:
function GetEmailFromWhois($domain){
$whois = new Whois();
$query = $domain;
$whois->deep_whois=TRUE;
$result = $whois->Lookup($query, false);
$raw_data = $result["rawdata"];
$email = "";
foreach($raw_data as $item){
$items = explode(":",$item);
if($items[0] == "Registrant Email"){
$email = $items[1];
}
}
return $email;
}
The code above gets the Registrant Email from the whois results.
I reference it later on in my code like this: $email = GetEmailFromWhois($domain);
However, at the same time as getting the registrant email, I'd also like to get the Registrant Name, Registrant Phone, and Registrant Country.
I could just copy the code above 3 more times for each of those additional fields, but that would cause there to be 4 whois queries for each domain - instead of just one.
Anyone know how I can get the info I need in a single query and then use it later on in my code?
As I recently noted in another answer, parsing WHOIS data is a complex, messy affair. The exact format of WHOIS responses is not specified by any standard, and not all registries/registrars will use the format you're attempting to parse here. (Some use different labels to mark the fields you're searching for, some use labels that are ambiguous without context, some don't label certain fields at all, and some won't even include the information you're searching for here.) Worse, some registries/registrars will heavily rate limit you if it becomes apparent that you're trying to extract more than a few responses from them. In short, I'd recommend that you avoid attempting to parse WHOIS responses if at all possible.
To solve your immediate problem, though, you can create an associative array to represent the WHOIS response like so:
$arr = [];
foreach($raw_data as $item) {
list($k, $v) = explode(":", $item);
$arr[$k] = $v;
}
This will give you an associative array of the results, so you can pull out individual values using e.g.
$email = $arr["Registrant Email"];
I have a string with values (which are suburbs) like so:
$suburbs = "Mawson, Elizabeth, Burnside, Elizbeth, Mawson";
There COULD be double ups in the suburbs that the string contains. I can't change this fact.
What I am trying to do is create an option list for a drop down menu that a user will use. I do not want to display the same suburb twice( or more for that matter).
What I have so far:
$suburbs = "Mawson, Elizabeth, Burnside, Elizbeth, Mawson";
//Explode the suburbs string delimited by a comma
$boom = explode(',', $suburbs);
foreach($boom as $b)
{
$suburbOptionList .= '<option value='.$b.'>'.$b.'</option>';
}
?>
<select> <?php
echo $suburbOptionList;
?>
</select>
I know that this will simply display all of the options but I really don't know how to display each suburb only once. Ive tried a few foreach,and if combinations but they look ugly and work just as bad.
Any help would be appreciated.
Cheers in advance!
Pass $boom through array_unique() and you'll be fine.
$bada_boom = array_unique($boom);
P.S.: This will not help if you have typos or variations in duplicates. (Elizbeth != Elizabeth).
In that case you will need to get creative.
Also, hw (in comments) made a good point about trimming whitespaces. If the suburbs come from an untrusted source and are improperly formatted, you may need to normalize them. This means trimming whitespaces and normalizing capitals:
$boom = array_walk($boom, 'trim');
$boom = array_walk($boom, 'strtolower');
$bada_boom = array_unique($boom);
I have the following street names and house numbers in a text file:
Albert Dr: 4116-4230, 4510, 4513-4516
Bergundy Pl: 1300, 1340-1450
David Ln: 3400, 4918, 4928, 4825
Garfield Av: 5000, 5002, 5004, 5006, 8619-8627, 9104-9113
....
This data represents the boundary data for a local neighborhood (i.e., what houses are inside the community).
I want to make a PHP script that will take a user's input (in the form of something like "4918 David Lane" or "3000 Bergundy") search this list, and return a yes/no response whether that house exists within the boundaries.
What would be an efficient way to parse the input (regex?) and compare it to the text list?
Thanks for the help!
It's better to store this info in a database so that you don't have to parse out the data from a text file. Regexes are also not generally applicable to find a number in a range so a general purpose language is advised as well.
But... if you want to do it with regexes (and see why it's not a good idea)
To lookup the numbers for a street use
David Ln:(.*)
To then get the numbers use
[^,]*
You could simply import the file into a string. After this is done, breack each line of the file in an array so Array(Line 1=> array(), Line 2=> array(), etc. After this is done, you can explode using :. After, you'll simply need to search in the array. Not the fastest way, but it may be faster then regex.
You should sincerely consider using a database or re-think how your file are.
Try something like this, put your street names inside test.txt.. Now that you are able to get the details inside the text file, just compare it with the values that you submit in your form.
$filename = 'test.txt';
if(file_exists($filename)) {
if($handle = fopen($filename, 'r')) {
$name = array();
while(($file = fgets($handle)) !==FALSE) {
preg_match('#(.*):(.*)#', $file, $match);
$array = explode(',', $match[2]);
foreach($array as $val) {
$name[$match[1]][] = $val;
}
}
}
}
As mentioned, using a database to store street numbers that are relational to your street names would be ideal. I think a way you could implement this with your text file though is to create a a 2D array; storing the street names in the first array and the valid street numbers in their respective arrays.
Parse the file line by line in a loop. Parse the street name and store in array, then use a nested loop to parse all of the numbers (for ones in a range like 1414-1420, you can use an additional loop to get each number in the range) and build the next array in the initial street name array element. When you have your 2D array, you can do a simple nested loop to check it for a match.
I will try to make a little pseudo-code for you..
pseudocode:
$addresses = array();
$counter = 0;
$line = file->readline
while(!file->eof)
{
$addresses[$counter] = parse_street_name($line);
$numbers_array = parse_street_numbers($line);
foreach($numbers_array as $num)
$addresses[$counter][] = $num;
$line = file->readline
$counter++;
}
It's better if you store your streets in a separate table with IDs, and store numbers in separate table one row for each range or number and street id.
For example:
streets:
ID, street
-----------
1, Albert Dr
2, Bergundy Pl
3, David Ln
4, Garfield Av
...
houses:
street_id, house_min, house_max
-----------------
1, 4116, 4230
1, 4510, 4510
1, 4513, 4516
2, 1300, 1300
2, 1340, 1450
...
In the rows, where no range but one house number, you set both min and max to the same value.
You can write a script, that will parse your txt file and save all data to db. That should be as easy as several loops and explode() with different parameters and some insert queries too.
Then with first query you get street id
SELECT id FROM streets WHERE street LIKE '%[street name]%'
After that you run second query and get answer, is there such house number on that street
SELECT COUNT(*)
FROM houses
WHERE street_id = [street_id]
AND [house_num] BETWEEN house_min AND house_max
Inside [...] you put real values, dont forget to escape them to prevent sql injections...
Or you even can run just one query using JOIN.
Also you should make sure that your given house number is integer, not float.
I am importing an RSS feed from the NOAA website which is returned as RSS.
The latitude and longitude values are returned as one tag which is below:
<georss:point>40.369 -73.703</georss:point>
Is it possible to 'break' apart these values and create two variables such as:
$lat = 40.369
$lng = -73.703
Here is my PHP script that is currently parsing out the XML:
$rss_title = $RSS_DOC->channel->title;
$rss_link = $RSS_DOC->channel->link;
$rss_editor = $RSS_DOC->channel->managingEditor;
$rss_copyright = $RSS_DOC->channel->copyright;
$rss_date = $RSS_DOC->channel->item->pubDate;
$rss_description = $RSS_DOC->channel->item->description;
Appreciate any resource to get me pointed in the right direction. thanks,
Yes, not too hard. Explode (edited - thanks #sdleihssirhc):
http://php.net/manual/en/function.explode.php
E.g.:
list($latt, $long) = explode(" ", $RSS_DOC->channel->item->point);
Hope it works.