Localiser une IP en php

Résolu/Fermé
Herve_be Messages postés 1017 Date d'inscription mercredi 4 août 2010 Statut Membre Dernière intervention 25 avril 2024 - 20 juin 2020 à 15:03
Herve_be Messages postés 1017 Date d'inscription mercredi 4 août 2010 Statut Membre Dernière intervention 25 avril 2024 - 29 juin 2020 à 09:36
Bonjour,
Je trouve des réponses sur https://forums.commentcamarche.net/forum/ mais elles ne sont pas récentes; j'en ai essayé quelques unes : soit ça ne fonctionne pas du tout, soit le nombre d'interrogations est limité, ...
Bref, comment obtenir le pays et si possible la ville correspondants à une adresse IP ?
Merci

32 réponses

Herve_be Messages postés 1017 Date d'inscription mercredi 4 août 2010 Statut Membre Dernière intervention 25 avril 2024 8
26 juin 2020 à 18:21
Comme ceci ?
try $record = $reader->city(trim($IP));
catch (Exception $e) echo 'Exception reçue : '. $e->getMessage();
0
yg_be Messages postés 22729 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 26 avril 2024 1 477
26 juin 2020 à 18:35
cela donne quoi comme résultat?
0
Herve_be Messages postés 1017 Date d'inscription mercredi 4 août 2010 Statut Membre Dernière intervention 25 avril 2024 8
26 juin 2020 à 18:59
J'attendais une confirmation avant d'essayer
Mon code initial
	if (filter_var($IP, FILTER_VALIDATE_IP) and $IP <> '0.0.0.0')
		{
		$record = $reader->city(trim($IP));
		$IP = utf8_decode(($record->city->names['fr'] ?? "Ville?")."/".($record->country->names['fr'] ?? "Pays?"));
		}

Code modifié
		Try {$record = $reader->city(trim($IP));}
		catch (Exception $e) {$IP = "IP : ".$IP." ". $e->getMessage();}
		if (substr($IP, 0, 5) !== "IP : ")  $IP = utf8_decode(($record->city->names['fr'] ?? "Ville?")."/".($record->country->names['fr'] ?? "Pays?"));

Ça fonctionne !
Par exemple quand je vais chercher l'IP j'obtiens une erreur "80072F7D Une erreur s’est produite lors de la connexion sécurisée" que je mets dans la DB au lieu de l'IP.
Si j'essaye d'obtenir la localisation sur base de cette valeur qui n'est évidemment pas une IP, j'obtiens bien une exception qui est attrapée et qui ajoute "IP : " devant et le message d'erreur "attrapé" derrière, j'obtiens alors
IP : 80072F7D Une erreur s’est produite lors de la connexion sécurisée The value "80072F7D Une erreur s’est produite lors de la connexion sécurisée" is not a valid IP address.

A combiner autrement parce que a fait bizarre mais c'est correct.
J'arrangerai ça demain.
encore merci :-)
0
Herve_be Messages postés 1017 Date d'inscription mercredi 4 août 2010 Statut Membre Dernière intervention 25 avril 2024 8
27 juin 2020 à 09:20
Bonjour,
Encore une question s'il te plait.
En cas d'erreur il exécute les instructions du bloc catch.
Est-il possible d'exécuter qqch s'il n'y a pas d'erreur ?

Dans le code ci-dessus, en cas d'erreur je mets "IP : ..." dans la variable $IP;
ensuite je teste la variable $IP, si elle ne contient pas "IP : " alors je peux décoder le résultat;
je trouve que ce n'est pas très propre comme code, une meilleure idée ?
0
yg_be Messages postés 22729 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 26 avril 2024 1 477
Modifié le 27 juin 2020 à 10:01
n'est-il pas très simple de tester $record, pour déterminer si il y a eu erreur, ou pas?
en passant, je trouve dommage de réutiliser la variable $IP, au lieu d'utiliser une nouvelle variable.

exemple:
Try {
     $record = $reader->city(trim($IP));
}
catch (Exception $e) {
	$reponse = "IP : ".$IP." ". $e->getMessage();
}
if ( empty($reponse) )  {
	$reponse = 
              utf8_decode(($record->city->names['fr'] ?? "Ville?").
                       "/".($record->country->names['fr'] ?? "Pays?"));
}
0
Herve_be Messages postés 1017 Date d'inscription mercredi 4 août 2010 Statut Membre Dernière intervention 25 avril 2024 8
27 juin 2020 à 10:03
J'utilise la variable $IP plus loin quoi qu'elle contienne, c'est peut-être juste son nom qui est mal choisi.
Entretemps j'ai fait comme ceci
$CatchedError=false;
Try {$record = $reader->city(trim($IP));}
catch (Exception $e) {$CatchedError=true;}
if ($CatchedError)
	{
	$IP = $e->getMessage();
	}
else
	{
	$IP = utf8_decode(($record->city->names['fr'] ?? "Ville?")."/".($record->country->names['fr'] ?? "Pays?"));
	}

Que veux-tu dire par "tester $record" ?
0
yg_be Messages postés 22729 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 26 avril 2024 1 477
27 juin 2020 à 10:13
exemple de test de $record:
if ( empty($record) ) 
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Herve_be Messages postés 1017 Date d'inscription mercredi 4 août 2010 Statut Membre Dernière intervention 25 avril 2024 8
27 juin 2020 à 10:15
Je ne suis pas certain que $record soit vide si $reader rencontre une erreur.
0
Herve_be Messages postés 1017 Date d'inscription mercredi 4 août 2010 Statut Membre Dernière intervention 25 avril 2024 8
27 juin 2020 à 11:07
Bizarrement, avec $record->city->names['fr'] j'ai rarement la ville
avec $record->city->names['en'] pratiquement toujours.
0
Herve_be Messages postés 1017 Date d'inscription mercredi 4 août 2010 Statut Membre Dernière intervention 25 avril 2024 8
28 juin 2020 à 11:06
Je ne parviens pas à obtenir la région
($record->city->names['en'] ?? "Ville?")."/".($record->subdivision->names['fr'] ?? "Region?")."/".($record->country->names['fr'] ?? "Pays?")

donne toujours "Region?"
Où est mon erreur ? Structure de la DB :
            [1] => GeoIp2\Record\Subdivision Object
                (
                    [validAttributes:protected] => Array
                        (
                            [0] => confidence
                            [1] => geonameId
                            [2] => isoCode
                            [3] => names
                        )
                    [locales:GeoIp2\Record\AbstractPlaceRecord:private] => Array
                        (
                            [0] => en
                        )
                    [record:GeoIp2\Record\AbstractRecord:private] => Array
                        (
                            [geoname_id] => 2990129
                            [iso_code] => 59
                            [names] => Array
                                (
                                    [de] => Nord
                                    [en] => North
                                    [es] => Norte
                                    [fr] => Nord
                                )
                        )
                )
0
yg_be Messages postés 22729 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 26 avril 2024 1 477
28 juin 2020 à 11:55
as-tu fait
print_r($record);
?
comment as-tu obtenu la structure que tu nous montres?
0
Herve_be Messages postés 1017 Date d'inscription mercredi 4 août 2010 Statut Membre Dernière intervention 25 avril 2024 8
28 juin 2020 à 12:16
... avec
print_r($record)
mais je n'ai pas mis la structure complète, seulement la partie où je trouve la région.
0
yg_be Messages postés 22729 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 26 avril 2024 1 477
28 juin 2020 à 13:03
eh bien, c'est dans la partie que tu ne montres pas que tu vas probablement trouver la solution à ton soucis.
fais aussi
print_r($record->subdivision->names['fr']);
et
print_r($record->subdivision);
, cela t'aidera peut-être à comprendre.
0
Herve_be Messages postés 1017 Date d'inscription mercredi 4 août 2010 Statut Membre Dernière intervention 25 avril 2024 8
28 juin 2020 à 17:05
print_r($record->subdivision->names['fr']);
donne Uncaught RuntimeException: Unknown attribute: subdivision
print_r($record->subdivision);
donne Uncaught RuntimeException: Unknown attribute: subdivision
ça ne m'aide pas vraiment.
Si j'essaye de copier ici le print_r complet j'obtiens
You don't have permission to access "http://forums.commentcamarche.net/forum/_xhr_/postmsgfrm/" on this server.

Reference #18.8d01f351.1593356617.1f854d61

alors je l'ai sauvé là https://www.rudyv.be/Temp/Structure.txt
0
yg_be Messages postés 22729 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 26 avril 2024 1 477
28 juin 2020 à 17:28
le pense que le message que tu as reçu devrait vraiment t'aider. "Unknown attribute: subdivision": qu'en penses-tu?

voici la partie utile de ton extrait. qu'y vois-tu?
GeoIp2\Model\City Object
(
    [subdivisions:protected] => Array
        (
            [0] => GeoIp2\Record\Subdivision Object
                (
                    [record:GeoIp2\Record\AbstractRecord:private] => Array
                        (
                            [names] => Array
                                (
                                    [en] => Hauts-de-France
                                    [fr] => Hauts-de-France
                                )
                        )
                )
            [1] => GeoIp2\Record\Subdivision Object
                (
                    [record:GeoIp2\Record\AbstractRecord:private] => Array
                        (
                            [names] => Array
                                (
                                    [de] => Nord
                                    [en] => North
                                    [es] => Norte
                                    [fr] => Nord
                                )
                        )
                )
     
0
Herve_be Messages postés 1017 Date d'inscription mercredi 4 août 2010 Statut Membre Dernière intervention 25 avril 2024 8
28 juin 2020 à 17:33
Si tu fais allusion à "protected" pourquoi ai-je bien accès à city ?
GeoIp2\Model\City Object
(
    [city:protected] => GeoIp2\Record\City Object
        (
            [validAttributes:protected] => Array
                (
                    [0] => confidence
                    [1] => geonameId
                    [2] => names
                )
            [locales:GeoIp2\Record\AbstractPlaceRecord:private] => Array
                (
                    [0] => en
                )
            [record:GeoIp2\Record\AbstractRecord:private] => Array
                (
                    [geoname_id] => 3013619
                    [names] => Array
                        (
                            [en] => Hazebrouck
                            [fr] => Hazebrouck
                            [ja] => アーズブルック
                            [ru] => Азбрук
                            [zh-CN] => 阿兹布鲁克
                        )
                )
        )
0
yg_be Messages postés 22729 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 26 avril 2024 1 477
Modifié le 28 juin 2020 à 18:52
dommage, tu n'as pas compris.
le message te dit "subdivision n'existe pas", et je te montre que "subdivisions" existe.
ceci t'aidera sans doute:
print_r($record->subdivisions);
0
Herve_be Messages postés 1017 Date d'inscription mercredi 4 août 2010 Statut Membre Dernière intervention 25 avril 2024 8
28 juin 2020 à 19:12
Si je te suis il faut utiliser
[subdivisions:protected] => Array
(avec s) qui contient 2 niveaux
[0] => GeoIp2\Record\Subdivision Object
[1] => GeoIp2\Record\Subdivision Object
le second [1] contient le nom que je cherche, cependant je ne connais pas l'utilisation de ces arrays complexes, comment aller chercher names['fr'] ?
            [1] => GeoIp2\Record\Subdivision Object
                (
                    [validAttributes:protected] => Array
                        (
                            [0] => confidence
                            [1] => geonameId
                            [2] => isoCode
                            [3] => names
                        )
                    [locales:GeoIp2\Record\AbstractPlaceRecord:private] => Array
                        (
                            [0] => en
                        )
                    [record:GeoIp2\Record\AbstractRecord:private] => Array
                        (
                            [geoname_id] => 2990129
                            [iso_code] => 59
                            [names] => Array
                                (
                                    [de] => Nord
                                    [en] => North
                                    [es] => Norte
                                    [fr] => Nord
                                )
                        )
                )
0
yg_be Messages postés 22729 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 26 avril 2024 1 477
28 juin 2020 à 20:33
ne serait-ce pas beaucoup plus clair si tu montrais quelle instruction tu utilises pour obtenir ce que tu partages? en plus, tu supprimes chaque fois, avant de partager, la partie utile.
essaie peut-être
print_r($record->subdivisions[1]);

il ne s'agit pas d'array complexes. as-tu déjà utilisé des array en php?
peux-être pourrais-tu commencer par des exercices plus simples en php?
0
Herve_be Messages postés 1017 Date d'inscription mercredi 4 août 2010 Statut Membre Dernière intervention 25 avril 2024 8
Modifié le 29 juin 2020 à 09:47
Bonjour,
Pour obtenir ce que je montre j'utilise
print_r($record);

Je ne parviens pas à coller le résultat complet sur ce forum, alors j'ai mis la totalité du résultat de print_r dans ce fichier https://www.rudyv.be/Temp/Structure.txt

print_r($record->subdivisions[1]);
donne le résultat ci-dessous
j'ai donc compris que je dois utiliser
$record->subdivisions[1]->names['fr']
: ça fonctionne !
Merci beaucoup

GeoIp2\Record\Subdivision Object
(
    [validAttributes:protected] => Array
        (
            [0] => confidence
            [1] => geonameId
            [2] => isoCode
            [3] => names
        )
    [locales:GeoIp2\Record\AbstractPlaceRecord:private] => Array
        (
            [0] => en
        )
    [record:GeoIp2\Record\AbstractRecord:private] => Array
        (
            [geoname_id] => 2796741
            [iso_code] => WHT
            [names] => Array
                (
                    [de] => Provinz Hennegau
                    [en] => Hainaut Province
                    [fr] => Hainaut
                    [pt-BR] => Hainaut
                )
        )
)
0