2010-05-02 7 views
29

मैं अपने डेटाबेस में आईपी पते स्टोर करना चाहता हूं, लेकिन मुझे अपने आवेदन के दौरान उन्हें उपयोग करने की भी आवश्यकता है। मैंने अपने MySQL प्रश्नों में 3212 बिट हस्ताक्षरित पूर्णांक प्राप्त करने के लिए INET_ATON() और INET_NTOA() का उपयोग करने के बारे में पढ़ा है, जो वास्तव में मैं चाहता हूं क्योंकि यह char (15) का उपयोग करने से डेटाबेस के माध्यम से तेज़ी से खोज करेगा।INET_ATON() और INET_NTOA()?

बात यह है कि मुझे ऐसा कोई फ़ंक्शन नहीं मिल रहा है जो PHP में समान प्रकार की चीज़ करता है। केवल एक चीज मैं भर में आया है:

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

तो मैं यह परीक्षण किया:

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

और यह कुछ भी नहीं आउटपुट। उदाहरण में उन्होंने इसे काम करने लगता है, लेकिन फिर मुझे बिल्कुल यकीन नहीं है कि ip2long()INET_ATON() जैसा ही है।

क्या कोई एक PHP फ़ंक्शन जानता है जो ऐसा करेगा? या डेटाबेस में आईपी एड्रेस स्टोर करने के लिए भी एक बिल्कुल नया समाधान?

धन्यवाद।

+0

जोड़ने के लिए, मैं, स्थानीय होस्ट पर काम कर रहा हूँ तो शायद इसलिए है भूल ip2long() कुछ भी वापस नहीं कर रहा है? – blerh

+0

लोकहोस्ट का आईपीवी 4 अभी भी 127.0.0.1 है, इसे तब तक काम करना चाहिए जब तक आप आईपीवी 6 का उपयोग नहीं कर रहे हों - मेरा जवाब देखें। –

उत्तर

34

ip2long() और long2ip() कार्यों को ठीक काम करना चाहिए।

नोट: यदि आप IPv4 पतों के लिए उन का उपयोग करना चाहिए - यह सुनिश्चित करें कि, आपके मामले में, $_SERVER['REMOTE_ADDR'] वास्तव में एक वैध IPv4 पता (और नहीं कुछ आईपीवी 6-सामान) शामिल हैं।


एक गूगल आईपी पते पर कोशिश कर रहा है:

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

मैं निम्नलिखित उत्पादन प्राप्त करें:

int(3512066963) 
string(14) "209.85.227.147" 
1

ip2long inet_aton के बराबर है()।

ip2long केवल आईपीवी 4 के साथ काम करता है। मुझे संदेह है कि आपका सिस्टम लूपबैक के लिए आईपीवी 6 का उपयोग कर रहा है। REMOTE_ADDR प्रिंट करने का प्रयास करें।

+1

आह मैं देख सकता हूं कि यह अब क्यों काम नहीं कर रहा है, '$ _SERVER ['REMOTE_ADDR']' रिटर्न: ':: 1'। शायद क्योंकि मैं लोकलहोस्ट पर हूं। क्या इसको रोकने के लिए कोई रास्ता है? या मुझे यह देखने के लिए एक जांच करनी चाहिए कि यह ':: 1' लौट रहा है या नहीं? – blerh

+1

:: 1 लूपबैक के लिए आईपीवी 6 है। आपको आईपीवी 6 को अक्षम करने की जरूरत है। लिनक्स के लिए, इस निर्देश का पालन करें: http://blog.taragana.com/index.php/archive/how-to-disable-ipv6-on-fedora-linux-why/ –

11

आईपीवी 4 और आईपीवी 6 समर्थन के लिए inet_pton() और inet_ntop() का उपयोग करें, ये PHP 5.1+ के बाद से उपलब्ध हैं और सटीक MySQL फ़ंक्शंस की नकल करते हैं।

अन्यथा बस ip2long() और long2ip() का उपयोग करें।

+0

मैं इसकी नकल करने में सक्षम नहीं हूं। – Artistan

29

ip2long, long2ip और MySQL फ़ंक्शंस के बीच एक महत्वपूर्ण अंतर है।

PHP के ip2long और long2ip हस्ताक्षरित पूर्णांक के साथ सौदा।

देखें http://php.net/manual/en/function.ip2long.php

"क्योंकि PHP के पूर्णांक प्रकार हस्ताक्षरित किया गया है, और कई IP पते 32-बिट आर्किटेक्चर पर नकारात्मक पूर्णांक में परिणाम होगा, तो आप() या '% यू' sprintf का फ़ॉर्मेटर उपयोग करने की आवश्यकता हस्ताक्षर किए गए आईपी पते की स्ट्रिंग प्रस्तुति प्राप्त करने के लिए printf()।, "

MySQL के INET_ATON() और INET_NTOA() अहस्ताक्षरित पूर्णांकों

साथ सौदा http://dev.mysql.com/doc/refman/5.0/en/miscellaneous-functions.html#function_inet-aton

देखें" INET_ATON (द्वारा उत्पन्न की दुकान मान) के लिए INT, जो हस्ताक्षरित किया गया है बजाय एक INT अहस्ताक्षरित स्तंभ का उपयोग करें। आपके द्वारा हस्ताक्षरित स्तंभ का उपयोग करते हैं, IP पते, जिसके लिए पहले ओकटेट अधिक से अधिक से अधिक 127 सही ढंग से जमा नहीं किया जा सकता है के लिए इसी महत्व देता है। "

यहाँ कुछ कार्यों आप दोनों के बीच काम करने के लिए उपयोग कर सकते हैं।

आप MySQL डेटाबेस में डाला, तो INET_ATON() का उपयोग कर एक आईपी, आप इसे वापस PHP में परिवर्तित निम्नलिखित का उपयोग कर सकते हैं:

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

और आप इस का उपयोग कर PHP से डेटाबेस में सहेजने के लिए परिवर्तित कर सकते हैं:

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

(इसके अलावा महत्वपूर्ण है, नहीं है int इस रूप में टाइप के कलाकारों $ip_address संख्या लपेटकर द्वारा समस्याओं के कारण हो सकता है अगर यह MAX_INT से भी बड़ा है। आप इसे कास्ट करना होगा, तो एक long या float)

+0

एक आकर्षण की तरह काम करता है। टिप के लिए बहुत बहुत धन्यवाद। मुझे इसके बारे में कभी पता नहीं था। 64-बिट सिस्टम पर –

+3

'ip2long' एक हस्ताक्षरित परिणाम देगा। हालांकि, "% u" अभी भी उस मामले में सही काम करेगा। – Brilliand

14

आपको लगता है कि पीएचपी अंदर से निपटने के लिए नहीं होना चाहिए करने के लिए इसे डाली, कि क्या MySQL देशी funcions के लिए कर रहे हैं। इस उदाहरण देखें:

create table iptable (
    ip int(32) unsigned not null, 
    comment varchar(32) not null 
); 

insert into iptable (ip, comment) values (inet_aton('10.0.0.3'), 'This is 10.0.0.3'); 

select * from iptable; 

+-----------+------------------+ 
| ip  | comment   | 
+-----------+------------------+ 
| 167772163 | This is 10.0.0.3 | 
+-----------+------------------+ 

select inet_ntoa(ip) as ip, comment from iptable; 

+----------+------------------+ 
| ip  | comment   | 
+----------+------------------+ 
| 10.0.0.3 | This is 10.0.0.3 | 
+----------+------------------+ 

आप दोनों IPv4 और एक ही क्षेत्र में आईपीवी 6 से निपटने के लिए चाहते हैं, और आप Mysql 5.6 या अधिक प्रयोग कर रहे हैं, तो आप varbinary (16) और inet6_aton कार्य करता है और inet6_ntoa उपयोग कर सकते हैं। यही कारण है कि आप MySQL कार्यों का उपयोग और नहीं पीएचपी अंदर बाइनरी डेटा के साथ सौदा करना चाहिए का एक बेहतर उदाहरण है:

create table iptable2 (
    ip varbinary(16) not null, 
    comment varchar(32) not null 
); 

insert into iptable2 (ip, comment) values 
    (inet6_aton('192.168.1.254'), 'This is router 192.168.1.254'), 
    (inet6_aton('::1'), 'This is ipv6 localhost ::1'), 
    (inet6_aton('FE80:0000:0000:0000:0202:B3FF:FE1E:8329'), 'This is some large ipv6 example') 
; 

select * from iptable2; 
+------------------+---------------------------------+ 
| ip    | comment       | 
+------------------+---------------------------------+ 
| +¿?¦    | This is router 192.168.1.254 | 
|    ? | This is ipv6 localhost ::1  | 
| ¦Ç  ??¦ ¦?â) | This is some large ipv6 example | 
+------------------+---------------------------------+ 

select inet6_ntoa(ip) as ip, comment from iptable2; 
+--------------------------+---------------------------------+ 
| ip      | comment       | 
+--------------------------+---------------------------------+ 
| 192.168.1.254   | This is router 192.168.1.254 | 
| ::1      | This is ipv6 localhost ::1  | 
| fe80::202:b3ff:fe1e:8329 | This is some large ipv6 example | 
+--------------------------+---------------------------------+ 

आप देख सकते हैं कि ऐसा करने से, आप वास्तव में विभिन्न स्वरूपों में IPv6 पतों का मूल्यांकन करने से बच सकते हैं, क्योंकि MySQL उन्हें बाइनरी में बदल देता है और वापस अपनी सबसे सरल अभिव्यक्ति में बदल जाता है।

मुझे पता है कि इस प्रश्न में 2 से अधिक वर्षों पहले से ही हैं, लेकिन मैं यह जानकारी उन लोगों के लिए उपयोगी होना चाहता हूं जो आने वाले हैं।

HTH

फ्रांसिस्को Zarabozo

+0

क्या होगा यदि आपको उन्हें एक तैयार कथन के साथ डालना है? आप mysql फ़ंक्शंस, 'INET_ATON (?)' के पैरामीटर को बाध्य नहीं कर सकते हैं, इसलिए आपको php –

+0

@the_nuts का उपयोग करना होगा आप किस बारे में बात कर रहे हैं? हाँ तुम कर सकते हो। अपने लिए कोशिश करो। –

+0

हाँ मैंने इसे क्षमा किया :) –

3

यहाँ (अपने कार्यक्रम में सरल कॉपी/पेस्ट) वैकल्पिक कार्यों पीएचपी -

function inet_aton($ip) 
{ 
    $ip = trim($ip); 
    if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) return 0; 
    return sprintf("%u", ip2long($ip)); 
} 


function inet_ntoa($num) 
{ 
    $num = trim($num); 
    if ($num == "0") return "0.0.0.0"; 
    return long2ip(-(4294967295 - ($num - 1))); 
} 
संबंधित मुद्दे