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"];
Related
PHP Version 7.4
I am currently working on a small php program to take certain shipments and optimize the order of them to the most efficient route. So far so good, it works with the google maps api the following way:
$url = "https://maps.googleapis.com/maps/api/directions/json?";
$url .= "origin=".urlencode($this->startPoint);
$url .= "&destination=".urlencode($this->endPoint);
$url .= "&waypoints=".urlencode("optimize:true")."|";
$x = 0;
foreach($ordersadress as $order){
if($x != 0){
$url .= urlencode("|");
}
$url .= urlencode($order["address"]);
$x++;
}
$url .= "&key=".$conf->global->GOOGLE_MAPS_API_KEY;
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$resp = curl_exec($ch);
$json = json_decode($resp);
Now, in order to know which Shipment actually comes first, I go through the json response and compare the addresses of my shipments to each waypoint in the response to see which address comes first and so on.
Here is my problem, in the response the addresses are not written out, they are shortened. For example with a german address, my shipment address that I add to the api call is "Kirchenplatz 4". In googles response they shorten it to "Kirchenpl. 4".
I think the equivalent in english would be changing "Road" to "Rd".
(I will put an example request at the end, incase you do not know what it looks like, you do need a Google API key though.)
For now, I'm doing it the following way:
foreach($json->routes[0]->legs as $leg){
if($iterator != 0){
foreach($ordersadress as $order){
$addy = explode(",", $leg->start_address);
$oa = explode(",", $order["address"]);
//Here I compare if the returned address is the same as the one on the shipment, needs to be a 1:1 match, this is my issue
if(strpos($oa[0], $addy[0]) !== false){
$lat = $leg->start_location->lat;
$lon = $leg->start_location->lng;
$co = $order["object"];
$this->orders[] = ["rowid" => $co->id, "sortorder" => $sortnum, "notes" => "", "tourdate" => $tourdate->format("d.m.Y"), "address" => $leg->start_address, "drivetime" => $leg->duration->value, "object" => $co, "lat" => $lat, "lon" => $lon];
$this->kmAll += round($leg->distance->value/1000, 2);
$sortnum++;
foreach($leg->steps as $step){
$polyline .= $step->polyline->points;
}
break;
}
}
unset($order);
}
This example only works with exact 1:1 matches, which is ofcourse not viable in a real world scenario, as the workers of my customer will not be able to always put the address in the exact same way that google returns it, besides, there is already data for thousands of shipments which would have to be changed.
I have thought of following solutions:
Get a list of all words that are shortened by google, and then do it to my addresses. However I was not able to find a list.
My second solution was to do a percentage match of 2 addresses, and the one with the highest match would be at the position that google returned. With this solution, I am going to be honest I did not really understand the similar_text function and how it works and I am not sure if it would even be a good solution in my case.
I am open to any ideas and suggestions that you might have.
Example Google API request:
https://maps.googleapis.com/maps/api/directions/json?origin=Lange+G.+20%2C+2700+Wiener+Neustadt&destination=Ruckergasse+42%2C+1120+Wien&waypoints=optimize%3Atrue|Brauhausgasse+6%7CHauptpl.+1%2C+Graz%7CKirchenpl.+4%2C+G%C3%A4nserndorf%7CS%C3%BCdtiroler+Pl.+1%2C+Salzburg%7CUnter+dem+Rucker+14%7CVivenotgasse+3%2F6+13%2C+Wien&key=YOUR_API_KEY
After trying for a while and asking some friends I arrived at the solution of using the fuzzy logic to match addresses. Luckily there is already an implementation of a method of this logic which is called levenshtein($string1, $string2)
I would suggest reading it up here: https://www.php.net/manual/de/function.levenshtein.php
Example 1 was basically my solution to the problem and has been working without problems so far.
However be careful! As explained here in the comment below example 1 using UTF-8 will cause problems!
I have a php script getting all folders in a posts folder and making them into a list.
I have a $postinfo_str variable assigned to a json file for each folder which I am using to store post date and category/tag info etc in.
I also have a $pagetitle variable assigned to a title.php include file for each folder. So say I am on a "June 2018" archive page, the text in that file will be "June 2018". If I am on say a "Tutorials" category page, that will be the text in the title.php.
In the json file, I have:
{
"Arraysortdate": "YYYYMMDD",
"Month": "Month YYYY",
"Category": ["cat1", "cat2", "etc"]
}
I am ordering the array newest to oldest using krsort with Arraysortdate as key.
How do I filter the array using $pagetitle as input, finding if there is a match in $postinfo_str, and if there isn't, remove that folder from the array?
All I can seem to find regarding array sorting is where the info in the $pageinfo_str is basically the array and so by that, the $title is the input and the output is the matching text from the $postinfo_str, whereas I want the output to be the folders that only have the matching text in the $postinfo_str to what the input ($pagetitle) is.
Here is my code I have.. Keep in mind this is flat file, I do not want a database to achieve this. See comments if you want an explaination.
<?php
$BASE_PATH = '/path/to/public_html';
// initial array containing the dirs
$dirs = glob($BASE_PATH.'/testblog/*/posts/*', GLOB_ONLYDIR);
// new array with date as key
$dirinfo_arr = [];
foreach ($dirs as $cdir) {
// get current page title from file
$pagetitle = file_get_contents("includes/title.php");
// get date & post info from file
$dirinfo_str = file_get_contents("$cdir/includes/post-info.json");
$dirinfo = json_decode($dirinfo_str, TRUE);
// add current directory to the info array
$dirinfo['dir'] = $cdir;
// add current dir to new array where date is the key
$dirinfo_arr[$dirinfo['Arraysortdate']] = $dirinfo;
}
// now we sort the new array
krsort($dirinfo_arr);
foreach($dirinfo_arr as $key=>$dir) {
$dirpath = $dir['dir'];
$dirpath = str_replace('/path/to/public_html/', '', $dirpath);
?>
<!--HTML HERE SUCH AS--!>
TEXT <br>
<?php
};
?>
I have difficulties following your problem description. Your code example is slightly confusing. It appears to load the same global includes/title.php for each directory. Meaning, the value of $pagetitle should be the same every iteration. If this is intended, you should probably move that line right outside the loop. If the file contains actual php code, you should probably use
$pagetitle = include 'includes/title.php';
or something similar. If it doesn't, you should probably name it title.txt. If it is not one global file, you should probably add the path to the file_get_contents/include as well. (However, why wouldn't you just add the title in the json struct?)
I'm under the assumption that this happened by accident when trying to provide a minimal code example (?) ... In any case, my answer won't be the perfect answer, but it hopefully can be adapted once understood ;o)
If you only want elements in your array, that fulfill certain properties, you have essentially two choices:
don't put those element in (mostly your code)
foreach ($dirs as $cdir) {
// get current page title from file
$pagetitle = file_get_contents("includes/title.php");
// get date & post info from file
$dirinfo_str = file_get_contents("$cdir/includes/post-info.json");
$dirinfo = json_decode($dirinfo_str, TRUE);
// add current directory to the info array
$dirinfo['dir'] = $cdir;
// add current dir to new array where date is the key
// ------------ NEW --------------
$filtercat = 'cat1';
if(!in_array($filtercat, $dirinfo['Category'])) {
continue;
}
// -------------------------------
$dirinfo_arr[$dirinfo['Arraysortdate']] = $dirinfo;
array_filter the array afterwards, by providing a anonymous function
// ----- before cycling through $dirinfo_arr for output
$filtercat = 'cat1';
$filterfunc = function($dirinfo) use ($filtercat) {
return in_array($filtercat, $dirinfo['Category']));
}
$dirinfo_arr = array_filter($dirinfo_arr, $filterfunc);
you should read up about anonymous functions and how you provide local vars to them, to ease the pain. maybe your use case is bettersuited for array_reduce, which is similar, except you can determine the output of your "filter".
$new = array_filter($array, $func), is just a fancy way of writing:
$new = [];
foreach($array as $key => $value) {
if($func($value)) {
$new[$key] = $value;
}
}
update 1
in my code samples, you could replace in_array($filtercat, $dirinfo['Category']) with in_array($pagetitle, $dirinfo) - if you want to match on anything that's in the json-struct (base level) - or with ($pagetitle == $dirinfo['Month']) if you just want to match the month.
update 2
I understand, that you're probably just starting with php or even programming, so the concept of some "huge database" may be frightening. But tbh, the filesystem is - from a certain point of view - a database as well. However, it usually is quite slow in comparison, it also doesn't provide many features.
In the long run, I would strongly suggest using a database. If you don't like the idea of putting your data in "some database server", use sqlite. However, there is a learning curve involved, if you never had to deal with databases before. In the long run it will be time worth spending, because it simplifys so many things.
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.
re: Home Site = http://mobiledetect.net/
re: this script = Mobile_Detect.php
Download script here: https://github.com/serbanghita/Mobile-Detect
This script functions perfectly detecting the different parameters of a user's device.
However, this is how I am currently detecting these parameters:
// each part of the IF statement is hard-coded = not the way to do this
if($detect->isiOS()){
$usingOS = 'iOS';
}
if($detect->isAndroidOS()){
$usingOS = 'Android';
}
echo 'Your OS is: '.$usingOS;
My goal is to use a FOREACH to iterate thru the various arrays in this script to determine a user's device's parameters. I would need to have the "($detect->isXXXXOS())" be dynamic... (which, would be based upon the KEY). The results would display the KEY. But the detection would be based upon the VALUE.
Also, since my web page uses a REQUIRE to access this script... in the Mobile_Script.php script, the arrays are "protected." I think this is also causing me problems (but I don't know for sure).
Any help is appreciated.
In foreach loop you can call dynamic method look like this :
$array = array('Android','Windows','Linux','Mac');
foreach( $array as $value) {
$method = "is{$value}OS";
if($detect->$method()) {
$os = $value;
echo "Your OS is : {$os}";
}
}
Please rearrange your code what you want. I give you an example.
you can try to use somethin like this:
$OSList = $detect->getOperatingSystems();// will give array of operating system name => match params
foreach($OSList as $os_name=>$os_params/*unused*/)
{
$method = 'is'.$os_name;
if($detect->$method())
{
$usingOS = $os_name;
}
}
I am trying to search for a php variable in an xml file using xpath, but failing miserably. It works with a hard coded value, so I am nearly there..
<visitors>
<detail>
<id>876867</id>
<name>Bob McHaggis</name>
<email>bob#gmail.com</email>
</detail>
<detail>
<id>897987</id>
<name>Mark McBob</name>
<email>mark#gmail.com</email>
</detail>
</visitors>
<?php $sxe = simplexml_load_file("/CaptivePortal/visitors.xml");
foreach($sxe->xpath('//visitors/detail') as $item){
$row = simplexml_load_string($item->asXML());
$v = $row->xpath('//id[. ="'.$_COOKIE["judsons"].'"]');
} echo $v[0]; ?>
This works great checks for an id against the id stored in the cookie. But based on that value being found how do I access the name and email for the key matched?
Found & matched: 897987
I want to echo the name and email to, so based on that is Mark McBob & mark#gmail.com
My initial advice would be to take a good few minutes to (re-)read through the SimpleXML Basic Usage page in the PHP manual.
For selecting a single item within the XML file, there is no need at all to loop over anything. The example code below, and why it is different from yours, should become clear after familiarising yourself with the page mentioned above.
<?php
$search_id = (int) $_COOKIE["judsons"];
$visitors = simplexml_load_file("/CaptivePortal/visitors.xml");
$details = $visitors->xpath("detail[id='$search_id']");
if (empty($details)) {
echo "No details found for '$search_id'.";
} else {
$detail = $details[0];
$name = (string) $detail->name;
$email = (string) $detail->email;
echo "$name's email is $email";
}
The idea above is that $details will be an array containing hopefully just one <detail> element. It could be an empty array if no <detail> was found with the specified <id>, which is what the if(empty(…)) checks for. If the $details array is not empty, we're really only interested in the first one ($details[0]).
To access the information available within the <detail>, as explained on the "basic usage" page, the elements can be accessed with normal object property syntax ($detail->name). Doing so returns an object for that item (e.g. the <name>), so to get at the value as a string the object is type cast using (string).
You're actually doing quite a bit you don't need to there. For one thing, you don't need the loop. For another, inside your loop, you convert the context XML into a string (::asXML()), then convert it back into XML (simplexml_load_string()).
All you need is:
$xml = "<visitors><detail><id>876867</id><name>Bob McHaggis</name><email>bob#gmail.com</email></detail><detail><id>897987</id><name>Mark McBob</name><email>mark#gmail.com</email></detail></visitors>";
$sxe = simplexml_load_string($xml);
$row = $sxe->xpath('detail[id = '.$_COOKIE["judsons"].']');
That gets you the row. To extract part of it:
$name = $row[0]->xpath('name');
echo $name[0]; //Mark McBob