• Das Erstellen neuer Accounts wurde ausgesetzt. Bei berechtigtem Interesse bitte Kontaktaufnahme über die üblichen Wege. Beste Grüße der Admin

[FRAGE] Problem mit Geolocationscript

schlegel.berlin

New member
Liebe Leute,

nun bin ich kaum wieder zuhause, habe ich schon wieder ein Problem.
Das nachstehend gepostete Script läuft wie gewünscht, aber NUR wenn ich es unter Apache auf meine Rechner aurfufe (natürlich während er online ist).
Es liefert dann folgendes Ergebnis (mit einer zu Testzwecken fest vorgegebenen IP, die sonst über $_SERVER['REMOTE_ADDR'] ermittelt wird).

IP: xx.xx.xxx.xxx
Stadt: Berlin
Region: Berlin
Land: Germany
Länderkürzel: DE
Längengrad: 13.4
Breitengrad: 52.516701


Lade ich es auf den Server hoch, liefert das gleiche Script dort folgendes Ergebnis (die Variablen sind leer):
IP: xx.xx.xxx.xxx
Stadt:
Region:
Land:
Länderkürzel:
Längengrad:
Breitengrad:


Anmerkung: Wie man aus der 'geoplugin.class.php' ersehen kann, liefert der GeoPlugin-Server noch weitere Viarablen, die ich aber nicht benötige.

Nun hofe ich, das jemand von Euch eine Idee hat, WO das Problem liegt. Ich blick's im Moment überhaupt nicht ...

Liebe Grüße, Karin

Hier das Script:
PHP:
<?php

require_once('geoplugin.class.php');

$geoplugin = new geoPlugin();

$geoplugin->locate();

echo "IP: {$geoplugin->ip}: <br />\n".
	"Stadt: {$geoplugin->city} <br />\n".
	"Region: {$geoplugin->region} <br />\n".
	"Land: {$geoplugin->countryName} <br />\n".
	"Länderkürzel: {$geoplugin->countryCode} <br />\n".
	"Längengrad: {$geoplugin->longitude} <br />\n".
	"Breitengrad: {$geoplugin->latitude} <br />\n";

?>

Und hier die 'geoplugin.class.php':
PHP:
<?php

class geoPlugin {
	
	//the geoPlugin server
	var $host = 'http://www.geoplugin.net/php.gp?ip={IP}&base_currency={CURRENCY}';
		
	//the default base currency
	var $currency = 'USD';
	
	//initiate the geoPlugin vars
	var $ip = null;
	var $city = null;
	var $region = null;
	var $areaCode = null;
	var $dmaCode = null;
	var $countryCode = null;
	var $countryName = null;
	var $continentCode = null;
	var $latitude = null;
	var $longitude = null;
	var $currencyCode = null;
	var $currencySymbol = null;
	var $currencyConverter = null;
	
	function geoPlugin() {

	}
	
	function locate($ip = null) {
		
		global $_SERVER;
		
		if ( is_null( $ip ) ) {
			$ip = $_SERVER['REMOTE_ADDR'];
		}
		
/* ======  ACHTUNG: Nachstehend habe ich testweise MEINE monmentane IP Adresse angegeben ===== */
		$ip ="91.65.230.213";  
/* =========================================================================================== */

		$host = str_replace( '{IP}', $ip, $this->host );
		$host = str_replace( '{CURRENCY}', $this->currency, $host );
		
		$data = array();
		
		$response = $this->fetch($host);
		
		$data = unserialize($response);
		
		//set the geoPlugin vars
		$this->ip = $ip;
		$this->city = $data['geoplugin_city'];
		$this->region = $data['geoplugin_region'];
		$this->areaCode = $data['geoplugin_areaCode'];
		$this->dmaCode = $data['geoplugin_dmaCode'];
		$this->countryCode = $data['geoplugin_countryCode'];
		$this->countryName = $data['geoplugin_countryName'];
		$this->continentCode = $data['geoplugin_continentCode'];
		$this->latitude = $data['geoplugin_latitude'];
		$this->longitude = $data['geoplugin_longitude'];
		$this->currencyCode = $data['geoplugin_currencyCode'];
		$this->currencySymbol = $data['geoplugin_currencySymbol'];
		$this->currencyConverter = $data['geoplugin_currencyConverter'];
		
	}
	
	function fetch($host) {

		if ( function_exists('curl_init') ) {
						
			//use cURL to fetch data
			$ch = curl_init();
			curl_setopt($ch, CURLOPT_URL, $host);
			curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
			curl_setopt($ch, CURLOPT_USERAGENT, 'geoPlugin PHP Class v1.0');
			$response = curl_exec($ch);
			curl_close ($ch);
			
		} else if ( ini_get('allow_url_fopen') ) {
			
			//fall back to fopen()
			$response = file_get_contents($host, 'r');
			
		} else {

			trigger_error ('geoPlugin class Error: Cannot retrieve data. Either compile PHP with cURL support or enable allow_url_fopen in php.ini ', E_USER_ERROR);
			return;
		
		}
		
		return $response;
	}
	
	function convert($amount, $float=2, $symbol=true) {
		
		//easily convert amounts to geolocated currency.
		if ( !is_numeric($this->currencyConverter) || $this->currencyConverter == 0 ) {
			trigger_error('geoPlugin class Notice: currencyConverter has no value.', E_USER_NOTICE);
			return $amount;
		}
		if ( !is_numeric($amount) ) {
			trigger_error ('geoPlugin class Warning: The amount passed to geoPlugin::convert is not numeric.', E_USER_WARNING);
			return $amount;
		}
		if ( $symbol === true ) {
			return $this->currencySymbol . round( ($amount * $this->currencyConverter), $float );
		} else {
			return round( ($amount * $this->currencyConverter), $float );
		}
	}
	
	function nearby($radius=10, $limit=null) {

		if ( !is_numeric($this->latitude) || !is_numeric($this->longitude) ) {
			trigger_error ('geoPlugin class Warning: Incorrect latitude or longitude values.', E_USER_NOTICE);
			return array( array() );
		}
		
		$host = "http://www.geoplugin.net/extras/nearby.gp?lat=" . $this->latitude . "&long=" . $this->longitude . "&radius={$radius}";
		
		if ( is_numeric($limit) )
			$host .= "&limit={$limit}";
			
		return unserialize( $this->fetch($host) );

	}

	
}

?>
 
Zuletzt bearbeitet von einem Moderator:
Ich nehme an, das PHP Plugin bekommt vom Client nicht die nötigen Infos, um damit einen Standort zu ermitteln. Wo landen denn die Fehlermeldungen des Plugins aus dem Aufruf von trigger_error()?
 
Du könntest auch das Debug-Skript von jspit ausprobieren: Debug - Simple PHP Debug Class. Hat mir schonmal geholfen, als keine Fehlermeldungen angezeigt wurden.
Füge dazu vor deinem Skript folgende Zeilen hinzu
PHP:
ini_set('display_errors', 'Off');
error_reporting(-1);

require 'class.debug.php';
debug::log('log.html',true);
debug::write('start:  ',__FILE__);
, danach findest du im selben Ordner die Logdatei "log.html".

PS: wäre das hier was für dich?
 
Zuletzt bearbeitet:
Hallo meine Lieben,

erst mal vielen Dank für die guten Antworten

Also, folgendes kann ich schon mal sagen:
1. es enstehen keine Fehlermeldungenm weshalb ich ja auch ein Problem habe einen Fehler zu finden
2. Ich habe das mit 'class.debug.php' eben versucht. Es gibt auch keine Fehlmeldungen zurück
3. 'allow_url_fopen' ist auf dem Server aktiv
4. API für Infos über eine IPv6-Adresse ist leider keine Option für mich
5. Ich habe das Script vorhin auf den Server eines Freundes in Südtirol hochgeladen (mit meiner IP-Adresse im Script). Dort funktioniert es : htp://www.frommeralm.it/_test/geolocation.php


Wenn jemand eine andere, gute Idee hat, wie ich an die gewünschten Geolocation-Daten kommen und dafür eien Scriptlösung hat, würde ich irre freuen. Ich muss das ja nicht zwangsweise über den Weg machen, den ich als Problemfall gepostet habe.

Und jetzt bin ich 1. mal weg und 2. wünsche ich Euch allen einen herzzerreissend schönen Tag,
LG, Karin
 
Zuletzt bearbeitet:
Ja Moment, die fest im Script vorgegebene IP hattest du ja auf deinem Rechner lokal auch, wo es funktioniert hat. Was also sollte der Server des Freundes an neuen Erkenntnissen bringen? Das es mit fester IP geht wussten wir ja vorher schon. Die Frage ist, in welcher Konstellation funktioniert es wie gewünscht, also mit der IP des Clients? Wenn man das weiß kann man ganz strukturiert die Unterschiede zwischen dem funktionierenden System und dem gewünschten Zielsystem suchen.
 
Warum greifst du auf eine Klasse zurück, welche dich von einem fixen Webservice abhängig macht? Hab damit keine guten Erfahrungen gemacht. Irgendwann wird der Service eingestellt, und du fängst von vorne an.
Nimm einen Webservice, welcher dir die Antwort als JSON-String liefert (z.B. wie hier von julian).

Mit wenigen Zeilen hast du deine Informationen in einem Array:
PHP:
$ip = "xx.xx.xxx.xxx";

$json = file_get_contents("http://ipinfo.io/".$ip."/json"); 
$array = json_decode($json, true);
var_dump($array);

Wenn es eine Klasse sein soll, dann sollte diese möglichst unabhängig von einen bestimmten Webservice arbeiten.
Ist nicht so schwer, so etwas selbst zu machen oder eine zu finden, bei welcher URL und Zuordnungen bei der Objekterstellung mtgeliefert werden können.

LG jspit
 
Zuletzt bearbeitet von einem Moderator:
Du könntest unter das
PHP:
        $response = $this->fetch($host);
mal ein
PHP:
var_dump($response);
einfügen und sehen, ob du vom Server überhaupt was bekommst.
Wenn da eine Fehler oder gar nichts drin ist, musst du zuerst feststellen, ob in der fetch()-Methode über cURL oder file_get_contents() gegangen wird.
Bei cURL kann man dann mit curl_errno() bzw. curl_error() näheres zum Fehler rausfinden.
 
Halo Ihr Lieben,

musste grad wieder mal kurz aus Berlin weg (wg. Reha) und bin (voraussichtlich) erst kommende Woch ab Dienstag wieder zuhause.
Vorherr hab ich keine rechte Möglchkeit, was zu machen.
Ich möchte michaber wenisgstens erst mal einfach für Eure Hilfe bedanken und melde mich, sobald ich Eure Vorschläge befolgend Ergebnisse zu berichten habe...

LG, Karin
 
Bin wieder da. Das war nix mit der REHA. Also bin ich dort "abgehauen" ... :)

So, jetzt zur Sache:

Zu dem Tipp von kkapsner:
Das hatte ich schon gemacht und festgestellt, dass das Array eben keine Variablen enthält. Aber eben nur auf dem Server bei STRATO. Auf anderen Servern hatte es ja funktioniert.
Nach dem einige Telefonat mit der Technikhotline von STRATO nicht zu einem verwertbaren Ergebnis führte, habe ich das Problem jetzt anders gelöst (auf der Grundlage des Tipps von jspit und auf die Schnelle. Werde das Script aber noch etwas "zusammenstreichen". Das ist jetzt einfach so mit ’loser’ Hand entstanden").

Es wird aber eventuell wieder einigen newbies helfen können, ihre Erkenntnisse zu mehren :)
Hier noch mal kurz die Aufgabenstellung (eigentlich nur eine Übung - schließlich gibt's ja Google Analytics - aber vielleicht kann's jemand brauchen):

Die Aufgabe war ein Script...

a) ... das Besucher erfasst mit Datum, Uhrzeit, IP und diversen Geolocationdaten (Ort, Land, geografische Breit u.Länge).

b) ... die erfassten Daten in eine kleine Tabelle schreibt und diese in einer Textdatei speichert. Dabei doll die generierte Tabelle an in der Textdatei bereits vorhandenen Tabellen "angehängt" werden (Die Styleanweisungen für die Tabelle habe ich ins Script geschrieben).

c) die so entstandene Textdatei soll dann ausgelesen werden und einen Link zu GooglerMaps enthalten, der als Variablen die geografische Länge und Breite übergibt. Mit einem Klick auf diesen Link soll dann in einem sich öffnenden Fenster der ungefähre Standort des Besuchers in Googler Maps angezeigt werden.

Das nachstehende gepostete Script (_geolocatio.php) wird dabei in die index-date auf dem Server eingebunden (include '_geolocation.php';)

Mit dem als nächstes geposteten Script wird ie Textdatei ausgelesen und die aneinander gereiten Tabellen ausgegeben (absteigend sortiert, neustes Datum also oben.)

Hier das geolocation script:
PHP:
<?
//Aktuelles Datum und aktuelle Zeit ermitteln
$datum = date("d.m.Y"); 
$uhrzeit = date("H:i");


$ip = $_SERVER['REMOTE_ADDR'];

$json = file_get_contents("http://ipinfo.io/".$ip."/json");  
$geo_variablen = json_decode($json, true); 

// Vriablen werden aus dem Array_1 ausgelesen
$IP = $geo_variablen['ip'];
$host = $geo_variablen['hostname'];
if($host == "No Hostname"){$host = "(Host nicht ermittelbar)";}
if($host == ""){$host = "(Host nicht ermittelbar)";}
$city = $geo_variablen['city'];
if($city == ""){$city = "(bitte auf den Google Link klicken)";}
$country = $geo_variablen['country'];
$location = $geo_variablen['loc'];

//Längen- und Breitengrad
$geloc_values = $location;
$geloc_values_array = explode(',', $geloc_values);

$latitude = $geloc_values_array[0];
$longitude = $geloc_values_array[1];

//jetzt wird eine Tabelle generiert, die alle gewünschetn Variablen aus dem Array_1 enthält
$logdaten = '<table width="100%" cellpadding="1" cellspacing="1" class="content" style="margin-top:10px;border: dotted 1px black" bgcolor="#BBBBBB"><tr><td>Besuchszeit: </td><td>'.$datum .' - '.$uhrzeit .' Uhr</td></tr><tr bgcolor="white"><td width="78">IP-Adresse: </td><td>'.$IP .'</td></tr><tr bgcolor="white"><td>Host: </td><td>'.$host.'</td></tr><tr bgcolor="white"><td>Ort: </td><td>'.$city.'</td></tr><tr bgcolor="white"><td>Land: </td><td>'.$country.'</td></tr><tr bgcolor="white"><td colspan="2">Standortkoordinaten</td></tr><tr bgcolor="white"><td>Längengrad:</td><td>'.$longitude.'</td></tr><tr bgcolor="white"><td>Breitengrad:</td><td>'.$latitude.'</td></tr><tr bgcolor="white"><td>Geografisch: </td><td><a href="https://maps.google.com/maps?q='.$latitude.','.$longitude.'&&z=11" target="_blank">Standort in Google Maps</a></td></tr></table>';

//Jetzt wird die Tabelle in einer Textdatei gespeichert und zwar an in der Datei eventuell bereits vorhande Tabellen "angehängt" [I](kann man auch einfacher schreiben)...[/I]
$datei = file("log/besucher.txt"); 
foreach($datei AS $old) { } 
$logdaten = $logdaten." ".$old;
$filename = 'log/besucher.txt';
if (is_writable($filename)) {
if (!$handle = fopen($filename, "w")) {
print "Kann die Datei $filename nicht öffnen";
exit;
}
if (!fwrite($handle, $logdaten)) {
print "Kann in die Datei $filename nicht schreiben";
exit;
}
fclose($handle);
} else {
print "Die Datei ".$filename." ist nicht schreibbar";
}
?>

Und jetzt die Ausgabe (die Datei kann man auch einfacher auslesen):
PHP:
<?
$rows_ge = file('../log/besucher.txt');
if (is_array ($rows_ge))
{ 
foreach ($rows_ge as $row_ge)
{
$values_ge = explode ("|", $row_ge);
$log_list = stripslashes($values_ge[0]);
}
}

echo $log_list; 
?>

Wie ich schon schrieb, werde ich die Scripte noch 'redigieren'. Aber vielleicht können 'nebies' was draus lernen können, so hoffe ich ...

LG, Karin

PS: Das Script habe ich natürlich getestet und es funzt bestens. AUCH bei STRATO ...
 
Zuletzt bearbeitet:
Ein paar kleine Kommentare:
1. eine gescheite Einrückung würde dem Code nicht schaden... macht ihn viel lesbarer.
2. file_get_contents() ist eine bessere Methode um eine komplette Datei in einen String zu lesen als mit file() das Ganze zeilenweise zu bekommen und dann wieder zusammenzubauen.
3. und genau beim zusammenbauen hast du einen kleinen Fehler (der mit Codeeinrückung schneller zu finden ist):
PHP:
foreach($datei AS $old) { } 
$logdaten = $logdaten." ".$old; [/code] - die zweite Zeile sollte wohl in den foreach-Block und nicht danach...
4. implode() ist schneller, wenn man einen Array von Strings zusammenbauen will...
5. aber [inline]fopen($filename, "a")[/inline] ist viel effizienter als die komplette Datei einzulesen und wieder komplett neu zu schreiben.

[SIZE=1]- - - Aktualisiert - - -[/SIZE]

EDIT: oh - da sehe ich gerade, dass du das neue va [b]vorne[/b] anhängen willst... das geht mit dem "a" Flag natürlich nicht...
 
Guten Morgen,

ich versuche ein wenig zu helfen, indem ich ein paar Fragen stelle, die mir hier im Thread nicht beantwortet scheinen:

[ 1. ] Ist die benutzte Klasse durchgängig "kostenfrei" oder erkennt diese den Unterschied zwischen "localhost" und "Live-Betrieb"?

[ 2. ] Ist der Browser, mit dem die unterschiedlichen Ergebnisse getestet wurden, exakt gleich? (Anspielung auf mögliche Settings zur Wahrung der Privatsphäre, Nichtverfolgung usw.)

[ 3. ] Ist der Provider gleich oder schiebt sich was dazwischen (bspw. Proxy)? Weicht der Anfrage-Header ab, ändert der Server was (würde bei einem 301/302 (pfui!) aufgrund SEO an der Live-Seite eine benötigte Info verloren gehen?)?

[ 4. ] Sind die Testsysteme sauber (kein Routing aufgrund Malware, Toolbar etc.)?

[ 5. ] Könnte es ein Plugin im Browser sein, welches diese Informationen "frisst"? (bspw. "disconnect")

[ 6. ] Welche Daten liefert ein anderer Browser am gleichen System beim gleichen Provider?

Und wenn ihr mir eine kleine Spitze während meines Kaffees erlaubt: Der Quellcode verträgt mehr als nur eine Einrückung ... :D

Viele Grüße
 
Zu 2. eine IP Adresse muss immer beim Server ankommen, da dieser sonst nicht weiß, wohin er die Antwort zurückschicken soll. Wenn man einen VPN oder Proxy verwendet kann das natürlich eine andere als die "wirkliche" sein. Aber dann ist es die IP-Adresse des VPN-Servers oder des Proxys.
Zu 4. und 5. das Problem ist doch, dass der Strato-Server keine Daten vom geoplugin-Server bekommt... das hat doch nichts mit dem Clientsystem zu tun.
 
Hi kkapsner,

Du hast (quasi) mit allem Recht. Ich schrieb ja bereizs, dass der Code noch verbesserungswürdig ist.
Ich hatte ihn wirklich mit der heißen Nadel "gestrickt" und daher entstand in der Folge halt ein kleiner "Wildwuchs".
Dass ich den Code nicht "einrückte", sorry, aber auch da war die heiße Nadel ursächlich...
Ich dachte mit halt, besser so "unfertig" schnell gepostet, als übehaupt nicht :)

Es wäre ja vielleicht auch eine Idee, dass irgendjemand im Forum, den Quellcode nicht nur (auskommentiert) verbessert und dann die Zeilen zur besseren Lesbarkeit auch gleich noch einrückt.
Dann könnten nämlich "newbies" aus dem "Verbesserungs-Schritt" was dazulernen ...

Um's mal drastisch auszudrücken:
Es ist evntuell für die/den eine/n oder andere/n lehrreich, zu sehen, wie auch "Scheiße" "Gold" wird .... :)

Schöne Pfingsten Euch allen, ich bin dann mal wiederweg für einige Tage.
LG, Karin
 
@kkapsner: zu Deiner ...
2: Richtig, allerdings könnte dieser Proxy die eine oder andere Information ändern/erweitern, wodurch das GEO-Script "komisch" (cases, defaults, if's) wird und andere Dinge meint machen zu müssen (die Krux mit Drittanbietern).
4+5: Verwende ich (ohne Proxy) Möchte-gern-Verschlüsselungen (da gibt es genügend Plugins zwecks "anonym surfen" etc.), verwende ich von irgendwem die Leitung - ich kriege zwar meine Antwort, doch muss das GEO-Script genau diese IP-Adresse (= Datenbestand; extern - nicht meine interne vor dem Plugin) auch handhaben können; ansonsten liefere ich "" (nix) zurück. Ich habe selbst so ein Script, welches IP-Ranges vergleicht, damit bspw. niemand auf die Idee kommt, Domainabfragen in Fernost oder Übersee zu machen (zu performance-lastig). Ich verspreche, dass bei den IP-Adressen ziemlich Bewegung ist, wem ein Range zugesprochen wird etc. (= reger Handel). Man muss förmlich seine Daten aktuell halten. Was also gestern bspw. noch im Mobilfunknetz von Voda**** lag, ist morgen Teil eines chinesischen Telekommunikationsanbieters (ich habe hier selbst mehr als 135k Zuweisungen dieser Art; sogar mein Datenbestand ist schon zu alt).

Ebenfalls schöne Pfingsten und zum Glück spielt das Wetter hier bei mir wohl mit ...
 
Zurück
Oben