تابع stream_get_transports() در PHP
تابع stream_get_transports() یکی از توابع مفید در خانواده Streamهای PHP است که لیستی از پروتکلها/ترنسپورتهای قابل استفاده برای ایجاد stream/socket را برمیگرداند. این اطلاعات برای تشخیص قابلیتهای محیط اجرای PHP، انتخاب استراتژی اتصال و مدیریت پویا اتصالات شبکه بسیار کاربردی است.
چرا این تابع مهم است؟
در برنامههای شبکهای یا زمانی که نیاز به برقراری اتصالات پویا دارید، دانستن پروتکلهای در دسترس (مانند tcp، udp، unix، ssl/tls و غیره) به شما کمک میکند تا:
- قبل از تلاش برای اتصال، بررسی کنید آیا یک ترنسپورت پشتیبانی میشود یا خیر.
- کد قابل حملتر و مقاومتری بنویسید که روی سرورهای مختلف رفتار قابل پیشبینی داشته باشد.
- در سناریوهای fallback، بهصورت خودکار از پروتکل جایگزین استفاده کنید.
نحوه استفاده اولیه
<?php
// خواندن لیست ترنسپورتهای قابل استفاده
$transports = stream_get_transports();
echo "Available transports:n";
print_r($transports);
?>این کد آرایهای از رشتهها بازمیگرداند که نام هر ترنسپورت را نشان میدهد. سپس با print_r میتوانید آنها را مشاهده کنید.
نمونه خروجی (نمونهٔ احتمالی)
Array
(
[0] => tcp
[1] => udp
[2] => unix
[3] => udg
[4] => ssl
[5] => tls
)توجه کنید که این خروجی ممکن است بین سرورها متفاوت باشد و بسته به نسخهٔ PHP، تنظیمات کامپایل، ماژولهای نصبشده و سیستمعامل تغییر کند. بنابراین نباید روی یک مجموعهٔ ثابت حساب کنید.
مثال عملی: انتخاب پویا بین tcp و unix socket
<?php
$transports = stream_get_transports();
// فرض: اگر unix موجود باشد امتیاز به آن میدهیم زیرا محلی و سریعتر است
$address = null;
if (in_array('unix', $transports, true)) {
$address = 'unix:///var/run/myservice.sock';
} elseif (in_array('tcp', $transports, true)) {
$address = 'tcp://127.0.0.1:12345';
} else {
throw new RuntimeException('No supported transports available');
}
$fp = @stream_socket_client($address, $errno, $errstr, 3.0);
if (!$fp) {
echo "Connection failed: $errstr ($errno)n";
} else {
fwrite($fp, "HELLOn");
echo fgets($fp);
fclose($fp);
}
?>در این مثال، ابتدا ترنسپورتها بررسی میشوند. اگر unix socket موجود باشد از آن استفاده میکنیم؛ در غیر این صورت به tcp بازمیگردیم. سپس با stream_socket_client اتصال برقرار شده و درخواست/پاسخ سادهای ارسال میشود. استفاده از @ برای suppress خطاهای هشداردهنده انتخابی است؛ بهتر است در برنامهٔ تولیدی خطاها را مدیریت کنید.
بهبودها و نکات حرفهای
- کشینگ نتایج: فراخوانی stream_get_transports() هزینهٔ زیادی ندارد اما در حلقهها یا مسیرهای با فراخوانی زیاد میتوانید نتیجه را کش کنید.
- بررسی وجود تابع: در نسخهها یا محیطهای بسیار قدیمی ممکن است تابع موجود نباشد؛ بهتر است قبل از استفاده آن را بررسی کنید.
- فولبک و استراتژیهای پشتیبان: طراحی کنید که اگر ترنسپورت مطلوب در دسترس نبود، به جای شکست کامل از گزینهٔ دیگری استفاده شود یا پیغام راهنمایی مناسبی نمایش داده شود.
- امنیت: هنگام استفاده از ssl/tls مطمئن شوید تنظیمات context (مانند verify_peer، cafile) بدرستی قرار گرفتهاند تا از MITM جلوگیری شود.
کد نمونه با بهبود: بررسی وجود تابع و کشینگ
<?php
if (!function_exists('stream_get_transports')) {
throw new RuntimeException('stream_get_transports is not available in this PHP build.');
}
// کشینگ نتیجه برای استفادهٔ مکرر
static $cachedTransports = null;
if ($cachedTransports === null) {
$cachedTransports = stream_get_transports();
}
// مثال استفاده از کش
if (in_array('ssl', $cachedTransports, true) || in_array('tls', $cachedTransports, true)) {
// استفاده از SSL/TLS با context مناسب
$context = stream_context_create([
'ssl' => [
'verify_peer' => true,
'allow_self_signed' => false,
// 'cafile' => '/path/to/ca.pem',
],
]);
$fp = @stream_socket_client('tcp://example.com:443', $errno, $errstr, 5, STREAM_CLIENT_CONNECT, $context);
}
?>این نسخه ابتدا وجود تابع را بررسی کرده و سپس پاسخ را کش میکند. در ادامه مثالی از استفادهٔ SSL/TLS با context آورده شده است تا نشان دهد باید تنظیمات امنیتی را بهدرستی قرار داد.
لیست رایج ترنسپورتها (توضیح)
| ترنسپورت | معنی و کاربرد |
|---|---|
| tcp | اتصالات TCP/IP معمولی؛ رایجترین گزینه برای شبکه |
| udp | پروتکل بدون اتصال، مناسب برای پیغامهای کوچک یا real-time |
| unix | ساکتهای محلی Unix domain — سریع و امن برای ارتباط محلی |
| ssl / tls | لایهٔ امن روی TCP برای ارتباطات رمزنگاریشده |
این جدول فهرست کاملی نیست بلکه رایجترین موارد را نشان میدهد. لیست واقعی تابع بستگی به محیط سرور دارد.
موارد رایج سوال و پاسخ
- آیا میتوانم فقط بهترنسپورت خاصی اعتماد کنم؟ بهتر است برنامه را طوری بنویسید که انعطافپذیر باشد و در صورت نبود یک ترنسپورت از گزینهٔ جایگزین استفاده کند.
- آیا ترنسپورتهای برگشتی شامل wrappers مانند “http” هستند؟ stream_get_transports مربوط به transport-level wrappers است. برای wrapperهای فایل/HTTP بهتر است از stream_get_wrappers() استفاده کنید.
- آیا لیست قابل تغییر است؟ این لیست در زمان اجرا از تنظیمات، ماژولهای افزودهشده و سیستمعامل تبعیت میکند؛ با نصب افزونهها یا تغییر تنظیمات ممکن است تغییر کند.
جمعبندی
تابع stream_get_transports() ابزار ساده ولی قدرتمندی است برای شناخت قابلیتهای شبکهای محیط اجرای PHP. استفادهٔ آگاهانه از آن باعث میشود کد شما قابل حملتر، امنتر و مقاومتر در برابر تغییرات محیط شود. همواره نتایج تابع را در طول اجرای برنامه مدیریت و از استراتژیهای fallback و تنظیمات امنیتی مناسب بهره ببرید.
آیا این مطلب برای شما مفید بود ؟




