تابع set_local_infile_default() در PHP
در ابتدا لازم است اشاره کنم که تابعی با نام دقیق set_local_infile_default() در مستندات رسمی PHP یا اکستنشنهای مرسوم (mysqli، PDO_MySQL، mysqlnd) بهعنوان یک تابع جداگانه یافت نمیشود. اگر این نام را از منبع خاصی دیدهاید ممکن است اشتباه نوشتاری، یک تابع داخلی در یک فریمورک/کتابخانه شخص ثالث یا یک تابع سفارشی باشد. با این وجود مفهومِ «تنظیم رفتار پیشفرض برای LOAD DATA LOCAL INFILE» یک نیاز واقعی و رایج است و در ادامه به جایگاه این مفهوم، جایگزینهای عملی و نمونه کدهای مرتبط با متدهای رسمی مانند mysqli_set_local_infile_handler و تنظیمات مرتبط سرور/کلاینت میپردازم.
مفهوم کلی: LOAD DATA LOCAL INFILE و دلیل نیاز به کنترل
دستور SQL LOAD DATA [LOCAL] INFILE اجازه میدهد فایلهایی روی کلاینت به سرور MySQL ارسال و درون جدول بارگذاری شوند. گزینه LOCAL باعث میشود فایل از سمت کلاینت خوانده شود. این رفتار میتواند مفید اما از نظر امنیتی خطرناک باشد — مثلاً اگر به صورت ناامن فعال باشد، مهاجم میتواند فایلهای حساس را از سیستم کلاینت ارسال کند.
- بعضی از سرورها/کلاینتها بهصورت پیشفرض پشتیبانی LOCAL را غیرفعال میکنند.
- در PHP، راههایی برای کنترل این رفتار وجود دارد: سطح سرور (متغیر server-side)، سطحِ کانکشنِ MySQL کلاینت، یا با ثبت «هندلر» برای تولید محتوای فایل هنگام درخواست سرور.
جایگزینهای عملی در PHP
- غیرفعال/فعال کردن در سمت سرور MySQL: مدیر پایگاهداده میتواند گزینه local_infile را در سرور فعال یا غیرفعال کند. این امنترین روش برای کنترل کلی است.
- تنظیم در سمت کلاینت/اتصال: در mysqli میتوان گزینههای اتصال را تنظیم کرد تا امکان LOCAL را فعال یا غیرفعال کند (بهعنوان مثال از طریق mysqli_options یا پارامترهای اتصال در برخی موارد).
- استفاده از هندلر در PHP: تابع رسمی mysqli_set_local_infile_handler() اجازه میدهد یک callback ثبت کنید تا هنگام اجرای LOAD DATA LOCAL INFILE دادهها را به سرور بدهد. این رویکرد کنترل دقیقتری دارد و خطرات خواندن مستقیم فایلهای سیستم را کاهش میدهد.
نمونه کد: استفاده از mysqli_set_local_infile_handler
/* مثال ساده با mysqli_set_local_infile_handler (procedural) */$mysqli = mysqli_init();
$mysqli->real_connect('127.0.0.1', 'dbuser', 'dbpass', 'dbname', 3306);
/* هندلر خواندن: باید دادهٔ فایل را به صورت رشته بازگرداند؛
هندلر پایانی (در این مثال خالی) برای پاکسازی استفاده میشود */mysqli_set_local_infile_handler($mysqli,
function($filename) {
// اجتناب از استفاده مستقیم از نام فایلِ ارسالشده؛ مسیر ایمن را تعیین کنید
$safe = '/var/uploads/' . basename($filename);
if (!is_readable($safe)) {
return false; // اطلاع به MySQL که فایل قابل خواندن نیست
}
return file_get_contents($safe); // محتوای فایل به صورت رشته برگردانده میشود
},
function() {
// cleanup (در این مثال لازم نیست)
}
);
/* اجرای دستور SQL */$sql = "LOAD DATA LOCAL INFILE 'user_provided_name.csv'
INTO TABLE my_table
FIELDS TERMINATED BY ','
LINES TERMINATED BY 'n'
(col1, col2, col3)";
$mysqli->query($sql);توضیح: در این مثال، هنگام اجرای LOAD DATA LOCAL INFILE، MySQL از کلاینت میخواهد محتوای فایل را ارسال کند و تابع خواندن تعریفشده روی سمت PHP فراخوانی میشود. تابع خواندن مسیر امنی را میسازد و فایل مورد نظر را میخواند و محتوای آن را به سرور میدهد. این روش از ارسال مستقیم مسیرهای دلخواه توسط کاربر جلوگیری میکند و میتوان منطق اعتبارسنجی، فیلتر و تبدیل را نیز در همان callback انجام داد.
نکات امنیتی و بهترین شیوهها
- هرگز نام فایل ورودی را مستقیماً از ورودی کاربر قبول نکنید؛ از basename و whitelist مسیرها استفاده کنید.
- در صورت امکان، قابلیت LOCAL را روی سرور غیرفعال کنید و اگر لازم است، فقط به کانکشنهای مشخص اجازه دهید.
- برای دادههای حساس از روشهای جایگزین (مثلاً بارگذاری فایل به مسیر امن از طریق HTTP و سپس پردازش آن در سرور) استفاده کنید.
- محدود کردن مجوزهای سیستم فایل: فایلهایی که قرار است بارگذاری شوند باید تنها قابل خواندن توسط فرآیندی باشند که PHP اجرا میکند.
- در هندلر PHP میتوانید قبل از خواندن فایل، ویرایش/پاکسازی محتوای CSV را انجام دهید تا SQL Injection یا دادههای نامناسب حذف شوند.
مقایسه خلاصه: تابع فرضی set_local_infile_default() و جایگزینها
| نام/مکان | هدف | کنترل/امنیت |
|---|---|---|
| تابع فرضی set_local_infile_default() | تنظیم رفتار پیشفرض LOCAL (نامشخص) | نامشخص — در مستندات رسمی PHP یافت نشده |
| mysqli_set_local_infile_handler | ثبت هندلر برای تأمین دادهها هنگام LOAD DATA LOCAL INFILE | بالا — کنترل کامل بر داده ارسالی، اعتبارسنجی و فیلتر |
| تنظیم local_infile در MySQL | فعال/غیرفعال کردن قابلیت در سطح سرور | عالی — کنترل سراسری توسط DBA |
جمعبندی و توصیهها
اگر در مستنداتی نام set_local_infile_default() را دیدید، ابتدا منبع و نسخه PHP/پکیج را بررسی کنید؛ احتمالاً یک نام اشتباه یا تابعی از کتابخانهای خارج از هسته PHP است. برای مدیریت امن عملیات LOAD DATA LOCAL INFILE در PHP از راهکارهای رسمی مانند mysqli_set_local_infile_handler یا مدیریت تنظیمات سرور MySQL استفاده کنید. همچنین همیشه قواعد امنیتی و اعتبارسنجی را در هندلرهای بارگذاری رعایت نمایید تا از نشت داده یا اجرای ناخواسته کد جلوگیری شود.
در صورت نیاز میتوانم نمونههای پیشرفتهتر (پردازش chunked برای فایلهای بزرگ، تبدیل دادهها در مسیر، یا پیادهسازی در PDO با روشهای جایگزین) را نیز آماده کنم — فقط مشخص کنید محیط اجرا و نسخه PHP/موتور MySQL شما چیست.
آیا این مطلب برای شما مفید بود ؟



