For college, I've made a dynamic news website which uses openweathermap and ipinfo to create a little weather info line in the navbar. Initially it threw an error 'failed loading cafile stream' which was solved by installing a CA certificate in xampp/Apache/bin.
I've got a vague idea what this does - something in relation to making sure the peer's server certificate is valid, but I thought this was only necessary if you're using the 'curl' library? I'm not sure where in my code I've used this, unless it's related to where I pull info from one of the URLs? Just looking for clarification on where in the code 'curl' is used, what it's doing and why exactly I need this certificate. Also as an additional point, if I were to send my files to another person, would they also have to install this .crt file to xampp/apache/bin?
$query = #unserialize (file_get_contents('http://ip-api.com/php/'));
if ($query && $query['status'] == 'success') {
foreach ($query as $data) {
$data . "<br>";
}
}
$url="https://api.openweathermap.org/data/2.5/find?q=" . $query['city'] . "," . $query['countryCode'] . "&units=imperial&type=accurate&mode=xml&APPID=MYKEYCODE";
/*Converts an XML document to an object we can pull our info from*/
$getweather = simplexml_load_file($url);
$gettemp = $getweather->list->item->temperature['value'];
$celcius = ($gettemp - 32) * 5/9;
Thank you!
The slightly modified version I tried was as follows ( using json rather than XML for simplicity ):
$appkey='xxxxxxxxxx165be29428029b';
$data=(object)#unserialize( file_get_contents('http://ip-api.com/php/') );
if( $data ){
$city=$data->city;
$countryCode=$data->countryCode;
$url=sprintf('https://api.openweathermap.org/data/2.5/find?q=%s,%s&units=imperial&type=accurate&mode=json&APPID=%s',$city,$countryCode,$appkey);
$json=json_decode( file_get_contents( $url ) ) ?: false;
if( $json ){
$temp=$json->list[0]->main->temp;
$celcius=( ( $temp - 32 ) * 5/9 );
printf("<pre>City: %s\nCountry: %s\nTemperature: %sF (%sC)</pre>",$city,$countryCode,$temp,$celcius);
}
}
Which yielded:
City: Sheffield
Country: GB
Temperature: 42.17F (5.65C)
Which is a little odd as I have never been to Sheffield and it's nowhere near where I live but I know my ISP routes traffic all over the reekin so geo-location etc never works. That aside there were no errors and no requirement for a valid cacert
good luck
Related
I have this PHP function that logs the visitors to a .txt file (for security reasons). It uses an API to get their location. It works fine on localhost, but when it's actually live it logs empty values. I'm assuming it's because the functions runs before the API has had time to return the data. Is there a way to write something like a Javascript promise or some asynchronous function that will wait for the data to return before logging it?
This is what I currently have:
function getLocation() {
$query = #unserialize (file_get_contents('http://ip-api.com/php/'));
if ($query && $query['status'] == 'success') {
$user = $_SERVER['REMOTE_ADDR'].' - '.date("H:i:s d-m-Y").' - '.$query['country'].', '.$query['regionName'].', '.$query['city'].', '.$query['zip'];
$file = '../logs/userlog.txt';
$currentFileData = file_get_contents($file);
$currentFileData .= $user . PHP_EOL;
file_put_contents($file, $currentFileData);
}
}
What the output should be:
127.0.0.1 - 11:59:33 03-04-2020 - South Africa, Western Cape, Cape Town, 8001
What the actual output is:
127.0.0.1 - 11:59:33 03-04-2020 - , , ,
Your help will be greatly appreciated!
You are not passing the IP address as stated in the documentation after the /php/ part of the URL. It should be
$query = #unserialize (file_get_contents('http://ip-api.com/php/' . $_SERVER['REMOTE_ADDR']));
SOLVED: Thanks to #DanielProtopopov's post I actually found on the documentation that this php version of the API has been deprecated. So using #DanielProtopopov's fix I have to use the JSON API for it to work:
$query = json_decode(file_get_contents('http://ip-api.com/json/' . $_SERVER['REMOTE_ADDR']));
A password was changed and cPanel broke. Fixed the password and it's still broken! I have to iterate over parked domains. I've verified the user / password combination is correct via PuTTY.
<?php
include_once('cpanel_api_xml.php');
$domain = 'example.com';
$pass = '';//etc
$user = '';//etc
$xmlapi = new xmlapi('127.0.0.1');
$xmlapi->password_auth($user,$pass);
$domains_parked = $xmlapi->listparkeddomains($user);
foreach ($domains_parked as $k1=>$v1)
{
if ($v1->domain == $domain) {$return = true; break;}
}
?>
That code generates the following error:
Invalid argument supplied for foreach()
Apparently $domains_parked is not even set! I've spent time looking at the function being called so without dumping all 86KB here is the cleaned up version of $xmlapi->listparkeddomains:
<?php
public function listparkeddomains($username, $domain = null)
{
$args = array();
if (!isset($username))
{
error_log("listparkeddomains requires that a user is passed to it");
return false;
}
if (isset($domain))
{
$args['regex'] = $domain;
return $this->api2_query($username, 'Park', 'listparkeddomains', $args);
}
return $this->api2_query($username, 'Park', 'listparkeddomains');
}
?>
I don't know what they're doing with setting a variable as the second parameter. I've called this function with and without and tested the reaction with a simple mail().
Next I tried calling the API in a more direct fashion:
$xmlapi->api2_query($username, 'Park', 'listparkeddomains')
That also does not work. Okay, let's try some really raw output testing:
echo "1:\n";
print_r($xmlapi);
echo "2:\n";
print_r($xmlapi->api2_query($user, 'Park', 'listparkeddomains'));
echo "3:\n";
$domains_parked = $xmlapi->listparkeddomains($user);
print_r($domains_parked);
die();
That outputs the following:
1: xmlapi Object (
[debug:xmlapi:private] =>
[host:xmlapi:private] => 127.0.0.1
[port:xmlapi:private] => 4099
[protocol:xmlapi:private] => https
[output:xmlapi:private] => simplexml
[auth_type:xmlapi:private] => pass
[auth:xmlapi:private] => <pass>
[user:xmlapi:private] => <user>
[http_client:xmlapi:private] => curl ) 2: 3:
I have never encountered such fragile code though I have no choice but to use it. Some help please?
So cPanel version 74 killed off the whole XML API and it doesn't frigin tell you with any error messages. I can not objectively say in the least that cPanel provides a stable platform to build anything reliable upon. You can either intentionally gimp your server from automatically updating (and potentially miss out on security updates) or every so X iterations of time completely rewrite the code again...and again...and again.
I'm currently developing an app in a IGB (In-Game-Browser) for an Online MMO. For third party development the browser sends HTTP headers with in game information such as Locations, Item ID's, Items Type ID's, etc,.
It's a small script I've been using to practice with. This script works on my local server and like everyone else who's posted on this issue it does not work on my web server. I have come to the conclusion that this is due to Apache not being installed as a module. I spoke with my hosting provider. They said they could not tell me anything other than I need to find an alternative to "apache_request_headers". I've looked over all the previously posted issues on this topic on this site and I'm unable to see how it all fits together. How to use the examples on here to accomplish my end result. Like this [question]: Call to undefined function apache_request_headers()
My code:
<?php
$headers = apache_request_headers();
foreach ($headers as $header => $value) {
echo "$header: $value <br />\n";
}
?>
My error:
Fatal error: Call to undefined function apache_request_headers() in /home/ncgotggb/public_html/ezalternatives.com/index.php on line 2
I have been learning as I go this year and it's been self taught and at a fast pace so I'm still newbish to alot of these concepts. At this point tho I have no choice I'm heavily committed and need to complete it. When displaying your answer It would be greatly appreciated if you showed your solution in complete form.
It sounds like your local server is running Apache and your remote server is not, as this function only works with Apache (unless the server is running PHP 5.4.0, then it also works under FastCGI.
On the PHP Manual page for this function, one of the commenters included a replacement function that will be declared only if the built-in one doesn't exist. I haven't tested this, but I've seen the same function posted elsewhere.
if( !function_exists('apache_request_headers') ) {
function apache_request_headers() {
$arh = array();
$rx_http = '/\AHTTP_/';
foreach($_SERVER as $key => $val) {
if( preg_match($rx_http, $key) ) {
$arh_key = preg_replace($rx_http, '', $key);
$rx_matches = array();
// do some nasty string manipulations to restore the original letter case
// this should work in most cases
$rx_matches = explode('_', $arh_key);
if( count($rx_matches) > 0 and strlen($arh_key) > 2 ) {
foreach($rx_matches as $ak_key => $ak_val) {
$rx_matches[$ak_key] = ucfirst($ak_val);
}
$arh_key = implode('-', $rx_matches);
}
$arh[$arh_key] = $val;
}
}
return( $arh );
}
}
I found that my site in ISP Config was set to have PHP as 'Fast-CGI' - changing this to 'MOD-PHP' fixed things nicely.
I want a Mirror script which determines whether or not a certain file is accessible or not. If the mirror 1 is accessible, it will present the link to mirror 1. If mirror 1 is not accessible, it will present the link to mirror 2.
This so far is perfect, however I would like more mirrors. For example, if mirror 2 is unavailable, mirror 3 will be presented. If mirror 3 is unavailable, mirror 4 will
be presented and so on. I'm just not quite sure exactly how I could make this work. Has anyone got any suggestions? They would be highly appreciated. I've tried quite a lot of things already!
$mirror1 = "download1.exe";
$mirror2 = "download2.exe";
$header_response = get_headers($mirror1, 1);
if ( strpos( $header_response[0], "404" ) !== false )
{
echo '
Download Mirror 1
';
}
else
{
echo '
Download Mirror 2
';
}
Here's one way to do this:
$mirrors = array("download1.exe","download2.exe","download3.exe");
foreach($mirrors as $mirror) {
$header_response = get_headers($mirror, 1);
if (strpos( $header_response[0], "404" ) === false) {
echo 'Download from '.$mirror.'';
break; //removing break will show all available mirrors
}
}
You could put them all into an array. Then while() the response was === false, array_shift the next one out of the array and use it. Once it's not false, you'll echo the last one that was used.
I have a list of MAC addresses coming from a database. I would like to lookup the vendor for each MAC address and then have a count of devices on network by vendor in the end.
I believe I could do it the dirty way which would be to parse the vendor prefixes from the file available here http://standards.ieee.org/develop/regauth/oui/oui.txt.
But I'm wondering if there is a better way ?
There is a library in Pear, but it does have substantial overhead involved in that the vendor lookup requires a relational database that's been loaded with the vendor data. However, considering the alternative this might be worth exploring.
http://pear.php.net/manual/en/package.networking.net-mac.php
The package provides a loader for the list maintained by wireshark: https://code.wireshark.org/review/gitweb?p=wireshark.git;a=blob_plain;f=manuf
If all you care about is getting the manufacturer of the device based on the mac address then you can simply copy and paste the list on this website here (unto 200 at a time). It's very quick:
www.admin-toolkit.com/mac-address-lookup-manufacturer.html
But I'm wondering if there is a better way ?
If you can use other languages like ruby, there's a gem called macvendors
There is no need to use an external api or get stopped by rate limit.
You can use it from your command line:
gem install macvendors
macvendors find 98:e0:d9:a5:61:eb
Apple, Inc.
You can use it in your ruby code:
require 'macvendors'
MacVendors.setup #for the first time
puts MacVendors.find("98:e0:d9:a5:61:eb")
I have made an SQlite (Macvendors.db) from the Wireshark manuf source. I use it via PDO with a simple query.
Here is a method I write to show you how you could use it:
public function getAllCompaniesFromMacs($macs)
{
try {
// connect to the SQLite file
$conn = new \PDO("sqlite:/path/to/sqlite/Macvendors.db");
$conn ->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
// aux vars
$macsParaBuscar = array();
$macsIN = "";
// output vars
$salida = array();
// Clean repeated MACs and remove the ":" chars
foreach ($macs as $unaMac) {
$unaMac = str_replace(":", "", $unaMac);
$firstChars = substr($unaMac, 0, 6);
$macsParaBuscar[$firstChars] = $firstChars;
}
// Create a IN statment for the WHERE
$macsIN = "( 'HOLA'";
foreach ($macsParaBuscar as $unaMacBuscar) {
$macsIN .= ", '" . $unaMacBuscar . "'";
}
$macsIN .= ")";
// Prepare and execute the query
$stm = $conn->prepare("SELECT mac, vendor FROM macvendor WHERE mac IN " . $macsIN);
$stm->execute();
// Put results in output var
while( $row = $stm->fetch() ) {
$auxMac = $row["mac"];
$salida[$auxMac] = $row["vendor"];
}
return $salida;
} catch (\Exception $e) {
throw new \Exception("Ha ocurrido un error", 1);
}
}
Sorry about the unbeauty example code.
Have fun!
Update
There is another library that doesn't depend on any API but the XML file database which is Cisco vendorMacs.xml
The package is hosted here
Yes here is one I wrote, it depends on the online API of Mac address vendor website
Here is the repository with examples