تابع set_local_infile_handler() در PHP
تابع set_local_infile_handler() (یا نسخهٔ شیءگرای آن mysqli::set_local_infile_handler) به شما اجازه میدهد هنگام اجرای دستور SQLِ LOAD DATA LOCAL INFILE از PHP بهصورت برنامهنویسی دادهها را به سرور MySQL ارسال کنید — بدون نیاز به فایل موقتی روی دیسک. این قابلیت مخصوصی از درایور mysqlnd است و برای بارگذاری دادههای تولیدشده پویا، فشردهشده یا محافظتشده مفید است.
چیست و چه کاری انجام میدهد؟
وقتی از LOAD DATA LOCAL INFILE استفاده میکنید و گزینهٔ LOCAL فعال است، معمولاً کلاینت MySQL فایل را میخواند و محتوا را به سرور میفرستد. با set_local_infile_handler شما یک handler تعریف میکنید که وقتی سرور خواستار خواندن دادهها شد، PHP آن را اجرا کند و دادهها را بهصورت chunk به سرور بفرستد. این روش امکان تولید جریان داده (streaming) یا خواندن از منابع غیر فایلی (مثل حافظه، S3، فایلی فشرده) را فراهم میکند.
پیشنیازها و محدودیتها
- قابلیت تنها با درایور mysqlnd کار میکند — اگر از libmysqlclient استفاده میکنید، این تابع قابلاستفاده نیست. میتوانید با تابع mysqli_get_client_info() بررسی کنید که mysqlnd استفاده میشود یا نه.
- متغیرهای پیکربندی مرتبط: سطح سرور MySQL (local_infile) و تنظیم PHP مثل mysqli.allow_local_infile ممکن است استفاده از LOCAL را محدود کنند.
- مواظب مسائل امنیتی باشید: LOAD DATA LOCAL INFILE میتواند سو استفاده شود. همیشه دادهها را اعتبارسنجی کنید و این قابلیت را فقط در موارد نیاز فعال نمایید.
امضا و نوع callbackها
بهصورت کلی سه callback تعریف میشود:
- read callback: function(int $maxlen): string — باید تا $maxlen بایت برگرداند؛ برگرداندن رشتهٔ خالی (”) بهمعنای EOF است.
- end callback: function(): void — پاکسازی منابع در پایان انتقال.
- error callback: function(string $message): void — برای ثبت پیام خطا یا لاگ.
مثال ساده — بارگذاری CSV از یک رشته در حافظه (procedural)
= strlen($data)) return ''; // EOF
$chunk = substr($data, $pos, $maxlen);
$pos += strlen($chunk);
return $chunk;
};
$end = function() {
// cleanup if needed
};
$error = function($message) {
error_log("LOCAL INFILE error: $message");
};
mysqli_set_local_infile_handler($link, $read, $end, $error);
mysqli_query($link, "LOAD DATA LOCAL INFILE 'ignored'
INTO TABLE mytable
FIELDS TERMINATED BY ','
IGNORE 1 LINES (id, name)");
?>توضیح: در این مثال دادهها داخل متغیر $data هستند. callback خواندن بهتدریج رشتهها را برمیگرداند تا وقتی رشتهٔ خالی برگرداند، mysqlnd آن را بهعنوان EOF میپذیرد. نام فایل در دستور LOAD DATA LOCAL INFILE اهمیتی ندارد (اینجا ‘ignored’) چون mysqlnd بجای باز کردن فایل از handler استفاده میکند.
نمونه: خواندن از فایل فشرده و ارسال مستقیم به MySQL
set_local_infile_handler($read, $end, $error);
$mysqli->query("LOAD DATA LOCAL INFILE 'ignored' INTO TABLE mytable FIELDS TERMINATED BY ',' IGNORE 1 LINES (col1,col2)");
?>توضیح: این مثال فایل فشرده gz را بهصورت chunk میخواند و مستقیم به MySQL میفرستد. این روش مانع باز کردن فایل فشرده روی دیسک جداگانه یا ایجاد فایل موقت میشود و مناسب دادههای حجیم یا حساس است.
نکات امنیتی و پیکربندی
- اطمینان حاصل کنید که سرور MySQL اجازهٔ LOCAL را به صورت کنترلشده میدهد (متغیر server system variable: local_infile).
- در PHP، گزینهٔ mysqli.allow_local_infile ممکن است فعال/غیرفعال باشد؛ در صورت خاموش بودن، handler کار نخواهد کرد.
- همیشه دادههای ورودی را اعتبارسنجی کنید و از SQL Injection جلوگیری کنید (پارامترها را جدا کنید و فقط از باشگاه دادهٔ امن استفاده کنید).
- در صورت استفاده از منابع از راه دور (S3، API)، از مکانیزمهای امن (موقت کردن توکنها، TLS) استفاده کنید.
خطاها و رفع اشکال
- اگر mysqli_set_local_infile_handler برگشتی false داد، ابتدا بررسی کنید که mysqlnd فعال است.
- اگر server اجازهٔ LOCAL را نمیدهد، خطا از طرف MySQL خواهد آمد؛ به error log سرور و پیام بازگشتی توجه کنید.
- در داخل read callback، اگر خطایی رخ داد میتوانید پیام را از طریق error callback گزارش کنید؛ سپس MySQL فرایند را متوقف میکند.
مزایا و موارد کاربرد
- بارگذاری دادههای پویا بدون ایجاد فایل موقت روی دیسک.
- استریم مستقیم از منابع فشرده یا از راه دور.
- کنترل کامل روی نحوهٔ ارسال دادهها به سرور (قابل استفاده برای تبدیل فرمت در لحظه).
| روش | مزایا | معایب |
|---|---|---|
| set_local_infile_handler | بدون فایل موقت، streaming، امنتر برای دادههای حساس | نیازمند mysqlnd، تنظیمات امنیتی پیچیده |
| فایل موقت + LOAD DATA LOCAL INFILE | سادهتر در برخی موارد | نیاز به نوشتن روی دیسک، مدیریت فایل موقت |
نتیجهگیری: اگر از mysqlnd استفاده میکنید و میخواهید دادهها را مستقیم و ایمن به MySQL وارد کنید، set_local_infile_handler() ابزار قدرتمندی است. با رعایت نکات امنیتی و مدیریت مناسب callbackها میتوانید بارگذاریهای سریع و منعطفی پیادهسازی کنید.
آیا این مطلب برای شما مفید بود ؟



