Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: PHP: Sivun kustomointi käyttäjän sijainnin perusteella PHP

Sivun loppuun

hevonen [06.03.2009 13:46:03]

#

Ongelma: kustomoida internet sivu suomalaisille ja muulle maailmalle geolokaation mukaan PHP:llä. Eli vain suomalaiset saavat sivulla erikoiskohtelun.

Tiedon murusia, joita mahdollisesti tarvitaan:
1. $_SERVER['REMOTE_ADDR']
2. Suomen IP osoitteet: en ole varma tästä

Pseudokoodi:

$luo-taulukko
$lataa suomen ip-osoitteet tauluun viikoittain täältä: http://software77.net/cgi-bin/ip-country/geo-ip.pl

if $_SERVER['REMOTE_ADDR'] == [suomi-ip-osoitteet]
   do-thisA
else
   do-thisB

Miten ratkaisisit ongelman?

kinnala [06.03.2009 14:14:28]

#

Ei taida olla ihan noin yksinkertaista, että IP-osoitteen formaatista näkisi suoraan mistä maasta on. Tarttee jonkinnäkösen tietokannan. Nopeella googletuksella löysin tällaisen:
http://software77.net/cgi-bin/ip-country/geo-ip.pl

hevonen [06.03.2009 14:30:24]

#

kinnala kirjoitti:

Ei taida olla ihan noin yksinkertaista, että IP-osoitteen formaatista näkisi suoraan mistä maasta on. Tarttee jonkinnäkösen tietokannan. Nopeella googletuksella löysin tällaisen:
http://software77.net/cgi-bin/ip-country/geo-ip.pl

Olet oikeassa.
Ongelma on vaativampi.
Muutin aloitusviestiäni.

Blaze [06.03.2009 14:35:19]

#

hevonen kirjoitti:

Miten ratkaisisit ongelman?

<h1>Mistä oot?</h1>
<a href="suomi.html">Suomesta</a>
<a href="muut.html">muualta</a>

kinnala [06.03.2009 15:00:23]

#

Kirjotinpa ton huvikseni. Eli siis tarvitsee tuolta sivuilta ladattavan IpToCountry.csv -tiedoston.

Aja tämä ensin ja copypastee sen tuloste IpToCountry.csv:hen. Parsii pois kaikki ulkomaiset IP:t. (Käsittääkseni oli siis tarkoitus tunnistaa onko IP Suomesta vai muualta?)

<?php

$handle = @fopen("IpToCountry.csv", "r");
while(!feof($handle))
{
	$buffer = fgets($handle, 4096);
	$tmp = explode(",",$buffer);
	if($tmp[4]=="\"FI\"") echo $buffer."<br />";
}

?>

Ja sitten tämä hoitaa loput:

<?php

$ip = $_SERVER['REMOTE_ADDR'];
$ip = explode(".",$ip);
$ip = $ip[3]+$ip[2]*256+$ip[1]*256*256+$ip[0]*256*256*256;
$handle = @fopen("IpToCountry.csv", "r");
$finland = false;
while(!feof($handle))
{
	$buffer = fgets($handle, 4096);
	$tmp = explode(",",$buffer);
	$from = (int)trim($tmp[0],"\"");
	$to = (int)trim($tmp[1],"\"");
	if($ip >= $from && $ip <= $to)
	{
		$finland = true;
		break;
	}
}
fclose($handle);

if($finland) echo "Tervetuloa!";
else echo "Welcome!";

?>

Toimii periaatteessa suoraan alkuperäiseen tietokantaankin, mutta on vaan onnettoman hidas.

Tuon tietokannan viikottaisen hakemisen ja parsimisen voi hoitaa vaikka cronilla. Ja tosiaankin olisi tietenkin järkevämpää parsia tuosta kaikki muukin turha pois (eikä pelkästään turhia rivejä), mutta tuo nyt on lähinnä nopee viritys.

hevonen [06.03.2009 16:06:40]

#

kinnala kirjoitti:

Ja sitten tämä hoitaa loput:

<?php

$ip = $_SERVER['REMOTE_ADDR'];
$ip = explode(".",$ip);
$ip = $ip[3]+$ip[2]*256+$ip[1]*256*256+$ip[0]*256*256*256;
$handle = @fopen("IpToCountry.csv", "r");
$finland = false;
while(!feof($handle))
{
	$buffer = fgets($handle, 4096);
	$tmp = explode(",",$buffer);
	$from = (int)trim($tmp[0],"\"");
	$to = (int)trim($tmp[1],"\"");
	if($ip >= $from && $ip <= $to)
	{
		$finland = true;
		break;
	}
}
fclose($handle);

if($finland) echo "Tervetuloa!";
else echo "Welcome!";

?>

Tein csv-filen Suomi-ip:stä: http://dl.getdropbox.com/u/175564/ip.csv . Muutin tiedoston nimen oikeaksi.
Testasin tuota koodia proxy.com -sivuston kautta onnistumatta.
Muu maailma näki saman kuin suomalaiset.

kinnala [06.03.2009 16:21:34]

#

Tuon .csv-tiedoston formaatti pitäisi olla muuten täsmälleen sama kuin alkuperäisen tietokannan, mutta ulkomaita koskevat rivit poistettuina. Sulla on tossa vaan noita IP-osoitteita listattu pilkulla erotettuna.

Tässä pätkä omaa tiedostoani:

"1043120128","1043136511","RIPE","1008720000","FI","FIN","FINLAND"
"1044201472","1044217855","RIPE","991785600","FI","FIN","FINLAND"
"1044840448","1044905983","RIPE","987638400","FI","FIN","FINLAND"
...

Ja jos haluat, niin voit tietekin säilyttää pelkät IP-osoitteet tähän malliin:

1043120128,1043136511
1044201472,1044217855
1044840448,1044905983
...

Pitäisi toimia ilman koodin muokkaamista, en kyllä testannut. Jos näin teet, niin nuo trimit voi ottaa pois. Alueet pitää kuitenkin olla omilla riveillään.

ville-v [06.03.2009 18:11:55]

#

Jos haluat vain tunnistaa suomalaiset, käytä vaikka

if(ereg("fi", $_SERVER["HTTP_ACCEPT_LANGUAGE"]))

hevonen [06.03.2009 21:22:38]

#

ville-v kirjoitti:

Jos haluat vain tunnistaa suomalaiset, käytä vaikka

if(ereg("fi", $_SERVER["HTTP_ACCEPT_LANGUAGE"]))

Tuo koodi luultavasti toimii niin, että katsotaan käyttäjän selaimen kieli. Näin päätetään suoritettava koodi. Näin vältytään myös ilmeisesti IP-osoitteiden keräämiseltä.

Tarkoitatko esimerkiksi näin

<?php

if(ereg("fi", $_SERVER["HTTP_ACCEPT_LANGUAGE"]))
   include('http://sivu.com/suomi.txt');
else
   include('http://sivu.com/muuMaailma.txt');

?>

?

Suoritan eri koodit suomalaisille ja muulle maailmalle.

[edit]

Kieli näkyy koko ajan suomena, vaikka selaimen ja käyttiksen kielet ovat eri kuin suomi.

hevonen [06.03.2009 23:16:41]

#

Ongelma ratkaistu

<?php

  if(preg_match('/fi/i', $_SERVER['HTTP_USER_AGENT']))
    include('http://sivu.com/suomi.txt');
  else
    include('http://sivu.com/muuMaailma.txt');

?>

trilog [06.03.2009 23:25:07]

#

hevonen kirjoitti:

Ongelma ratkaistu

Aika huono ratkaisu, nimittäin tuo nappaa kaikki kenellä on esim. Firefox user agenttina.

<?php
$m = NULL;
echo (preg_match("/fi/i", "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.0.3) Gecko/2008092417 Firefox/3.0.3", $m) ? "match" : "none")."<br />";
print_r($m);

/*
match
Array
(
    [0] => Fi
)

*/
?>

Metabolix [06.03.2009 23:46:58]

#

trilog kirjoitti:

Tuo nappaa kaikki kenellä on esim. Firefox user agenttina.

Lisäksi se jättää huomioimatta monet niistä, jotka eivät käytä suomenkielistä selainta. Tämä näkyy myös trilogin esimerkissä, vaikka siinä Firefox kielestä (en-US) huolimatta tuottaakin virheellisen osuman.

hevonen [07.03.2009 13:32:48]

#

Metabolix kirjoitti:

trilog kirjoitti:

Tuo nappaa kaikki kenellä on esim. Firefox user agenttina.

Lisäksi se jättää huomioimatta monet niistä, jotka eivät käytä suomenkielistä selainta. Tämä näkyy myös trilogin esimerkissä, vaikka siinä Firefox kielestä (en-US) huolimatta tuottaakin virheellisen osuman.

Seuraavan koodin pitaisi toimia paremmin

<?php

  if(preg_match('/fi/i', $_SERVER['HTTP_ACCEPT_LANGUAGE']))
    include('http://sivu.com/suomi.txt');
  else
    include('http://sivu.com/muuMaailma.txt');

?>

Nyt valitaan kieli selaimen kieliasetuksen mukaan.

TsaTsaTsaa [09.03.2009 17:53:42]

#

Kuten jo sanottu, moni käyttää selainta esim. englanninkielisenä, eli tuo ei ole hyvä ratkaisu.

ajv [09.03.2009 18:24:39]

#

TsaTsaTsaa kirjoitti:

Kuten jo sanottu, moni käyttää selainta esim. englanninkielisenä, eli tuo ei ole hyvä ratkaisu.

Riippuu vähän mitä tässä ollaan tekemässä. Jos todella halutaan antaa eri sisältö ip-osoitteen sijainnin mukaan, niin tuo ei toimi. Jos halutaan antaa eri(kielinen) sisältö sen mukaan mitä käyttäjä pyytää, niin tuo on se oikea tapa. Ei englanninkielinen selain automaattisesti tarkoita, etteikö selain voisi pyytää sivua suomen kielellä. Ainakin itsellä selain - kuten kaikki muutkin ohjelmat - ovat yleensä englanninkielisiä, mutta ff:n languages-määrityksissä on oletuskieleksi kuitenkin valittu suomi.

ajv [09.03.2009 22:16:49]

#

Tarkennan (loivennan) tuota edellistä kommenttiani vielä sen verran, että HTTP_ACCEPT_LANGUAGE-otsaketietoon ei voi sokeasti luottaa. Tuon perusteella voi minun mielestä tarjoilla oletuskieltä, mutta käytettävyyden nimissä kielivalinta täytyy edelleen olla hyvin esillä.


Sivun alkuun

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta