العمل مع CSV في PHP: قراءة وكتابة ومعالجة البيانات
يظل تنسيق CSV (القيم المفصولة بفواصل) أحد أكثر الطرق شيوعًا لتبادل البيانات الجدولية. توفر PHP دوالًا مدمجة للعمل مع هذا التنسيق، مما يجعله خيارًا مثاليًا لاستيراد/تصدير البيانات، والتكامل مع أنظمة CRM، وأنظمة المحاسبة، وإنشاء التقارير. في هذه المقالة، سنستعرض دورة العمل الكاملة مع CSV: من فتح الملف إلى معالجة الحالات المعقدة مع أحرف الهروب وترميز الأحرف.
الدوال الأساسية في PHP للعمل مع CSV
لدى PHP دالتان رئيسيتان: fgetcsv() للقراءة و fputcsv() للكتابة. تقومان تلقائيًا بمعالجة الفواصل وعلامات الاقتباس وأحرف الهروب.
قراءة ملف CSV سطرًا بسطر
مثال أساسي لقراءة CSV باستخدام fgetcsv():
<?php$filename = 'data.csv';
if (($handle = fopen($filename, 'r')) !== false) { // قراءة الرؤوس (السطر الأول) $headers = fgetcsv($handle, 1000, ','); if ($headers !== false) { echo "الرؤوس: " . implode(', ', $headers) . "<br>"; // قراءة البيانات سطرًا بسطر while (($row = fgetcsv($handle, 1000, ',')) !== false) { echo "السطر: " . implode(' | ', $row) . "<br>"; } } fclose($handle);}?>معاملات fgetcsv():
handle— واصف الملف (نتيجة fopen)length— أقصى طول للسطر (يوصى باستخدام 0 للكشف التلقائي)separator— فاصل الحقول (افتراضيًا الفاصلة)enclosure— رمز علامات الاقتباس (افتراضيًا علامات الاقتباس المزدوجة)escape— رمز الهروب (افتراضيًا الخط المائل العكسي)
كتابة البيانات إلى CSV
تقوم الدالة fputcsv() بتنسيق السطر تلقائيًا مع الهروب الصحيح:
<?php$data = [ ['ID', 'الاسم', 'البريد الإلكتروني', 'تاريخ التسجيل'], [1, 'إيفان بيتروف', 'ivan@example.com', '2024-01-15'], [2, 'ماريا سيدوروفا', 'maria@example.com', '2024-02-20'], [3, 'أليكسي "الأستاذ" إيفانوف', 'alex@example.com', '2024-03-10']];
$filename = 'users.csv';
if (($handle = fopen($filename, 'w')) !== false) { // كتابة BOM لعرض السيريلية بشكل صحيح في Excel fwrite($handle, "\\xEF\\xBB\\xBF"); foreach ($data as $row) { fputcsv($handle, $row, ';'); // استخدام الفاصلة المنقوطة لـ Excel } fclose($handle); echo "تم إنشاء الملف $filename بنجاح!";}?>معالجة ملفات CSV الكبيرة
عند العمل مع الملفات الكبيرة (مئات الآلاف من الأسطر)، من المهم عدم تحميل الملف بأكمله في الذاكرة. استخدم المعالجة التدفقية:
<?phpfunction processLargeCSV($filename, callable $callback) { $handle = fopen($filename, 'r'); if ($handle === false) { throw new Exception("تعذر فتح الملف: $filename"); } $headers = fgetcsv($handle, 0, ','); if ($headers === false) { fclose($handle); throw new Exception("ملف فارغ أو خطأ في قراءة الرؤوس"); } $rowNumber = 1; while (($row = fgetcsv($handle, 0, ',')) !== false) { if (count($row) !== count($headers)) { // تخطي الأسطر ذات العدد غير الصحيح من الحقول continue; } // دمج الرؤوس مع البيانات $assocRow = array_combine($headers, $row); call_user_func($callback, $assocRow, $rowNumber); $rowNumber++; } fclose($handle);}
// الاستخدام:processLargeCSV('bigdata.csv', function($row, $number) { echo "السطر #$number: {$row['email']} - {$row['name']}<br>";});?>العمل مع فواصل وترميزات مختلفة
غالبًا ما تكون ملفات CSV