تابع long2ip() در PHP
تابع long2ip() در PHP برای تبدیل مقدار عددی 32 بیتی (long) به رشتهٔ آدرس IPv4 در قالب dotted-quad (مثلاً 127.0.0.1) استفاده میشود. این تابع معمولاً مکمل ip2long() است: ip2long() یک آدرس متنی IPv4 را به عدد برمیگرداند و long2ip() آن عدد را دوباره به رشتهٔ آدرس تبدیل میکند.
مقدمهای کوتاه دربارهی نمای عددی IPv4
آدرس IPv4 در واقع عددی بین 0 تا 4294967295 (2^32 – 1) است. در بسیاری از کاربردها، نگهداری آدرس به صورت عددی در بانک اطلاعاتی یا پردازشهای باینری سریعتر است. long2ip و ip2long رابطی ساده برای تبدیل بین این دو نمایش فراهم میکنند.
طرز استفاده پایه
<?php
echo long2ip(2130706433); // "127.0.0.1"
$ip = '127.0.0.1';
$long = ip2long($ip); // 2130706433
echo long2ip($long); // "127.0.0.1"
?>کد بالا نشان میدهد که long2ip یک عدد را به آدرس متنی تبدیل میکند. 2130706433 مقدار عددی معادل 127.0.0.1 است.
نکات مهم و مشکلات رایج (خصوصاً در سیستمهای 32 بیتی)
- ip2long() ممکن است روی سیستمهای 32 بیتی، مقادیر بزرگتر از PHP_INT_MAX را به مقادیر منفی تبدیل کند. برای مثال ip2long(‘255.255.255.255’) در برخی پلتفرمها -1 برمیگرداند.
- long2ip() به طور کلی عدد را به رشته تبدیل میکند، اما اگر عدد شما به صورت رشتهٔ «غیرقابلِ نگاشت مستقیمِ int» ذخیره شده باشد، باید پیش از فراخوانی بررسی یا تبدیل مناسب انجام دهید.
- long2ip فقط برای IPv4 کاربرد دارد؛ برای IPv6 باید از inet_ntop و inet_pton استفاده کنید.
روشهای امن برای کار با مقادیر unsigned (بدون مشکل منفی بودن)
روش معمول برای نگهداری unsigned integer در دیتابیس و سپس تبدیل آن به آدرس، استفاده از sprintf(‘%u’, …) برای گرفتن نمایش بدون علامت است. سپس برای تبدیل به متن میتوان long2ip یا pack/inet_ntop را به کار برد:
<?php
$ip = '255.255.255.255';
$long = ip2long($ip); // ممکن است -1 روی 32-bit باشد
$unsigned = sprintf('%u', $long); // "4294967295"
echo long2ip((float)$unsigned); // "255.255.255.255"
?>در این مثال با sprintf(‘%u’) مقدار منفی به معادل unsigned تبدیل شده و با cast به float یا استفاده از pack/inet_ntop میتوان مقدار را به IP تبدیل کرد.
جایگزین مطمئن: استفاده از pack + inet_ntop
<?php
// تبدیل یک عدد unsigned (به صورت رشته یا عدد) به آدرس IPv4
function unsignedToIp($dec) {
if (!is_numeric($dec)) return false;
// pack('N', ...) بسته به پلتفرم به درستی بایتها را میسازد
return inet_ntop(pack('N', (int)$dec));
}
echo unsignedToIp('4294967295'); // "255.255.255.255"
?>این روش از لحاظ بایت-آرایش با استفاده از pack(‘N’, …) (شبکه/Big-endian) عمل میکند و سپس با inet_ntop مقدار متنی خروجی را میسازد. معمولاً این روش سازگاری و قابلاطمینانتری نسبت به اتکا صرف به long2ip در شرایط overflow دارد.
مثالهایی از خطاها و نحوهٔ بررسی ورودی
قبل از فراخوانی long2ip یا معادلها بهتر است بازه و نوع ورودی را بررسی کنید:
<?php
function safeLong2Ip($val) {
if (!is_numeric($val)) return false;
// مقادیر را به محدوده 0..4294967295 محدود میکنیم
$min = 0;
$max = 4294967295;
// در صورت large numbers میتوان از bc یا gmp استفاده کرد
if ($val < $min || $val > $max) return false;
return long2ip((float)$val);
}
?>در این تابع: ابتدا نوع داده بررسی میشود، سپس مقدار در محدودهٔ معتبر IPv4 قرار میگیرد. برای اعداد بسیار بزرگِ رشتهای میتوانید از کتابخانههای bcmath یا gmp برای مقایسه دقیق استفاده کنید.
مقایسه با ip2long و نکات ذخیرهسازی در دیتابیس
- برای ذخیرهٔ IP در دیتابیس MySQL معمولاً بهتر است از یک فیلد UNSIGNED INT (32-bit) استفاده کنید و مقدار را به صورت unsigned ذخیره کنید: INSERT INTO … VALUES (INET_ATON(‘127.0.0.1’)). تابعهای MySQL INET_ATON/INET_NTOA معادل ip2long/long2ip در سطح SQL هستند.
- اگر از PHP روی 32-bit هستید و ip2long مقدار منفی برمیگرداند، برای ذخیرهٔ unsigned از sprintf(‘%u’, ip2long($ip)) استفاده کنید.
- برای IPv6 از ستون VARBINARY(16) یا نصبیاتی مانند INET6_ATON/INET6_NTOA استفاده کنید و در PHP از inet_pton/inet_ntop بهره ببرید.
جدول خلاصه رفتار و نمونهها
| ورودی عددی | خروجی long2ip() | توضیح |
|---|---|---|
| 2130706433 | 127.0.0.1 | نمونه پایه |
| -1 (در 32-bit) | 255.255.255.255 | قابل تبدیل با sprintf(‘%u’, -1) یا pack+inet_ntop |
| 4294967295 | 255.255.255.255 | حداکثر مقدار unsigned |
نتیجهگیری و توصیههای عملی
تابع long2ip کاربردی، ساده و سریع برای تبدیل عدد به آدرس IPv4 است، اما هنگام کار با مقادیر unsigned یا روی سیستمهای 32 بیتی باید مراقب overflow و مقادیر منفی بود. برای کاربردهای حرفهای و پشتیبانی IPv6 توصیه میشود از inet_pton/inet_ntop یا توابع بانکاطلاعاتی مرتبط استفاده کنید. همیشه ورودیها را اعتبارسنجی کنید و اگر با مقادیر بزرگتر (رشتهای) کار میکنید از pack/inet_ntop یا کتابخانههای bcmath/gmp برای دقت بیشتر بهره بگیرید.
آیا این مطلب برای شما مفید بود ؟



