10

So I need to store IP addresses in database, but storing them as stings is not very efficient and not very convenient for my purpose.

So... How can I convert ip into integer in php with as less processing as possible because it will be done millions of times a day.

And of course how can I convert back from integet to ip?

I know this can be googled and there's some easy solutions - but I'm asking for the fastest way, not just for "do X and you get Y" because it's actually pretty easy task.

NewProger
  • 2,945
  • 9
  • 40
  • 58
  • 4
    Why don't you try some solutions and benchmark them? – Felix Kling Jun 27 '11 at 20:03
  • 1
    Chances are you won't find something faster than the built-in [`ip2long()`](http://php.net/ip2long) function. (Also: why would it matter?) – mario Jun 27 '11 at 20:05
  • Felix Kling, Well, proper benchmarking is not that easy to setup. Especially with such a small task. – NewProger Jun 27 '11 at 20:05
  • Will a float suffice? Alternativley, are you happy storing each part of the IP address in a separate column? Otherwise there is no way to have an int with different 'sections' – JoshB Jun 27 '11 at 20:05
  • Do you believe that `ip2long` is a fast method, although it is one of the top hits in Google? Next time, try Google first. – Felix Kling Jun 27 '11 at 20:07
  • mario, well... maybe it'd be better to do in in binarry or some other way I dont know about... And I need this for a statisctics for some very popular site. – NewProger Jun 27 '11 at 20:07
  • I take it you're not planning to support [IPv6](http://en.wikipedia.org/wiki/IPv6)? – Neil Jun 27 '11 at 20:29

4 Answers4

25

Use ip2long() and long2ip(). They are the fastest you can find in PHP, because they are just built on top of the corresponding C functions.

KingCrunch
  • 128,817
  • 21
  • 151
  • 173
  • 2
    That is one of the easy Google solutions, are you sure it is the fastest? ;) (just kidding) – Felix Kling Jun 27 '11 at 20:05
  • 1
    Yes. If you want to have it even faster, you may save the IPs as they are ;) – KingCrunch Jun 27 '11 at 20:07
  • Take care that PHP_INT_MAX is not configured on your system to make this function actually break! ;) – hakre Jun 27 '11 at 20:09
  • @lurler just run your own benchmarks, not hard with some simple code around on the net (try a google search). Also, C is always faster than php as it does not need to be interpreted – JoshB Jun 27 '11 at 20:10
  • @Lurler: Can't believe you're asking this. You must have no sense what the function actually does. Read the source code before you start even benchmark it. – hakre Jun 27 '11 at 20:10
  • 1
    @Lurler: Before you can benchmark code, you first have to have code. Write code, use the function, see if you have any performance problems. If you don't have any, you are fine. If you do, run a benchmark, find the bottleneck. *Premature optimization is the root of all evil.* – Felix Kling Jun 27 '11 at 20:13
  • @Felix Kling, when you will be paying few extra hundred bux for processing power of hosting you will understand :) So I asked this in hope that ppl might provide good answer, but it seems they think I'm noob and started trolling and minus'ing :( – NewProger Jun 27 '11 at 20:18
  • @Lurler: If one or two cpu cycles per function call cost you "hundred bux", than you are probably at the wrong hoster. As I mentioned: `ip2long()` is built directly on top of the c function with the same name, which is itself compiled into cool binary code optimized for your platform. If you find a way, how a function can get faster than this, tell me ;) And btw: The DB you mentioned will be _muuuch_ slower, than _any_ arithmetic function. Just don't waste your time by thinking about micro optimization. – KingCrunch Jun 27 '11 at 20:22
  • 5
    @Lurler: Your question is entirely based on conjectures about performance. If it was a serious concern of yours you would have benchmarked it. (Not saying what you tried is also pretty telling.) – mario Jun 27 '11 at 20:23
  • @KingCrunch, I think you are right afterall... thank you for piece of your mind :))) – NewProger Jun 27 '11 at 20:25
  • This answer has become quite old; when it was made, IPv6 was not widely used. Now it is, and its use is increasing. IPv6 addresses cannot be converted to integers of a typical size because they contain too much information. Calling `ip2long` on an IPv6 address will cause it to return `false`. Keep this in mind when designing your code: ip2long still works great on IPv4 addresses but fails on IPv6. – cazort Oct 22 '21 at 15:23
1

Use ip2long -- this function is so fast, it simply doesn't matter if you call it a million times a day. It is a library function, it is thus well-tested and reliable.

And, considering your working time, it is definitely the fastest solution in the whole universe.

Alexander Gessler
  • 45,603
  • 7
  • 82
  • 122
  • What does "fast" mean in this context? Does it execute in 1 millisecond? 1 microsecond? 1 nanosecond? – Gabe Jun 27 '11 at 20:06
1

You can use an INT

$ip = ip2long($ip);

To save in mysql:

$sql = "INSERT INTO user(ip) VALUES('$ip')";
$dbQuery = mysql_query($sql,$dbLink

You can get back the ip later :

SELECT INET_NTOA(ip) FROM 'user' WHERE 1

INET_NTOA(expr):

Given a numeric IPv4 network address in network byte order, returns the dotted-quad representation of the address as a binary string. INET_NTOA() returns NULL if it does not understand its argument.

mysql> SELECT INET_NTOA(167773449); -> '10.0.5.9'

Patrick Desjardins
  • 136,852
  • 88
  • 292
  • 341
0

Others have correctly pointed you to the ip2long() function. However, the question and answers are now around 10 years old. Back then, IPv6 was not widely used, but nowadays, it is, and its use is increasing.

If passed an IPv6 address, ip2long will return false, which, depending on the logic of your code, may get typecast to 0, which corresponds to the IP address 0.0.0.0.

In theory you could convert IPv6 addresses to 128-bit integers. Unfortunately, on 64-bit systems, 128-bit integers are a bit difficult to work with. The following question may be useful:

Php convert ipv6 to number

As for storing them in a database, the following question addresses it for MySQL:

Storing IPv6 Addresses in MySQL

Based on what I see in these answers and others to similar questions, I'm not sure if there is yet a consensus around a best method for these, the way there is for ip2long/long2ip for IPv4 addresses.

cazort
  • 516
  • 6
  • 19