[PHP] Dubbele ip's en ip masks in een array

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • niels_999348
  • Registratie: Maart 2003
  • Laatst online: 20-09 08:10
Mijn volgende probleem,
Ik heb hier een database die vol zit met ip's van de bezoekers. Nu wil ik dit doen:
1. De ip's uit de database halen.
2. Ze omzetten dus 80.100.23.4 -> 80.100 etc.
3. De dubbelen er dan tussen uit halen
4. Alle omgezette ip's zonder dubbelen naar 't scherm toe echo'en.

Nu weet ik hoe ik ze uit de database kan halen, ik heb niet echt een idee hoe ik de ip's kan omzetten. Ja, met regular expressions maar das niet mijn beste kant :P . De dubbelen er tussen uit halen in een array heb ik geen flauw idee van. Googelen heeft ook al niet erg veel opgelevert.
En naar 't scherm toe printen dat kan ik wel ;)
Dus of jullie ideen hebben hoe ik de ip's kan omzetten als ik ze vanuit mysql krijg en dan de dubbelen er tussen uit halen

Acties:
  • 0 Henk 'm!

  • Cavorka
  • Registratie: April 2003
  • Laatst online: 27-03-2018

Cavorka

Internet Entrepreneur

the-blueprints.com - The largest free blueprint collection on the internet: 50000+ drawings.


Acties:
  • 0 Henk 'm!

  • niels_999348
  • Registratie: Maart 2003
  • Laatst online: 20-09 08:10
:o
stom dat ik dat niet zelf gevonden had komt vast door mijn zoek acties op doubles in array :P

code:
1
2
$input = $changed_mysql;
$result = array_unique ($input);

dan heb ik voor die dubbelen m'n oplossing moet ik alleen nog iets hebben om de ip's te veranderen in mijn array die ik vanuit mysql krijg en dan ben ik weer tevreden :)
edit:
even dat progje testen :) ik zeg 't wel als ik er uitkom :)

[ Voor 8% gewijzigd door niels_999348 op 12-06-2005 15:25 ]


Acties:
  • 0 Henk 'm!

  • T-MOB
  • Registratie: Maart 2001
  • Laatst online: 16:36
Op zich heb je niet per sé een regex nodig. Met explode() kom je ook een heel eind.
PHP:
1
list($first, $second) = explode('.', $ip);

Regeren is vooruitschuiven


Acties:
  • 0 Henk 'm!

  • niels_999348
  • Registratie: Maart 2003
  • Laatst online: 20-09 08:10
Des te langer ik erover nadenk des te moeilijker word 't :'(
Wat ik dus concreet wil. Dit is mijn array:
1. 80.100.23.45
2. 34.2.9.2
3. 80.25.23.3
4. 34.2.9.10
5. 80.100.234.2

En er moet uitkomen:
1. 80.100.23.45
2. 34.2.9.2
3. 80.25.23.3

Dus zegmaar de dubbele ipmasks (X.X.*.*) moeten eruit.
Hoe doe ik het echt ???

Acties:
  • 0 Henk 'm!

  • T-MOB
  • Registratie: Maart 2001
  • Laatst online: 16:36
Dat kan vrij makkelijk, je zegt dat ze uit een database komen. Dan houden we in de loop door de resultset gewoon een array bij met masks die al gebruikt zijn. Alleen als de mask nog niet voorkomt stoppen we het betreffende IP in ons output-array. Ongeveer zoiets:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//in masks houden we de gebruikte ip-masks bij
$masks = array();

//in displayIp komen de ip'om weer te geven
$displayIp = array();

//we loopen door de db-results
while ($row = mysql_fetch_assoc($result)) {

  list ($first, $second) = explode ('.', $row['ip']);
  $mask = $first .'.' .$second;
  
  //als de mask al voorkomt in $masks negeren we dit ip
  if (!in_array($mask, $masks)) {
    $masks[] = $mask;
    $displayIp[] = $row['ip'];
  }
}

Regeren is vooruitschuiven


Acties:
  • 0 Henk 'm!

Verwijderd

Niet getest en on the fly, maar probeer iets als:
PHP:
1
2
3
4
5
6
foreach($ips as $ip) {
  $ipExploded = explode('.',$ip);
  $ipArray[] = $ipExploded[0] . "." . $ipExploded[1] .".*.*";
}
$uniqueIPs = array_unique($ipArray);
print_r($uniqueIPs);


dan zou je iets als
array {
[0] 80.100.*.*
[1] 34.2.*.*
[2] 80.25.*.*
}

behoren te krijgen :) Nogmaals... code is uit het hoofd, voor hetzelfde geld werkt ie niet :)

[ Voor 5% gewijzigd door Verwijderd op 12-06-2005 15:58 ]


Acties:
  • 0 Henk 'm!

Verwijderd

Waarom regel je dat niet al in je query? Ik heb hier geen MySQL (neem aan dat je dat gebruikt, maar nagenoeg elk DBMS heeft hier wel functies voor; PostgreSQL heeft ip adressen zelfs als type), maar stel dat je ze als string in MySQL opslaat, zou je SUBSTRING_INDEX kunnen gebruiken om zo t/m de tweede punt te selecteren, of vier SUBSTRING_INDEX'en om elk subnet in een aparte kolom te selecteren. Je hoeft dan bijna niets meer in PHP te doen.

Acties:
  • 0 Henk 'm!

  • niels_999348
  • Registratie: Maart 2003
  • Laatst online: 20-09 08:10
T-MOB schreef op zondag 12 juni 2005 @ 15:54:
Dat kan vrij makkelijk, je zegt dat ze uit een database komen. Dan houden we in de loop door de resultset gewoon een array bij met masks die al gebruikt zijn. Alleen als de mask nog niet voorkomt stoppen we het betreffende IP in ons output-array. Ongeveer zoiets:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//in masks houden we de gebruikte ip-masks bij
$masks = array();

//in displayIp komen de ip'om weer te geven
$displayIp = array();

//we loopen door de db-results
while ($row = mysql_fetch_assoc($result)) {

  list ($first, $second) = explode ('.', $row['ip']);
  $mask = $first .'.' .$second;
  
  //als de mask al voorkomt in $masks negeren we dit ip
  if (!in_array($mask, $masks)) {
    $masks[] = $mask;
    $displayIp[] = $row['ip'];
  }
}
Dit werkt inderdaad prachtig :) dit gebruik ik nu bedankt voor de moeite :)
Verwijderd schreef op zondag 12 juni 2005 @ 16:41:
Waarom regel je dat niet al in je query? Ik heb hier geen MySQL (neem aan dat je dat gebruikt, maar nagenoeg elk DBMS heeft hier wel functies voor; PostgreSQL heeft ip adressen zelfs als type), maar stel dat je ze als string in MySQL opslaat, zou je SUBSTRING_INDEX kunnen gebruiken om zo t/m de tweede punt te selecteren, of vier SUBSTRING_INDEX'en om elk subnet in een aparte kolom te selecteren. Je hoeft dan bijna niets meer in PHP te doen.
Euhm.. dan zou 't voor mij nog ingewikkelder worden. Dus 't is zo voor mij goed. :)

Acties:
  • 0 Henk 'm!

Verwijderd

niels_999 schreef op zondag 12 juni 2005 @ 17:39:
[...]

Euhm.. dan zou 't voor mij nog ingewikkelder worden. Dus 't is zo voor mij goed. :)
Je zou dan iets als dit krijgen:

PHP:
1
2
3
$result = mysql_query( "SELECT DISTINCT SUBSTRING_INDEX(<ipadres-kolom>, '.', 2) FROM <je tabel>" );
while ( $row = mysql_fetch_row( $result ) )
   echo $row[ 0 ] . ".*.*";


Door distinct heb je ook al gelijk geen dubbele waardes meer. Lijkt me dat deze wat resource-vriendelijker is dan alle bekende ip's te selecteren en hier hog een hoop functies op uit te voeren.

(ik heb de code niet getest, zal best een klein foutje inzitten aangezien ik nooit meer PHP/MySQL gebruik)


... en -NME-'s query is helemaal lekker clean.

[ Voor 42% gewijzigd door Verwijderd op 12-06-2005 18:07 . Reden: code gemaakt ]


Acties:
  • 0 Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

Verwijderd schreef op zondag 12 juni 2005 @ 17:50:
Je zou dan iets als dit krijgen:
PHP:
1
2
3
$result = mysql_query( "SELECT DISTINCT SUBSTRING_INDEX(<ipadres-kolom>, '.', 2) FROM <je tabel>" );
while ( $row = mysql_fetch_row( $result ) )
   echo $row[ 0 ] . ".*.*";
Kan zelfs nog korter. :)
PHP:
1
$result = mysql_query( "SELECT DISTINCT CONCAT(SUBSTRING_INDEX(ipadres, '.', 2), '.*.*') FROM tabel" );

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


Acties:
  • 0 Henk 'm!

  • T-MOB
  • Registratie: Maart 2001
  • Laatst online: 16:36
Verwijderd schreef op zondag 12 juni 2005 @ 17:50:
[...]
Je zou dan iets als dit krijgen:

Door distinct heb je ook al gelijk geen dubbele waardes meer. Lijkt me dat deze wat resource-vriendelijker is dan alle bekende ip's te selecteren en hier hog een hoop functies op uit te voeren.

(ik heb de code niet getest, zal best een klein foutje inzitten aangezien ik nooit meer PHP/MySQL gebruik)
Probleem is alleen dat de output niet meer klopt met de wens van TS. Hij wil voor elk IP-mask het eerste gehele IP weergeven. Of dat mogelijk is hangt af van de precieze wens van TS voor wat betreft het ip dat moet worden weergegeven. Als het (string-) minimum of maximum volstaat kan het met een GROUP BY
code:
1
SELECT MIN(ip) as ipadres FROM tabel GROUP BY SUBSTRING_INDEX(ipadres, '.', 2)


Moet het echt de eerste zijn bij een bepaalde sortering (bijv datum) dan houdt het vziw al snel op qua mogelijkheden in MySQL.

Regeren is vooruitschuiven

Pagina: 1