Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

INET_ATON() and INET_NTOA() in PHP?

I want to store IP addresses in my database, but I also need to use them throughout my application. I read about using INET_ATON() and INET_NTOA() in my MySQL queries to get a 32-bit unsigned integer out of an IP address, which is exactly what I want as it will make searching through the database faster than using char(15).

The thing is, I can't find a function that does the same sort of thing in PHP. The only thing I came across is:

http://php.net/manual/en/function.ip2long.php

So I tested it:

$ip = $_SERVER['REMOTE_ADDR']; echo ip2long($ip); 

And it outputs nothing. In the example they gave it seems to work, but then again I'm not exactly sure if ip2long() does the same thing as INET_ATON().

Does someone know a PHP function that will do this? Or even a completely new solution to storing an IP address in a database?

Thanks.

like image 546
blerh Avatar asked May 02 '10 17:05

blerh


2 Answers

The ip2long() and long2ip() functions should work just fine.

Note : you should use those for IPv4 addresses -- make sure that, in your case, $_SERVER['REMOTE_ADDR'] actually contains a valid IPv4 address (and not some IPv6-stuff).


Trying on a google IP address :

var_dump(ip2long('209.85.227.147')); var_dump(long2ip(3512066963)); 

I get the following output :

int(3512066963) string(14) "209.85.227.147"  
like image 142
Pascal MARTIN Avatar answered Oct 04 '22 13:10

Pascal MARTIN


There is an important distinction between ip2long, long2ip and the MySQL functions.

PHP's ip2long and long2ip deal with signed integers.

See http://php.net/manual/en/function.ip2long.php

"Because PHP's integer type is signed, and many IP addresses will result in negative integers on 32-bit architectures, you need to use the '%u' formatter of sprintf() or printf() to get the string representation of the unsigned IP address."

MySQL's INET_ATON() and INET_NTOA() deal with unsigned integers

See http://dev.mysql.com/doc/refman/5.0/en/miscellaneous-functions.html#function_inet-aton

"To store values generated by INET_ATON(), use an INT UNSIGNED column rather than INT, which is signed. If you use a signed column, values corresponding to IP addresses for which the first octet is greater than 127 cannot be stored correctly."

Here are some functions you can use to work between the two.

If you inserted into the MySQL database, an IP using INET_ATON(), you can convert it back in PHP using the following:

long2ip(sprintf("%d", $ip_address)); 

And you can convert it to save it in the database from PHP using this:

sprintf("%u", ip2long($ip_address)); 

(Also important, don't type-cast the $ip_address to int as this might cause problems by wrapping the number if it's bigger than MAX_INT. If you must cast it, cast it to a long or float)

like image 41
Tom Avatar answered Oct 04 '22 14:10

Tom