تابع gethostbyname() در PHP
تابع gethostbyname() در PHP یک ابزار ساده و قدیمی برای تبدیل نام میزبان (hostname) به آدرس آیپی نسخهٔ ۴ (IPv4) است. این تابع برای کارهای پایهای مانند پیدا کردن آدرس IP یک دامنه، ثبت لاگ یا انجام اتصالهای ساده کاربرد دارد. با اینحال محدودیتهایی هم دارد که باید هنگام استفاده در پروژههای مدرن در نظر گرفته شوند.
قواعد و مقدار بازگشتی
امضای تابع:
string gethostbyname(string hostname)توضیح: این تابع یک رشته شامل آدرس IPv4 را برمیگرداند. در صورت شکست حل نام (resolve) مقدار ورودی (hostname) را بدون تغییر برمیگرداند — یعنی تابع هیچگاه مقدار بولی false را بازنمیگرداند. این رفتار اهمیت دارد چون باید با مقایسه نتیجه و نام میزبان تعیین کنید که آیا تبدیل موفق بوده یا نه.
مثال ساده
<?php
$host = 'example.com';
$ip = gethostbyname($host);
if ($ip === $host) {
echo "Resolve failed for {$host}n";
} else {
echo "{$host} -> {$ip}n";
}
?>
توضیح: در این کد، ابتدا نام میزبان example.com را به تابع میدهیم. سپس با مقایسه نتیجه با مقدار اولیه متوجه میشویم که آیا حل نام موفق بوده است یا خیر. اگر بازگشتی برابر با نام میزبان باشد، حل نام با شکست مواجه شده است.
مثال با gethostbynamel() و بررسی چند آدرس
<?php
$host = 'google.com';
$ips = gethostbynamel($host); // returns array of IPv4 addresses or false
if ($ips === false) {
echo "No addresses foundn";
} else {
foreach ($ips as $ip) {
echo $ip . "n";
}
}
?>
توضیح: تابع gethostbynamel() ممکن است چند آدرس IPv4 برای یک نام میزبان برگرداند. این تابع در مواقعی که بخواهید از بین چند آدرس یکی را انتخاب کنید یا همه را بررسی کنید مفید است.
محدودیتها و نکات مهم
- فقط IPv4: gethostbyname() تنها آدرسهای IPv4 را برمیگرداند و برای IPv6 (AAAA) کاربردی ندارد.
- بازگشت رشتهٔ نام میزبان در صورت خطا: تابع در هنگام شکست resolve مقدار ورودی را برمیگرداند که باید حتماً چک شود.
- غیر آسنکرون و بلاککننده: فراخوانی ممکن است تا زمان پاسخ DNS بلاک شود؛ برای حجم بالا یا درخواستهای همزمان باید مراقب تایماوتها و اتصالها باشید.
- وابستگی به رزولور سیستم: عملکرد تابع به تنظیمات DNS سیستم/سرور متکی است (مثلاً فایل /etc/resolv.conf یا سرویسدهندهٔ DNS محلی).
راهکار برای پشتیبانی IPv6 و اطلاعات بیشتر
برای دریافت رکوردهای IPv6 یا اطلاعات DNS دقیقتر از dns_get_record() استفاده کنید. این تابع امکان دریافت انواع رکورد مانند A، AAAA، MX و غیره را دارد.
<?php
$host = 'ipv6.google.com';
$records = dns_get_record($host, DNS_A + DNS_AAAA);
$ips = [];
foreach ($records as $r) {
if (isset($r['type']) && $r['type'] === 'A' && isset($r['ip'])) {
$ips[] = $r['ip'];
} elseif (isset($r['type']) && $r['type'] === 'AAAA' && isset($r['ipv6'])) {
$ips[] = $r['ipv6'];
}
}
print_r($ips);
?>
توضیح: در این مثال از dns_get_record برای دریافت هم رکوردهای A (IPv4) و هم AAAA (IPv6) استفاده شده است. سپس آدرسها از آرایهٔ رکوردها استخراج میشوند. این روش کاملتر و مناسبتر برای برنامههای امروزی است.
مقایسهٔ توابع مرتبط
| تابع | چه چیزی برمیگرداند | پشتیبانی IPv6 | یادداشت |
|---|---|---|---|
| gethostbyname() | رشتهٔ IPv4 یا نام میزبان (در صورت خطا) | خیر | ساده اما محدود |
| gethostbynamel() | آرایهٔ IPv4 یا false | خیر | چند آدرس ممکن |
| dns_get_record() | آرایهٔ رکوردهای DNS | بله (با DNS_AAAA) | قابل تنظیم و کامل |
| stream_socket_client()/sockets | اتصال یا استفاده از getaddrinfo | بله | برای اتصال واقعی و پشتیبانی کامل بهتر است |
بهترین شیوهها و نکات عملی
- همیشه نتیجهٔ gethostbyname() را با نام ورودی مقایسه کنید تا خطا را تشخیص دهید.
- برای پشتیبانی IPv6 یا اطلاعات دقیق DNS از dns_get_record() یا توابع کتابخانهای دیگر استفاده کنید.
- اگر عملکرد مهم است، از کش داخلی (مثلاً APCu یا کش درونبرنامهای) برای نتایج رزولوشن استفاده کنید تا درخواستهای DNS تکراری کاهش یابد.
- برای امنیت، نتایج DNS را در صورت نیاز اعتبارسنجی کنید و از منابع معتبر DNS استفاده نمایید (مثلاً DNS over TLS/HTTPS در سطح سیستم).
- در برنامههای همزمان یا high-load از روشهای غیرقابل بلاک یا queue برای رزولوشن استفاده کنید.
نمونهٔ پیشرفته — تابع کمکی برای دریافت IPv4 یا IPv6
<?php
function resolve_host($host) {
// Try IPv6 and IPv4 via dns_get_record
$records = @dns_get_record($host, DNS_A + DNS_AAAA);
if ($records === false) {
return false;
}
$result = ['ipv4' => [], 'ipv6' => []];
foreach ($records as $r) {
if (isset($r['type'])) {
if ($r['type'] === 'A' && isset($r['ip'])) {
$result['ipv4'][] = $r['ip'];
} elseif ($r['type'] === 'AAAA' && isset($r['ipv6'])) {
$result['ipv6'][] = $r['ipv6'];
}
}
}
return $result;
}
?>
توضیح: این تابع ترکیبی از رکوردهای A و AAAA را دریافت کرده و در قالب یک آرایه با کلیدهای ipv4 و ipv6 برمیگرداند. استفاده از dns_get_record امکان پشتیبانی از IPv6 را نیز فراهم میکند و نسبت به gethostbyname() کاملتر است.
نتیجهگیری فنی
gethostbyname() برای استفادههای ساده و سریع مناسب است اما محدود به IPv4 و رفتار بازگشتی خاص آن (برگشت نام میزبان در صورت خطا) میتواند باعث اشتباه در برنامهها شود. برای کاربردهای حرفهای و پشتیبانی IPv6 از dns_get_record() یا راهکارهای سطح پایینتر مثل getaddrinfo استفاده کنید. همچنین در محیطهای پرترافیک به کش و روشهای غیرقابل بلاک برای رزولوشن توجه داشته باشید.
آیا این مطلب برای شما مفید بود ؟



